开发者成长激励计划-基于 TencentOS Tiny 的 Smart RGB Light DIY 之路

2022-08-18 15:11:41 浏览数 (2)

0x00.前言

首先感谢主办方提供这次活动,依旧是不收一分钱外加顺丰特快包邮,这条件甚至要优于自己上大学的时候,毕竟那时候学习在用的开发板还都是自己买的呢……虽然报名的晚,但是汪总还是给通过了,再次感谢下,其实报名晚的其中一个原因是在想要做的方向,所以没有着急填表,结果没想到就鸽到了最后……

  • 在讲这次要做的内容之前,先说下上次要做的东西是可以给家里的 ESXi 服务器远程开关机的开关,类似于 SwitchBot,虽然上次比赛(https://cloud.tencent.com/developer/article/1956609)因为被 AI 吸引了注意力最终没有实现,但是这件事情还是要完成的,不过变成了用舵机控制关闭墙上的开关。其实控制墙上的开关比电脑的开关还要更难,毕竟不会像直接贴到机箱上那么简单的了,墙上竖着的开关相比机箱上平的开关,不仅可选择摆放的位置变少了,发力方向也不再与重力平行,并且即使用 SwitchBot 效果也不一定就很好,RT
https://www.bilibili.com/video/BV1WQ4y167bUhttps://www.bilibili.com/video/BV1WQ4y167bU
  • 然后是这次要做的东西,是想 DIY 一个氛围灯或者是床头灯,主要还是因为市面上的成品价格也太离谱了吧,不就是一堆发光 LED 上云控制,到底是什么的成本让最终零售价能到达三位数?
氛围灯氛围灯
床头灯床头灯

看这价格,告辞!趁这次比赛的机会,为啥 DIY 一个出来呢?自己动手,丰衣足食,没有多想就去下单了 WS2812B 灯带

0x01.代码 视频 PPT

代码:https://github.com/yuangezhizao/CH32V307_EVB

PPT:

基于 TencentOS Tiny 的 Smart RGB Light DIY 之路.pdf

视频:

原始视频

路演视频

封面图

新封面图新封面图
旧封面图旧封面图

0x02.硬件

1.总览

  1. WS2812B 灯带,作为氛围灯
  2. SG90 舵机,用来控制墙上灯的开关
  3. 普通日落灯,是要被控制的
  4. USB 逻辑分析仪,为了方便调试
外围硬件(图左)外围硬件(图左)

2.SG90 舵机

选择它的理由很简单,价格足够便宜,并且即使是 180° 的旋转角度也够用,只要确定好要旋转到哪两个位置能把灯开关就行了

只要五块钱不到一个只要五块钱不到一个

3.WS2812B 灯带

选择它的理由之一,同样是价格足够便宜,最原始的硬件出处可能是这个:Adafruit NeoPixel Digital RGB LED Strip - Black 60 LED - BLACK,https://www.adafruit.com/product/1461,但是 $24.95 的价格,emmm 不是很懂,还有最佳实践介绍:https://learn.adafruit.com/adafruit-neopixel-uberguide/best-practices

一米十块钱左右的价格一米十块钱左右的价格

再一个,则是因为有巨多大佬们的开源项目支持 WS2812B 芯片,光搜索仓库就能得到 2K 多的结果,这基本上保证了基于它做项目是不会翻车的

然后这里根据看到的时间顺序简单举例一下吧,每个项目差不多都是重量级的

  • https://github.com/adafruit/Adafruit_NeoPixel
  • https://github.com/FastLED/FastLED
  • https://github.com/Makuna/NeoPixelBus
  • https://github.com/scottlawsonbc/audio-reactive-led-strip
  • https://github.com/microsoft/pxt-neopixel
  • https://github.com/kitesurfer1404/WS2812FX

0x03.软件

1. EVT 例程学习

有了上次的比赛经验,这次学会了,没有先看数据手册和应用手册,上来就把 EVT 的各个例程看了一遍,能烧录的都烧录进去了,然后观察现象,这样做之后就能知道自己需要的功能可以通过修改哪些例程来实现了,比如下面的部分示例就是参考的官方例程

2. 裁剪 TencentOS-Tiny 操作系统

通过 MRS 创建的例程是 2.4.5,不是最新的 2.5.2,反正自己也要整理文件夹结构,所以就先进行了裁剪

裁剪就不多说了,比如那些什么用不到的 pm 低功耗模块都可以干掉了,最终集中整理到 TencentOS_Tiny 文件夹下

剩余文件夹的内容保留自 MRS 创建的例程

3.操作系统的使用

在 examples 的 application_entry.c 文件中,起了 1 个消息队列,3 个任务

  • 1 个消息队列用于 mqtt 收到的下发命令转发到 WS2812B 控制任务中
  • 3 个任务分别是:WS2812B 控制任务,刷新屏幕任务,mqtt 任务
  • SD 卡和 KV 存储调好了,但 fatfs 和 vfs 未调好,故暂未使用
  • 烧录 ESP8266 腾讯云固件,所以 iot explorer 相关也被上一步裁剪掉了
操作系统 Task 示意图操作系统 Task 示意图

4. 单片机资源的使用

  • 频率拉满 144MHz
  • EXTI 中断检测按键
  • TIM4 输出 PWM 控制 SG90 舵机
  • SPI DMA 控制 WS2812B 灯带
  • RTC ON!
  • TIM6 中断控制 LED1 每秒闪烁

0x04.模块简述

1.SG90 舵机

原理网上有很多讲解的文章,这里贴几张图示意一下

参照原理图和手册,最终选择了 PD12 引脚,是位于「拓展 IO 」部分的,已经被引出来了可以直接插上去使用不用飞线

PD12PD12

查看应用手册,需要重映射 GPIO_Remap_TIM4,还不要忘记打开 AFIO 时钟

查看数据手册,PD12 是可以重映射到 TIM4_CH1_1 的

就像这样GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE);

初始化 TIM4 的 Channel1,设定 TIM_PSC=14400 - 1,ARR200 - 1

然后通过调用 TIM_SetCompare1 就能改变角度了

最大的难题在于怎么把它固定到墙上,因为觉得效果不好还买了 3M 的胶,效果好太多

2. WS2812B 驱动

移植成果:https://github.com/yuangezhizao/CH32V307_EVB/blob/RGB/User/ws2812_SPI.c

其实 MRS 里是有 WS2812B 的例程的,看了那里面的写法真就是堆 nop,另外那个是 C 写的,还有与 Arduino 相关的库

然后,搜了下常见的方法,要么是这种堆 nop,要么是 PWM DMA,要么是 SPI DMA

这里先调通的是 SPI DMA,PWM DMA 后来也试了,但暂时还没有调通

在社区也看到有人发帖,CH32V307 DMA PWM控制彩灯,脉冲数异常:https://www.wch.cn/bbs/thread-91018-1.html

使用 PB15 引脚,也就是SPI2_MOSI

TX 管脚在 DMA1 通道 5

WS2812B 对时序要求非常高,需要控制输出 0.4us 和 0.85us 的精度,上下浮动 150ns,恐怖如斯

这里本来是一边改着代码,一边拿逻辑分析仪看波形,一直觉得好像还是不对的样子,然后随手接上去竟然亮了……

这里对比贴出 RPI PICO 驱动的波形图,可以看出是 800kHz,高电平 250ns,低电平 1us,非常规整!

高电平高电平
低电平低电平

3. 显示屏

用 GPIO 控制日落灯太简单了就不说了,甚至接口都是沿用的 E53_SC1 上的那个灯的 PC10,点了这么多次的灯总该换一个了吧 2333

所以这里来说下显示屏部分,上面滚动播放的 4 张图片是来自 pic.h 的,每张 120*120 像素

尝试过 240*240 像素,结果只能放下一张,再来一张就爆 FLASH 大小了,虽然有成功把 115200 的图片数组塞到 SD 卡里,然是似乎取出来之后函数间传参没有跑通,不知道是不是因为 RAM 也不够用的

再一个 fs 没有调通还是不太方便,SD 卡插到电脑上也不知道怎么才能读出来用单片机写入的大数组,似乎连分区表都没有?

然后是 RTC (未来可作为离线定时触发源)

再下面显示的部分是灯的状态,再每次等切换的时候会触发更新,而不是每次刷新屏幕时都会刷新

三种灯的状态:

一、RGB Type 显示具体输出的类型

①color_wipe ②theater_chase ③rainbow ④rainbow_cycle ⑤theater_chase_rain

二、Sunset Light 和 Bedroom Light 为开关值

4. mqtt 任务

接收部分会收到控制命令,如果是舵机和日落灯就直接控制硬件操作了

如果是氛围灯,则需要发到消息队列里,因为这是两个任务了

然后 WS2812B 任务里会把消息队列里的消息取出来,整形枚举值映射成不同的类型,最后驱动灯带显示

这里消息队列传递的是指针,workaround 把整形转成了字符串,感觉用法有点儿奇怪,后期还会再查查

看邮箱传递的是值,应该比现在自己转成字符串再字符串对比要优雅吧

等待消息等待消息
发送消息发送消息

0x05.云平台

老生常谈的 iotexplorer,简单贴几张图吧

数据开发中可以指定规则,微信公众号下发通知

0x06.MRS

  • 可以通过右键选择是否编译,非常方便
  • 添加--print-memory-usage可以查看最终编译产物的内存占比

0x07.实际使用

首先是吸顶灯和日落灯

然后再主要说明下自己的氛围灯准备用在卧室的哪些地方

  • 床头灯:https://mastodon.yuangezhizao.cn/@yuangezhizao/108824846727694299
  • 显示器
  • 机箱内

0x08.后记

update:

•感谢主办方提供的这次活动,借此机会实现了自己的想法

•WS2812B 驱动移植只实现了部分模式,未来还会继续移植

•SD 卡和 KV 存储没有利用上,有点儿遗憾

•RTC 时钟对时可以参照系统级 topic 里的 NTP 时间

最开始翻阅 EVT 例程然后照着改,一遍改代码一边拿逻辑分析仪看现象,真的是收获了不少经验

这次比赛终于不鸽,完成了自己的作品,自己实际中已经用上了,非常开心

比赛中还经历了很多有趣的事情,在结束前有时间的话还会补充到文章中,已补充

远哥制造

220811

0 人点赞