WS2812还能这么玩?!AI控制、自动感温变色...

本文为【星空灯DIY】活动的优秀作品之一,楼主@shihengrui在原教程的基础上添加了音乐播放、灯光感温切换冷暖色、小爱同学语音控制三个功能。现在分享出来,供大家学习参考,文末有开源代码和PCB文件,感兴趣的粉丝滑到文末获取~
▶ 主控选择
看到《星空灯教程》做的那个,好像只是把灯放进去了,nucleo板子放在外面,不太美观。考虑到要添加WIFI控制功能,板子也要更小一点能放进罩子里,我打算使用一片ESP8266,既有IO能够控制灯环,还自带WIFI功能,主要是便宜,仅仅10元。(送女朋友的当然能省则省,反正论坛没人知道我女朋友,我也不怕有人打小报告
真白菜价,我选择了外围器件最少的ESP-12S,内部自带上下拉电阻。
▶ 灯环选择
本来我已经画好了PCB,准备直接干30颗灯珠(巨亮),后来想想上次焊灯珠时候的报废率,我放弃了,还是选择现成12位的灯环。
▶ 扩展功能
(1)不仅是简单的小清新星空灯,也要是动次打次半镭射灯,所以少不了动次打次音乐播放功能,我选择了一款简单的串口控制的MP3模块:
还有喇叭:
(2)我添加了一个温湿度传感器,在不动次打次的时候,可以让灯光跟随温度或湿度变换冷暖,用的是DHT11:
▶ 原理图
原理图和PCB我用了国产软件立创EDA,效果非常好。
下面展示原理图:
原理图
PCB(2D)
PCB(3D)
实物图
可以说相当帅气了
▶ 点灯
这次我使用了高效率的arduino开发,开发环境在这里不再说了。点灯我们用的是WS2812,arduino有现成的库,我下载的是这个:
程序如下:
←左右滑动,查看代码→
#include <Adafruit_NeoPixel.h>
#define WS2811_PIN D1
#define MAX_LED 12
Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, WS2811_PIN, NEO_RGB + NEO_KHZ800 );
uint8 RGB[][3] = {
{ 0xFF, 0x00, 0x00 },
{ 0x00, 0xFF, 0xFF },
{ 0x00, 0x00, 0xFF },
{ 0x00, 0x00, 0xA0 },
{ 0xFF, 0x00, 0x80 },
{ 0x80, 0x00, 0x80 },
{ 0xFF, 0xFF, 0x00 },
{ 0x00, 0xFF, 0x00 },
{ 0xFF, 0x00, 0xFF },
{ 0xFF, 0xFF, 0xFF },
{ 0xC0, 0xC0, 0xC0 },
{ 0x00, 0x00, 0x00 },
{ 0xFF, 0x80, 0x40 },
{ 0x80, 0x40, 0x00 },
{ 0x80, 0x00, 0x00 },
{ 0x80, 0x80, 0x00 },
{ 0x40, 0x80, 0x80 }
};
void setup() {
strip.begin();
// 初始化时关闭所有LED
strip.show();
}
void loop() {
// 循环输出七彩色
for (uint16_t i = 0; i < sizeof(RGB) / sizeof(RGB[0]); i++)
{
// 设置颜色,参数为 R G B,范围0-255
uint32_t color = strip.Color(RGB[i][0], RGB[i][1], RGB[i][2]);;
for (uint16_t j = 0; j < MAX_LED; j++)
{
strip.setPixelColor(j, color);
}
// 发送数据并显示
strip.show();
// 延时500毫秒
delay(500);
}
}
▶ 播放音乐
同样,这个模块arduino同样有库,所以...
程序如下:
←左右滑动,查看代码→
#include "DFRobotDFPlayerMini.h"
DFRobotDFPlayerMini myDFPlayer;
void setup() {
Serial.begin (9600);
myDFPlayer.begin(Serial);
myDFPlayer.volume(20); //Set volume value. From 0 to 30
myDFPlayer.play(1); //Play the first mp3
myDFPlayer.next();//Play the next mp3
}
void loop() {
delay(500);
}
}
温湿度搞起,同样还有库
程序如下:
←左右滑动,查看代码→
#include <Adafruit_NeoPixel.h>
#include "DHT.h"
#define WS2811_PIN D1
#define DHTPIN D4
#define MAX_LED 12
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, WS2811_PIN, NEO_RGB + NEO_KHZ800 );
uint8 RGB[][3] = {
{ 0xFF, 0x00, 0x00 },
{ 0x00, 0xFF, 0xFF },
{ 0x00, 0x00, 0xFF },
{ 0x00, 0x00, 0xA0 },
{ 0xFF, 0x00, 0x80 },
{ 0x80, 0x00, 0x80 },
{ 0xFF, 0xFF, 0x00 },
{ 0x00, 0xFF, 0x00 },
{ 0xFF, 0x00, 0xFF },
{ 0xFF, 0xFF, 0xFF },
{ 0xC0, 0xC0, 0xC0 },
{ 0x00, 0x00, 0x00 },
{ 0xFF, 0x80, 0x40 },
{ 0x80, 0x40, 0x00 },
{ 0x80, 0x00, 0x00 },
{ 0x80, 0x80, 0x00 },
{ 0x40, 0x80, 0x80 }
};
void setup() {
Serial.begin (9600);
strip.begin();
// 初始化时关闭所有LED
strip.show();
Serial.println(F("DHTxx test!"));
dht.begin();
}
void loop() {
delay(2000);
uint8 i;
float Hum = dht.readHumidity();//湿度
float Tem = dht.readTemperature();//温度
i = Tem/3;
uint32_t color = strip.Color(RGB[i][0], RGB[i][1], RGB[i][2]);
for (uint16_t j = 0; j < MAX_LED; j++)
{
strip.setPixelColor(j, color);
}
strip.show();
}
给星空灯加上远程控制,顺便能用小爱同学控制,所以选择了很容易上手的平台。
点灯-blink首先官网下载库,并添加:
下载APP并获取Secret Key:
打开例程并修改:
←左右滑动,查看代码→
#define BLINKER_MIOT_LIGHT //定义为语音控制灯设备
#define BLINKER_WIFI
#include <Adafruit_NeoPixel.h>
#include <Blinker.h>
#include "DHT.h"
#define WS2811_PIN D1
#define MAX_LED 12
Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, WS2811_PIN, NEO_RGB + NEO_KHZ800 );
char auth[] = "df246276026c";
char ssid[] = "mjy@2";
char pswd[] = "3673671040";
BlinkerButton Button1("btn-led"); //btn-abc 名称要和app新建组件一致
// app 端按下按键即会执行该函数 回调函数
void button1_callback(const String & state) {
BLINKER_LOG("get button state: ", state);
if (state=="on") {
uint32_t color = strip.Color(255, 255, 255);
for (uint16_t j = 0; j < MAX_LED; j++)
{
strip.setPixelColor(j, color);
}
// 发送数据并显示
strip.show();
// 反馈开关状态
Button1.print("on");
} else if(state=="off"){
uint32_t color = strip.Color(0, 0, 0);
for (uint16_t j = 0; j < MAX_LED; j++)
{
strip.setPixelColor(j, color);
}
// 发送数据并显示
strip.show();
// 反馈开关状态
Button1.print("off");
}
}
void setup() {
// 初始化串口,并开启调试信息
Serial.begin(9600);
BLINKER_DEBUG.stream(Serial); //串口打印调试信息
strip.begin();
// 初始化时关闭所有LED
strip.show();
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Button1.attach(button1_callback); //绑定按键执行回调函数
}
void loop() {
Blinker.run(); /*每次运行都会将设备收到的数据进行一次解析。
在使用WiFi接入时,该语句也负责保持网络连接*/
}
点灯平台还支持小爱同学控制:
直接上小爱同学点灯,这里用了一个调色和开关:
文档写的很清楚,不多说了,直接上程序:
←左右滑动,查看代码→
#define BLINKER_MIOT_LIGHT //定义为语音控制灯设备
#define BLINKER_WIFI
#include <Adafruit_NeoPixel.h>
#include <Blinker.h>
#define WS2811_PIN D1
#define MAX_LED 12
Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, WS2811_PIN, NEO_RGB + NEO_KHZ800 );
char auth[] = "df246276026c";
char ssid[] = "mjy@2";
char pswd[] = "3673671040";
BlinkerButton Button1("btn-led"); //btn-abc 名称要和app新建组件一致
BlinkerRGB WS2812("RGBKey");
uint8 RGB[][3] = {
{ 255, 0 , 0 },
{ 255, 128, 0 },
{ 255, 255, 0 },
{ 0 , 255, 0 },
{ 0 , 255, 255 },
{ 0 , 0 , 255 },
{ 128, 0 , 255 },
};
// app 端按下按键即会执行该函数 回调函数
void button1_callback(const String & state) {
BLINKER_LOG("get button state: ", state);
if (state=="on") {
uint32_t color = strip.Color(255, 255, 255);
for (uint16_t j = 0; j < MAX_LED; j++)
{
strip.setPixelColor(j, color);
}
// 发送数据并显示
strip.show();
// 反馈开关状态
Button1.print("on");
} else if(state=="off"){
uint32_t color = strip.Color(0, 0, 0);
for (uint16_t j = 0; j < MAX_LED; j++)
{
strip.setPixelColor(j, color);
}
// 发送数据并显示
strip.show();
// 反馈开关状态
Button1.print("off");
}
}
//小爱电源类回调
void miotPowerState(const String & state)
{
BLINKER_LOG("need set power state: ", state);
if (state == BLINKER_CMD_ON) {
uint32_t color = strip.Color(255, 255, 255);
for (uint16_t j = 0; j < MAX_LED; j++)
{
strip.setPixelColor(j, color);
}
// 发送数据并显示
strip.show();
BlinkerMIOT.powerState("on");
BlinkerMIOT.print();
}
else if (state == BLINKER_CMD_OFF) {
uint32_t color = strip.Color(0, 0, 0);
for (uint16_t j = 0; j < MAX_LED; j++)
{
strip.setPixelColor(j, color);
}
// 发送数据并显示
strip.show();
BlinkerMIOT.powerState("off");
BlinkerMIOT.print();
}
}
void miotColor(int32_t color)
{
uint8 colorR;
uint8 colorG;
uint8 colorB;
BLINKER_LOG("need set color: ", color);
colorR = color >> 16 & 0xFF;
colorG = color >> 8 & 0xFF;
colorB = color & 0xFF;
BLINKER_LOG("colorR: ", colorR, ", colorG: ", colorG, ", colorB: ", colorB);
color = strip.Color( colorG,colorR, colorB);
for (uint16_t j = 0; j < MAX_LED; j++)
{
strip.setPixelColor(j, color);
}
// 发送数据并显示
strip.show();
BlinkerMIOT.color(color);
BlinkerMIOT.print();
}
void ws2812_callback(uint8_t r_value, uint8_t g_value, uint8_t b_value, uint8_t bright_value)
{
BLINKER_LOG("R value: ", r_value);
BLINKER_LOG("G value: ", g_value);
BLINKER_LOG("B value: ", b_value);
BLINKER_LOG("Rrightness value: ", bright_value);
strip.setBrightness(bright_value);
uint32_t color = strip.Color(r_value, g_value, b_value);
for(int i = 0; i < MAX_LED; i++){
strip.setPixelColor(i, color);
}
strip.show();
}
void setup() {
// 初始化串口,并开启调试信息
Serial.begin(9600);
BLINKER_DEBUG.stream(Serial); //串口打印调试信息
strip.begin();
// 初始化时关闭所有LED
strip.show();
dht.begin();
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Button1.attach(button1_callback); //绑定按键执行回调函数
Button2.attach(play_callback);
Button3.attach(stop_callback);
Button4.attach(up_callback);
Button5.attach(down_callback);
Button6.attach(next_callback);
Button7.attach(pre_callback);
Button8.attach(random_callback);
WS2812.attach(ws2812_callback);
BlinkerMIOT.attachPowerState(miotPowerState); //小爱电源控制
BlinkerMIOT.attachColor(miotColor);
Blinker.attachData(dataRead);
Blinker.attachHeartbeat(heartbeat);
}
void loop() {
Blinker.run(); /*每次运行都会将设备收到的数据进行一次解析。
在使用WiFi接入时,该语句也负责保持网络连接*/
}
我觉得难点就在这了。程序都是小问题,我画的PCB直接就是三角形的,再加上螺丝孔,直接上面再架一个三角亚克力板,上边放灯,这样可以直接把灯罩放上去。
有三个面我没有留孔,让女朋友自行选择自己喜欢的(女人心思猜不透
投影效果:
原理图和PCB:
https://oshwhub.com/shihengrui/star-light
程序代码:
http://share.eepw.com.cn/share/download/id/388694
加入“电子产品世界”粉丝交流群
↓↓↓↓点击阅读原文,查看更多新闻

工程师必备
- 项目客服
- 培训客服
- 平台客服
TOP
