Blinker项目实例:Nodemcu驱动ws2812(附项目代码)

Blinker项目实例:Nodemcu驱动ws2812

一、 实验目的和要求
   (1) 计并开发一个网络应用软件系统 二、 实验内容和原理 实验内容: 本实验的目的是设计并开发一个物联网彩灯系统,用于智能化的居家氛围布置、照明。系统的操控方式为手机APP控制,通过MQTT远程实现。完成的功能有自由控制颜色、亮度,既可以所有的LED灯一起进行操作,也可以对单独LED等进行操作;一键彩灯,按下按钮,即可按照设定好的氛围光亮起彩灯,营造独特的氛围。本实验对氛围光只设定一个模式作为例子,具体应用时完全可以添加更多的模式。另外,彩灯不仅使用与氛围布置,还兼容学习场合,一键可以调整至护眼模式。

开发语言: C语言(Arduino平台)

二、 架构设计
1、硬件部分
   硬件包括一块Nodemcu开发板、一个WS2812灯带、一台智能手机。
   (1)nodemcu开发板。NodeMCU,是一个开源的物联网平台,使用esp8266作为核心 它使用Lua脚本语言编程,同时也可以使用Arduino进行编程。硬件配置主要有16个GPIO引脚,可实现1个模拟I/O和11个数字I/O。通讯接口有一个USB口、一个串口和一个Wifi通讯模块。本实验主要用到GPIO引脚来驱动WS2812,使用Wifi模块连接网络与服务器、手机进行通讯。Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第1张图片

   (2) WS2812。WS2812B是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同,每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路,还包含有高精度的内部振荡器和12V高压可编程定电流控制部分,有效保证了像素点光的颜色高度一致。数据协议采用单线归零码的通讯方式,像素点在上电复位以后,DIN端接受从控制器传输过来的数据,首先送过来的24bit数据被第一个像素点提取后,送到像素点内部的数据锁存器,剩余的数据经过内部整形处理电路整形放大后通过DO端口开始转发输出给下一个级联的像素点,每经过一个像素点的传输,信号减少24bit。像素点采用自动整形转发技术,使得该像素点的级联个数不受信号传送的限制,仅仅受限信号传输速度要求。LED具有低电压驱动,环保节能,亮度高,散射角度大,一致性好,超低功率,超长寿命等优点。将控制电路集成于LED上面,电路变得更加简单,体积小,安装更加简便。

2、 软件部分
   blinker是一套跨硬件、跨平台的物联网解决方案,提供APP端、设备端、服务器端支持,使用公有云服务进行数据传输存储。可用于智能家居、数据监测等领域,可以帮助用户更好更快地搭建物联网项目。Blinker由服务器端、app端、设备端组成,可以部署到几乎所有物联网平台,使用WiFi、MQTT等方式接入,服务器端可以部署到阿里云、腾讯云、OneNET、百度云、AWS、google cloud等平台,通过界面布局器,DIY用户可自己拖拽布局设备控制界面,自由打造专属的物联网设备。

Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第2张图片

3、 系统连接
(1)Nodemcu和WS2812的连接方式如下:

Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第3张图片

   以上红色箭头分别是D7、GND和VCC,其中Nodemcu的Vcc和ws2812的Vcc相连,Nodemcu的GND和ws2812的GND相连,Nodemcu的D7和ws2812的S(信号线)相连。
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第4张图片
   需要注意的是,ws2812所有的灯全亮电流超过500mA,无法通过电脑进行供电,需要外接电源。因此ws2812其实有两根VCC和两根GND。这两根线是短路的,具体连接的时候一根GND连接Nodemcu的GND,另一根GND连接5V直流电源的GND。但是VCC不能两根都连,一根VCC连接5V直流电源,另外一根VCC悬空。另外,信号线和Nodemcu的D7相连即可。(1)Nodemcu和手机APP的通信。本实验没有直接搭建服务器,而是采用了blinker解决方案的服务器。Nodemcu需要处于一个有wifi的局域网环境下,通过wifi接入Internet。通讯使用MQTT方式,即便用户离开了现场也能够进行操控。Nodemcu将秘钥发送到blinker服务器并建立连接,手机APP通过开关按键发送秘钥到服务器同样建立连接。服务器识别到Nodemcu和客户端同时发来了秘钥后,开始在两者之间传递命令协议。每个命令的发出都需要两步,一是客户端向Nodemcu发送指令,二是Nodemcu返回一个确认信息,客户端接收到之后确认操作完成。

三、主要仪器设备
1、一块Nodemcu开发板
2、一个WS2812灯条
3、Blinker手机app

四、设计要点
   (1)下载正确的库文件。本实验对ws2812的操作与对单个LED不同,点亮单个基色LED编写好PWM程序就可以调节亮度,不同亮度的三基色LED叠在一起就能呈现不同的颜色。但是ws2812是成线性排列的,所有的LED公用同一个根信号线,因此不能对LED进行单独操作。此处需要用到ws2812的库函数对其进行操作。 在github中搜索blinker library找到资源并下载,将下载好的blinker库解压到 我的电脑>文档>Arduino>libraries 文件夹中
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第5张图片
   (2)获得IoT设备秘钥。秘钥相当于一个设备的ID,服务器要找到特定的IoT设备,必须依赖该秘钥。打开blinker app,点击右上角的‘+’号,选择Arduino,获得秘钥并复制。

Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第6张图片
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第7张图片

   (3)代码中的IoT秘钥、wifi名称、wifi秘钥必须正确输入,否则设备无法与服务器连接。
在这里插入图片描述

   (4)组件名称要和代码对应。如LEDNum对应Number_1,LED_R对应Number_2.

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第8张图片

四、 实验结果与分析
1、搭建好的硬件如下:
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第9张图片

Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第10张图片
2、APP界面及组件如下:

Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第11张图片

3、工作时间显示:工作时间能够实时更新
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第12张图片

2、自由控制(整体)模式:按下自由模式,按钮高亮,点击任一颜色,灯颜色改变,手机上显示对应RGB值。图中可以看出选中绿色RGB是[0,255,52]
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第13张图片
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第14张图片
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第15张图片 Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第16张图片

3、七彩模式:按下七彩模式,按钮高亮,ws2812直接显示一个绚烂的彩色灯条。

Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第17张图片
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第18张图片

4、逐个调节模式。按下逐个调节模式按钮,按钮高亮。这时可以按顺序依次调节每一个灯珠的RGB值,当从第一个到最后一个都调整过以后,又重新回到第一个,循环进行。实验中为了显示每个灯珠都可以自由调节,特意相邻的灯珠选择了反差明显的颜色。
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第19张图片
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第20张图片

5、护眼照明模式。按下护眼照明模式按钮,按钮高亮。一键调整至护眼模式,此时是柔和的黄光。

Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第21张图片
Blinker项目实例:Nodemcu驱动ws2812(附项目代码)_第22张图片
   以上结果达到预期要求。另外需要说明的是,本实验对灯光效果只设定一个模式作为例子,具体应用时完全可以添加更多的模式。

五、实验注意
   1、本实验主要的代码内容是硬件设备Nodemcu上的,编写硬件代码比较麻烦的是参数的选取(关系到硬件是否能正产工作)。实验时一开始时将ws2812的144个灯珠全部点亮,带来了严重的问题,电脑突然掉电。重启后Windows系统提示USB口电流过大,无法继续使用。幸好内部电路没有破坏性损坏,冷却下来之后仍然能继续工作,否则我的电脑就会损失一个USB口。
   2、明确电脑无法直接给ws2812供电之后,又找了一个220V转5V的电源适配器来给ws2812供电(先接在面包板上再借ws2812)。这样一来144个LED灯珠都能正常工作。然而偶然触摸面包板温度非常高,迅速拔掉电源后发现面包板已经严重融化。可见144个灯珠同时亮起电流过大。
   3、最终才确定只点亮20个LED灯珠,防止再次出现意外。

六、附实验代码(C语言)

六、附实验代码(C语言)#define BLINKER_WIFI#include 
<Blinker.h>#include<math.h> 
char auth[] = "692310ffgrt";//IoT秘钥
char ssid[] = "ONEPLUS";//wifi名称
char pswd[] = "55555555"; //wifi秘钥
bool tab[5] = { false };
bool modestate[4] = { false }; //工作模式选项卡
bool AutoBit= false; //判断手动模式是否有效
bool SingleAdjust= false;//判断逐个调节是否有效
int LEDserial=0;//
int Offset=20;  //灯珠整体移动若干单位
#include #ifdef __AVR__  #include #endif #if defined (__AVR_ATtiny85__)  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);#endif  #define PIN            13#define NUMPIXELS      20#define RGB_1 "RGBKey"#define Tab_1 "tab-mode"#define Number_1 "LEDNum"#define Number_2 "LED_R"#define Number_3 "LED_G"#define Number_4 "LED_B"  BlinkerRGB WS2812(RGB_1);BlinkerTab Tab1(Tab_1);//定义数据结构
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
BlinkerNumber Number1 (Number_1);
BlinkerNumber Number2 (Number_2);
BlinkerNumber Number3 (Number_3);
BlinkerNumber Number4 (Number_4); //*************************************************************//选项卡触发函数
void tab1_callback(uint8_t tab_set){    //BLINKER_LOG("get tab set: ", tab_set);    
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));     
switch (tab_set)    {        
case BLINKER_CMD_TAB_0 :            
tab[0] = true;            //BLINKER_LOG("tab 0 set");            
AutoBit=!AutoBit;//手动位取反            
break;        
case BLINKER_CMD_TAB_1 :            
tab[1] = true;            //BLINKER_LOG("tab 1 set");            
Mode1();//开启Mode1,灯光模式1            
break;                    
case BLINKER_CMD_TAB_2 :            
tab[2] = true;            //BLINKER_LOG("tab 2 set");            
SingleAdjust=!SingleAdjust;//开启Mode2,灯光模式2            break;        
case BLINKER_CMD_TAB_3 :            
tab[3] = true;            //BLINKER_LOG("tab 3 set");            
Mode3();//开启Mode3,流水灯模式            
break;        
case BLINKER_CMD_TAB_4 :            
tab[4] = true;            //BLINKER_LOG("tab 4 set");            
break;        
default:            
break;    }} 
void tab1_feedback(){
    
for(uint8_t num = 0; num < 5; num++)    {        
if (tab[num])        {            
Tab1.tab(num);            
tab[num] = false;        }    }    
Tab1.print();}  //*******************************************************************//自由模式整体调节/逐个调节服务函数 
void ws2812_callback(uint8_t r_value, uint8_t g_value, uint8_t b_value, uint8_t bright_value){    
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));   
if (AutoBit==true){           digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));         
Mode0(r_value,g_value,b_value,bright_value);       return NULL;    }    
else if(SingleAdjust==true){      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));      
Mode2(r_value,g_value,b_value,bright_value);    }} 
//********************************************************************//自由控制(整体调节)Mode0
void Mode0(uint8_t r_value, uint8_t g_value, uint8_t b_value, uint8_t bright_value){    
pixels.setBrightness(bright_value);    
for(int i = 0; i < NUMPIXELS; i++){    
pixels.setPixelColor(i, r_value, g_value, b_value);        }    
pixels.show();     
Number2.print(r_value);    
Number3.print(g_value);    
Number4.print(b_value);}
//********************************************************************//七色模式Mode1
void Mode1(){    
int r=0;    int g=0;    int b=0;    int i=0;    int full=NUMPIXELS;    
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));    
for(int i=0;i<NUMPIXELS;i++){           if(i<full/3){            r=255;            g=ceil(255*3*i/full);            b=0;            }else if(i<full/2){                r=ceil(750-i*(250*6/full));                g=255;                b=0;            }else if(i<full*2/3){                r=0;                g=255;                b=ceil(i*(250*6/full)-750);            }else if(i<full*5/6){                r=0;                g=ceil(1250-i*(250*6/full));                b=255;            }else{                r=ceil(150*i*(6/full)-750);                g=0;                b=255;                  }             pixels.setPixelColor(i, pixels.Color(r,g,b));             }    pixels.show();     }//********************************************************************//逐个调节Mode2
void Mode2(uint8_t r_value, uint8_t g_value, uint8_t b_value, uint8_t bright_value){     pixels.setBrightness(bright_value);    pixels.setPixelColor(LEDserial, r_value, g_value, b_value);      pixels.show();        LEDserial=LEDserial+1;    LEDserial= LEDserial % NUMPIXELS;    Number2.print(r_value);    Number3.print(g_value);    Number4.print(b_value);    }//*******************************************************************//护眼照明模式 黄光Mode3
void Mode3(){        int bright_value=200;        int r_value=255;        int g_value=215;        int b_value=0;        pixels.setBrightness(bright_value);        for(int i = 0; i < NUMPIXELS; i++){        pixels.setPixelColor(i, r_value, g_value, b_value);        }               pixels.show();           Number2.print(r_value);        Number3.print(g_value);        Number4.print(b_value);}//*******************************************************************//显示数值
void dataRead(const String & data){    uint32_t BlinkerTime = millis();     Number1.print(BlinkerTime/1000);}  //*********************************************************************
void setup(){    Serial.begin(115200);    BLINKER_DEBUG.stream(Serial);        Blinker.attachData(dataRead);     pinMode(LED_BUILTIN, OUTPUT);//引脚设置为输出模式    
digitalWrite(LED_BUILTIN, LOW);     Blinker.begin(auth, ssid, pswd);       pixels.begin();//开启pixel对ws2812输出    
WS2812.attach(ws2812_callback);    
Tab1.attach(tab1_callback, 
tab1_feedback);     
 } 
void loop(){    Blinker.run();}

你可能感兴趣的:(Blinker项目实例:Nodemcu驱动ws2812(附项目代码))