【Nano Framework ESP32篇】WS2812 彩色灯带实验

这篇具有很好参考价值的文章主要介绍了【Nano Framework ESP32篇】WS2812 彩色灯带实验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

地球人皆知,许多物联网教程作者的心中都深爱着一灯大师,所以第一个例程总喜欢点灯,高级一点的会来个“一闪一闪亮晶晶”。老周今天要扯的也是和灯有关的,但不单纯地点个灯,那样实在不好玩,缺乏乐趣。老周打算舞个龙灯,哦不,是用 LED 彩色灯带给伙伴们整点炫酷乐子。

说到这LED彩灯,咱们常见到的有两类:

1、一卷一卷的灯带,灯带是软的,底部有背胶,可以随意贴(贴电脑机箱,贴储物柜,贴手办展示盒……);

2、点阵屏,其实跟灯带一个样,只是有个框架,做成矩阵。如 3 * 3、4 * 4 等。

驱动 IC 一般是 WS2812,此货体积甚小,便于寄生于每个灯珠内。所以,每个LED灯珠都可以单独控制。而且 WS2812 允许你把灯珠串联起来,发送给它的数据可以连续设置多个灯珠。颜色由 RGB 控制,即 24 位——设置灯珠颜色要向 WS2812 发送3个字节的数据。

其实,WS2812的驱动协议不那么复杂,随便查查资料就能懂的了。当然,Nano Framework 已经有封装好的驱动,咱们不需要自己写协议。对于 ESP32,有两种驱动方案:

1、SPI 方式,此法各种开发板通用。曾记否?老周写过在树莓派生用 SPI 驱动 WS2812 的水文;

2、RMT 方式,许多 ESP32 模组都支持RMT,可以用它来驱动 WS2812。RMT 说白了就是用来发送和接收红外编码的,比如,电视遥控器、电动马桶遥控器等(空调遥控器好像特殊一些,很多模块都解码不了)。RMT 由于可以在同一周期内设定高、低电平的持续时间,使得它也能用于驱动 WS2812。

实际上,PWM 也可以的,因为一个周期内的占空比也能设定高、低电平的持续时间。只是,在 PWM 连续发生时要频繁地更改占空比,对开发板的速度有要求,还要确保代码执行得够快。Nano Fw 毕竟是封装过的,性能上会有损失的。虽然使用第三方框加会带来一些性能上的削弱,但在应用层可以提升开发效率,就像写普通 .NET 程序那样。两者总是要有一个平衡的。当然了,还是那句话,如果用其他框架做不到的事情,就必须用官方的 idf 了。性能上肯定比脚本语言高的。

好了,基本理论准备完毕,接下来,咱们开始整活。

先来看看如何用 RMT 来驱动 WS2812 的。因为这个比较新奇,所以先介绍它。红外编码协议可能会劝退不少伙伴,但,你不必担心,毕竟咱们这里不是真的用红外通信,只是借助接口协议来给 WS2812 发数据罢了,不会涉及协议编码的。而且,Nano Framework 已经封装好了,用起来很省事,初始化只需要一条 new 语句就完事了。

A、硬件部分,ESP32 模块你可随意,只要有引出相关IO口就行,接口少也不要紧的,因为咱们顶多用一两根线(不含供电)。然后就是RGB灯带或者点阵屏。其实这两者本质上一样。老周这个灯带就是当初写树莓派文章时用的那个,ESP32 也是 3.6 年前买的,放在柜子里吃了几年尘螨。现在拿出来给大伙做演示,居然还能用,这质量可以的。

现在新点的开发板很多是 Type-C 接口的,不过老周这个毕竟是几年前的,是 Micro USB 接口的。啥接口没关系,可能就是找数据线麻烦些,现在很多手机是 C 口的。不过老周家里啥线都有,全都是绿联的。你没看错,老周所有数据线和转换器都是用绿联的。这不是广告,就是质量好。老周家里就是这样的:风扇是美的,因为电机静音;线材绿联的,墙插排插都是公牛的;音响器材铁三角或漫步者……老周不买小米的,小米其实就跟京东京造差不多,万能贴牌。老周记得,买硬盘唯一一次翻车的就是京造的。那个硬盘现在搭在树莓派上,专门放魔法少女动画片。

又扯远了,下面是步骤:

1、启动 VS;

2、新建 Nano 项目,选 Blank Application 项目模板就行了;

3、打开 Nuget 包管理器(方法自己百度),搜索 ws28xx esp32,然后你会找到一个【nanoFramework.Iot.Device.Ws28xx.Esp32】包。没错,它是专为 ESP32 封装,开箱即用(使用时引入 Iot.Device.Ws28xx.Esp32 命名空间)。

4、安装 nanoFramework.Iot.Device.Ws28xx.Esp32 包及相关依赖(一般自动安装);

这里介绍一下几个关键类。首先是 WS 芯片的公共基类 Ws28xx,在实例化时,咱们可以根据所使用的芯片选择派生类:Ws2812b 、Ws2812c、Sk6812 等,WS2812B 和 WS2812C 比较常见。至于你买的灯带是哪个 IC,还真不好说,比如老周这个其实是 WS2812C,可以卖家的商品介绍标注的是 WS2812B。问客服也没用的,多数是一问摇头三不知。客服客服,毫不客气地让你服得三观倒置。

这个可以上机测试,如果灯珠点亮后与你设置的颜色不对,可以换个类,比如,用 WS2812b 的结果不正确,可以换成 WS2812c 来试。WS2812b 和 WS2812c 的红色和绿色好像是反过来的。

接线就简单了,一根接 5V(没5V接口就接 3.3,或者单独供电),数据线只有一根,这里老周用 0 口,即 GPIO 0。你可以随便选其他接口,比如官方示例用的 GPIO 15。

public class Program
{
    const int PxCount = 16;     // 有多少个灯珠
    const int DelayMS = 10;     // 延时多少ms
    const int DataPin = 0;      // 使用哪个IO口

    // 入口点
    public static void Main()
    {
        Ws28xx ws28xx = new Ws2812c(DataPin, PxCount);
        BitmapImage bmp = ws28xx.Image;
        //ws28xx.ClockDivider = 2;
        //ws28xx.ResetCommand = new RmtCommand(1800, false, 1850, false);
        //ws28xx.OnePulse = new RmtCommand(35, true, 16, false);
        //ws28xx.ZeroPulse = new(14, true, 34, false);
        //Debug.WriteLine($"分频:{ws28xx.ClockDivider}");

        int i = default;
        int index1, index2;     // 要设置的灯珠索引
        while (true)
        {
            // 从两边向中间靠拢
            for (i = 0; i < PxCount / 2; i++)
            {
                // 每次设置两颗灯珠
                index1 = i;
                index2 = PxCount - 1 - i;
                bmp.SetPixel(index1, 0, Color.Red);
                bmp.SetPixel(index2, 0, Color.Red);
                ws28xx.Update();    // 更新
                Thread.Sleep(DelayMS);
            }
            // 从中间向两侧扩散
            for (i = PxCount / 2 - 1; i >= 0; i--)
            {
                index1 = i;
                index2 = PxCount - 1 - i;
                bmp.SetPixel(index1, 0, Color.Blue);
                bmp.SetPixel(index2, 0, Color.Blue);
                // 更新
                ws28xx.Update();
                Thread.Sleep(DelayMS);
            }
        }
    }
}

Ws2812c 类的构造函数有三个参数:1、你用的IO号;2、宽度;3、高度。这里的宽高即灯珠个数,此处老周只点16个灯,多了怕供电不足(其实可以点更多灯珠)。第三个参数默认是1,所以如果高为1可以忽略。这个宽和高啥意思呢?对于灯带来说,你可以认为它永远只有一行,但有 N 列(N 是无限大正整数),即 width = N, height = 1。而点阵屏是矩阵,所以用点阵屏就可以设置宽和高。

Ws28xx类公开 Image 属性,类型为 BitmapImage 类(也是个通用基类)。咱们可以把LED彩灯视作一张位图,每个灯珠就是一个像素。所以,设置某个灯的颜色就要调用 SetPixel 方法,参数是x、y坐标,以及颜色。这个和普通 .NET 程序操作一样。

这个示例,老周实现的效果是:

1、红灯的点亮顺序是从两边往中间靠拢;

2、蓝灯的点亮顺序是从中间向两边扩展。

每当你修改了位图的数据,只是存在内存中,只有调用 WsXXX 实例的 Update 方法才会正式将数据发送出去。

这个点灯算法其实很简单,咱们学过数学,在等差数列中,1+n=2+(n-1)=3+(n-3)。本例中,16个灯,一半就是8,而索引是从0开始的,所以是7,即全序列的索引是 0 到 15,于是得到:0+15=15,1+14=15,2+13=15,3+12=15 …… 7+8=15。每次循环我们就设置相加等于最大索引的那两个灯。这样就能实现从中间向两边展开,顺序反过来就实现从两边向中间收拢。

 运行的效果如下图所示。

【Nano Framework ESP32篇】WS2812 彩色灯带实验

细心的大伙伴会发现,上面的代码中有几行被注释掉了。这些代码用来设置参数的。不过 WS2812x 类会默认为咱们设置,除非发现默认设置的参数不正确时才要修改,

1、设置分频的分母。

ws28xx.ClockDivider = 2;

ClockDivider 用于设置分频,默认是2。目前支持的时钟是APB(外设的高级总线),频率是 80 MHz,分频2表示除以2=40MHz。也就是一个 Tick 的时间为 1/40000000 = 0.000000025 秒,换算为 0.025 微秒(us)。为什么分频不用 80 呢,这样一 Tick 就是 1 us岂不美哉?因为 WS28XX 的时序很短,比如发送 1 时,高电平持续时间为 0.7 us,低电平持续时间为 0.6 us,总时长在 1.3 us 左右。不过这类IC的时序有很多种版本,时序没有精确的时长。不管怎么说,这时间是要精确到 0.01 us的,所以,分频为80只精确到 1 us 显然不够用。分频为2精确到 0.025 us,基本能对付过去了。

2、设置高、低电平的持续时间。

ws28xx.ResetCommand = new RmtCommand(1800, false, 1850, false);
ws28xx.OnePulse = new RmtCommand(35, true, 16, false);
ws28xx.ZeroPulse = new(14, true, 34, false);

RmtCommand 类的构造函数是这样的:

RmtCommand(ushort duration1, bool level1, ushort duration2, bool level2)

咱们可以这样理解:一个周期内有两个电平,level1 和 level2,如果是true就是高电平否则低电平;duration1 描述 level1 的持续时间,duration2 描述 level2 的持续时间。假设持续时间是 100,如果分频是80,那么正好是 1us,可是咱们分频是2,就变成 100*0.025 us 了。毕竟分频后会变慢。

 

接下来看看 SPI 实现。

要安装这几个 Nuget 包:

1、nanoFramework.Iot.Device.Ws28xx

2、nanoFramework.Hardware.Esp32

3、nanoFramework.System.Device.Spi

其他的因为依赖关系会自动安装。

这个 iot 库里面,没有 Ws2812c 类,只有 ws2812b 类,但目前测试来看,能正常使用。

SPI 方案主要是用到了 MOSI 接口,虽然在初始化 SPI 总线时会设置几个引脚,但实际上只连接 MOSI 即可。

 // 设置引脚的功能
 Configuration.SetPinFunction(23, DeviceFunction.SPI1_MOSI);
 Configuration.SetPinFunction(19, DeviceFunction.SPI1_MISO);
 Configuration.SetPinFunction(18, DeviceFunction.SPI1_CLOCK);
 // 这里有两个参数:第一个是SPI总线ID,第二个是片选引脚,-1表示不使用
 SpiConnectionSettings cset = new(1, -1)
 {
     Mode = SpiMode.Mode0,
     ClockFrequency = 2400000,   // 通信频率
     DataBitLength = 8
 };
 // 初始化SPI设备
 SpiDevice spidev = SpiDevice.Create(cset);

 Ws28xx ws2812 = new Ws2812b(spidev, PxCount);
 // 获取图像对象
 var bmp = ws2812.Image;

 int i = default;
 // 进入循环
 while (true)
 {
     for(i=0; i<PxCount; i++)
     {
         bmp.SetPixel(i, 0, Color.Blue);
         ws2812.Update();
         Thread.Sleep(DelayMS);
     }
     for(i=PxCount -1 ; i >= 0;i--)
     {
         bmp.SetPixel(i, 0, Color.Red);
         ws2812.Update();
         Thread.Sleep(DelayMS);
     }
     for(i=0; i<PxCount; i++)
     {
         bmp.SetPixel(i,0,Color.Green);
         ws2812.Update();
         Thread.Sleep(DelayMS);
     }
     for(i=PxCount -1 ;i >= 0;i--)
     {
         bmp.SetPixel(i, 0, Color.WhiteSmoke);
         ws2812.Update();
         Thread.Sleep(DelayMS);
     }

 }

SPI 方式稍麻烦一点,用到的IO口有 18、19、23,而灯带只需连接 23 即可。注意在设置引脚功能时,如果选择 SPI1_MOSI、SPI1_CLOCK 等值,那说明用的是 SPI_1,在实例化 SpiConnectionSettings 对象时,busid 参数就是 1;如果设置功能时使用的是 SPI2_MOSI、SPI2_MISO、SPI2_CLOCK,那么实例化 SpiConnectionSettings 时 busid 是 2。虽然 ESP32 有四路 SPI,但前两路内部保留的,外设只用后两个,即 HSPI 和 VSPI,这两个名字也够奇葩的,其实用起来是一样。这破名字容易使人误认为 VSPI 是虚拟SPI,HSPI 是硬件SPI。

咱们在程序代码中指定的 SPI_1 和 SPI_2 就是 HSPI 和 VSPI。

本示例使用 32 个灯珠,在一轮循环中做四次填充:

1、从头到尾,填充蓝色;

2、从尾到头,填充红色;

3、从头到尾,填充绿色;

4、从尾到头,填充烟白色。

效果如下:

【Nano Framework ESP32篇】WS2812 彩色灯带实验

 

好了,今天就水到这里了。文章来源地址https://www.toymoban.com/news/detail-854739.html

到了这里,关于【Nano Framework ESP32篇】WS2812 彩色灯带实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32例程分享-05-WS2812B灯带(单线归零码)

    例程运行结果:    WS2812B是一款全彩LED控制IC,单总线控制, 灯带上的每一位灯珠都可用编程控制全彩显示,通过单片机,我们可以实现任意数量任意颜色任意组合效果的炫彩灯光显示效果。    数据协议采用单线归零码的通讯方式,像素点在上电复位以后,DIN端接受从控制

    2024年02月11日
    浏览(28)
  • WS2812B灯带

     开发WS2812B灯带笔记 目录 什么是WS2812B灯 WS2812B灯带连接原理图 WS2812B灯带的数据和数据传输是啥样的? 补充:什么是RGB? 那么WS2812B灯的24bit数据如何构造? WS2812B灯的逻辑“1”和逻辑“0” 代码部分 实现ns级别延时 WS2812B是一种智能控制LED光源,将控制电路和RGB芯片集成在

    2024年02月07日
    浏览(34)
  • 软件STM32cubeIDE下STM32F1xx使用定时器(TIM8)+DMA+PWM点亮灯带WS2812-基础样例

    好长时间不调试灯带ws2812了,最近项目上,要在STM32F1上进行点灯带ws2812,虽然自己之前做了很多了,但是人有个性质,一旦某个事情做完了,你不在去惦记它了,基本会完全抛在脑后。所以才体现记录的重要性,本次在做STM32F1上验证时,即使之前有经验的情况下,还是掉坑

    2024年02月01日
    浏览(53)
  • ESP32(MicroPython) 网页控制环形WS2812

    ESP32(MicroPython)网页控制环形WS2812 本程序用于提供网页控制环形WS2812,为了不影响网页正常运行,本程序取消了流水灯形式,改为每个灯或每2个灯或每4个灯取随机亮度,延时和亮度可调。主控换成ESP32C3,感觉网页流畅度比ESP32-EROOM32低一些。 程序如下

    2024年02月15日
    浏览(36)
  • WS2812+ESP32 diy拾音灯+各种灯效 通过Blinker控制

    软件版本:2.0.0 2023.02.08 修复软件开机自启动相关bug,具体为bat文件创建快捷方式时起始路径错误导致无法创建ip.bin 修复方式为快捷方式时起始路径向前一级 后续如有更新会更新博客。 ESP32开发板一个 ws2812灯带一条(我买的60灯珠) 杜邦线几根(公对母,主要用于灯带和开

    2023年04月18日
    浏览(33)
  • ESP32(MicroPython) WS2812点阵+可交互超声波云台+网页显示温湿度

    ESP32 RGB点阵 三种随机颜色模式 由于之前的RGB点阵程序中的后两个模式灯的颜色过饱和影响观感,本程序把这两个模式整合到所有灯取随机颜色的程序,分别实现所有灯各取随机颜色、每一圈的灯取随机颜色和每相邻4灯取同一种随机颜色。 本程序增加了服务器功能,可以通

    2024年02月12日
    浏览(39)
  • 【Nano Framework ESP32篇】使用 LCD 屏幕

    在开始主题之前,先介绍一个刷固件工具。这个工具在 idf 中是集成的,不过,乐鑫也单独发布了这个工具—— esptool。下载链接:Releases · espressif/esptool · GitHub。这货是用 Python 写的,只是封装成了 exe,方便直接运行罢了。 在使用时,需要 -p 参数指定串口号,如 COM15,-b 指

    2024年04月28日
    浏览(26)
  • 【Nano Framework ESP32 篇】刷入 nanoCLR 固件以及相关问题

    老周在几个世纪前曾写过树莓派相关的 iOT 水文,之所以没写 Nano Framework 相关的内容,是因为那时候这货还不成熟,可玩性不高。不过,这货现在已经相对完善,老周都把它用在项目上了——第一个是自制的智能插座,这个某宝上50多块可以买到,搜“esp32 插座”就能找到。

    2024年04月13日
    浏览(25)
  • (STM32笔记5)ws2812驱动开发

    ws2812 需要开发的外设:ws2812 开发环境:MDK 开发板:stm32最小系统板 杜邦线无数 一、原理阐述 (一) 这个ws2812有很多种,一个小灯、灯带,矩形像素屏等等。 这些都是DIN连接输入,DOUT连接输出,另外两个引脚是GNE和VCC   (二) 数据传输原理: 第1个WS2812B灯珠接收到了第1个

    2024年01月19日
    浏览(36)
  • STM32驱动全彩LED灯模块WS2812

    WS2812全彩LED灯模块系列,可以进行级联实现灯带的效果,MCU端通过一个管脚可以控制所有级联的LED灯的不同发光颜色显示。 WS2811(未集成LED)的级联电路如下所示: WS2812(集成LED)的级联电路如下所示: STM32是3.3V供电芯片,输出Push-Pull模式只有3.3V,WS2812采用5V供电,输入Vi

    2024年01月17日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包