物联网控制的智能LED灯带(1):WS2812灯带控制(WS2812/2811,ESP32,NODE-RED)

ESP32控制WS2812/11灯带

这个部分中笔者将使用ESP32的RMT功能控制WS2812/11灯带。

什么是WS2812/2811灯带?与5050rgb灯带有何区别

  1. 不象5050rgb灯带只能同时显示一种颜色,ws2812/2811灯带上的每一个led都能被单独精确控制,显示(8位*3)种颜色。
  2. WS2812/2811只需一根信号线就能控制灯带上所有led。多个灯带间可以通过串联轻松延长。
  3. 在30hz的刷新频率下一个信号线能够控制至多500个led。

WS2811芯片 与WS2812led.

WS2811芯片实现了上述功能。WS2812led灯珠为内置了2811芯片的RGB灯珠。
一些灯带用一个WS2811芯片驱动3个普通5050RGB灯珠,而另一些全部使用了集成了芯片的WS2812灯珠。WS2812灯条都为5v供电,芯片驱动版本的灯带有12v供电版本。

WS2812/2811的控制信号

如上所说,WS2812芯片依靠一个信号线控制上百个LED的颜色,这是如何实现的呢?
每个LED的信号有24位,由R,G,B各八位组成。每个数据位的高低由信号引脚的波形决定:
物联网控制的智能LED灯带(1):WS2812灯带控制(WS2812/2811,ESP32,NODE-RED)_第1张图片
T0H,T0L,T1H,T1L的时间值由具体的芯片决定,具体请参考worldsemi网站的技术手册。
当发送多个led的数据时,每个芯片都会吞掉最前面的24位数据。两个数据帧之间需要间隔280微秒以上。物联网控制的智能LED灯带(1):WS2812灯带控制(WS2812/2811,ESP32,NODE-RED)_第2张图片

ESP32输出WS2812控制信号

为了接入wifi,这个项目使用ESP32作为灯带控制器和MQTT网关。笔者使用的是arduino-ide的开发环境(关于如何在arduino-ide或类似环境中开发esp32)。
控制WS2812/11的arduino库有WS2812FX和NeoPixelBus,但是它们都不支持ESP32硬件。好在esp32有内置的RMT库专门用来输出数字波形,并且提供了控制ws2812的范例程序(arduinoIDE-文件-示例-esp32-RMT-RMTWriteNeoPixel)。

//设置led数量,声明rmt对象。
#define NR_OF_LEDS   50
#define NR_OF_ALL_BITS (24*NR_OF_LEDS)
//rmt数据
rmt_data_t led_data[NR_OF_ALL_BITS];
//rmt对象
rmt_obj_t* rmt_send = NULL;
//每一个led的颜色状态。
uint8_t allColor[NR_OF_LEDS][3];
//初始化rmt对象
//18:针脚,true:输出或输入,RMT_MEM_64:内存数量
 if ((rmt_send = rmtInit(18, true, RMT_MEM_64)) == NULL){
    Serial.println("init sender failed\n");
  }

//设置rmt的时间单位,这里为100ns,返回实际设置的时间单位。
  float realTick = rmtSetTick(rmt_send, 100);
  Serial.printf("real tick set to: %fns\n", realTick);
  int led, col, bit;
  int i = 0;
  for (led = 0; led < NR_OF_LEDS; led++) {
    for (col = 0; col < 3; col++ ) {
      for (bit = 0; bit < 8; bit++) {
        //位为1时。
        if  (allColor[led][col]  & (1 << (8 - bit))) {
          //先输出高电平
          led_data[i].level0 = 1;
          //高电平输出时间为8*100ns=0.8微秒
          led_data[i].duration0 = 8;
          //再输出低电平
          led_data[i].level1 = 0;
          //低电平输出时间为4*100ns=0.4微秒
          led_data[i].duration1 = 4;
        } else {
         //位为0时。
          led_data[i].level0 = 1;
          led_data[i].duration0 = 4;
          led_data[i].level1 = 0;
          led_data[i].duration1 = 8;
        }
        i++;
      }
    }
  }
//输出的目标波形。
// "0":
//         +-------+              +--
//         |       |              |
//         |       |              |
//         |       |              |
//      ---|       |--------------|
//         +       +              +
//         | 0.4us |   0.8us   |
//
// "1":
//         +-------------+       +--
//         |             |       |
//         |             |       |
//         |             |       |
//         |             |       |
//      ---+             +-------+
//         |    0.8us    | 0.4us |
//输出波形
rmtWrite(rmt_send, led_data, NR_OF_ALL_BITS);

注意:只要没有关闭电源,WS2812/2811芯片会保存颜色输出状态。因此只有需要改变灯带状态时,esp32才需要重新输出控制数据。

注意:esp32的一些引脚无法使用rmt功能,运行时会出现缓存读取错误。

硬件连接

物联网控制的智能LED灯带(1):WS2812灯带控制(WS2812/2811,ESP32,NODE-RED)_第3张图片
如果ESP32板上没有5v-3.3V线性电源则请自行添加。
另外,一些WS2812/11灯带需要5V控制电平,不支持ESP32 3.3V的控制电平。请添加三极管升压电路或者用高低电平转换模块解决。
如果使用12v的灯带和电源还需添加降压模块给esp32供电。

建议当灯带长度超过5米时建议每5米分别供电,不然后面的灯带会有较大的压降。另外灯带最后可添加稳压电容。

第二部分:https://blog.csdn.net/CharlieZ8/article/details/88044235
第三部分:https://blog.csdn.net/CharlieZ8/article/details/88096061

你可能感兴趣的:(物联网控制的智能LED灯带(1):WS2812灯带控制(WS2812/2811,ESP32,NODE-RED))