一、认识WS2812
1、什么是WS2812
WS2812是一种由数字灯珠组成的智能控制LED光源,其中控制电路和RGB芯片集成在5050元件包中,元件包的内部包括智能数字端口数据锁存器和信号重塑放大驱动电路。
WS2812是采用单总线通讯,每个灯珠由24bit的数据控制灯珠的颜色,即每个灯接受24位的数据为每个灯的颜色像素(RGB,32位数据,高8位为红色,中8位为绿色,低8位为蓝色)。信号线通过IN输入,每经过一个灯珠之后,信号线上前24bit数据会被该灯珠锁存,剩下的数据信号通过OUT输出,由下一个灯珠接受数据,在锁存数据,最后再把数据完整的传输出去。
WS2812的样式有很多,但本质的都是由一个一个灯珠组成的灯条,只是固定为条形、圆形、正方行等等。
2、WS2812模块介绍
(1)一个灯珠
(2)WS2812灯带的原理图
(3)WS2812的数据传输
二、认识Adafruit_NeoPixel.h库
1、添加Adafruit_NeoPixel.h库
(1)vscode platformio 添加库
(2)arduino 添加库
Arduino --> 项目 --> 加载库 --> 管理库 --> 搜索 --> 安装
2、认识Adafruit_NeoPixel.h库
(1)头文件
#include <Adafruit_NeoPixel.h>
(2)定义strip函数
Adafruit_NeoPixel strip(WS2812_NUM, WS2812_PIN, NEO_GRB + NEO_KHZ800);
功能:定义strip函数
参数:
①WS2812_NUM:灯的数量
②WS2812_PIN:灯带的连接引脚
③NEO_GRB + NEO_KHZ800:使用RGB模式控制ws2812类型灯带,灯带的频率为800KH
(3)初始化灯带函数
strip.begin();
功能:初始化灯带
参数:无
(4)输出函数
strip.show();
功能:初始化灯带
参数:无
注意:每次设置完灯带之后,都需要调用此函数进行输出,否则灯带不会变化
(5)控制亮度函数
strip.setBrightness(Bright);
功能:控制亮度
参数:Bright:灯带的亮度(max=255)
(6) 关闭所以灯函数
strip.clear();
功能:将颜色的R、G、B设置为0,关闭所以灯
参数:无
(7)设置颜色函数
strip.Color(R, G, B);
功能:设置灯的颜色(RGB像素)
参数:
①R:红色(max =255)
②G:绿色(max =255)
③B:蓝色(max =255)
(8)点亮一个灯的函数
strip.setPixelColor(location, Colored);
功能:设置某一个灯的颜色
参数:
①location:灯的位置,即第几个灯
② Colored:灯的颜色(32位数据,高8位为红色,中8位为绿色,低8位为蓝色)
(9)点亮连续几个灯的函数
strip.fill(Color, Start, Stop);
功能:设置连续几个灯颜色
参数:
①Color:灯的颜色(32位数据,高8位为红色,中8位为绿色,低8位为蓝色)
②Start:灯的起始位置
③Stop:灯的结束位置
(10)库中包含的其他一些函数(有兴趣可以去详细了解)
strip内的函数
void strip.begin(void);
void strip.show(void);
void strip.setPin(int16_t p);
void strip.setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
void strip.setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w);
void strip.setPixelColor(uint16_t n, uint32_t c);
void strip.fill(uint32_t c = 0, uint16_t first = 0, uint16_t count = 0);
void strip.setBrightness(uint8_t);
void strip.clear(void);
void strip.updateLength(uint16_t n);
void strip.updateType(neoPixelType t);
三、使用Adafruit_NeoPixel.h库控制WS2812
利用库去控制WS2812,以一下是我写的一些控制函数,是对WS2812的一些浅应用(其实还写少了一个设置引脚、灯珠数量、亮度的接口,有时间再补充,或者你们自己补充)。
(1)main.c文件
#include<Arduino.h>
#include"WS2812.h"
void setup() {
WS2812_Init();//初始化
}
void loop() {
//16个灯以紫色闪烁三次,间隔为1S
for(uint8_t i = 0; i < 3; i++)
{
//---起始灯珠---结束灯珠---灯珠颜色--------//
WS2812_ColoredLight(0, 16 ,WS2812_C_PURPIE);//点亮16个灯
delay(1000);//延时1S
//--------起始灯珠------结束灯珠-------//
WS2812_StopAppointLight(0, 16);//关闭灯珠
delay(1000);//延时1S
}
//进入彩虹灯效
//---注意:一旦进入此函数,将卡死在循环里面,慎用!!!!---//
//--------起始灯珠------结束灯珠-------//
WS2812_Start_ContinuousColoredLight(0, 16);
}
(2)WS2812.h文件
#ifndef __WS2812_H__
#define __WS2812_H__
//#include <Arduino.h>
//颜色
#define WS2812_C_RED 18 //红色
#define WS2812_C_ORANGE 54 //橙色
#define WS2812_C_YELLOW 90 //黄色
#define WS2812_C_GREEN 126 //绿色
#define WS2812_C_CYAN 162 //青色
#define WS2812_C_BIUE 198 //蓝色
#define WS2812_C_PURPIE 234 //紫色
void WS2812_Init(void);
void WS2812_StopAppointLight(uint8_t Start, uint8_t Stop);
void WS2812_Start_ContinuousColoredLight(uint8_t Start, uint8_t Stop);
void WS2812_ColoredLight(uint8_t Start, uint8_t Stop, uint8_t Color);
void WS2812_OneLight(uint8_t location, uint8_t Colored);
void WS2812_Clear(void);
#endif
(3)WS2812.c文件
#include<Arduino.h>
#include <Adafruit_NeoPixel.h>
#define WS2812_PIN 23 //灯带引脚
#define WS2812_NUM 16 //灯的数量
#define Bright 64 //灯珠亮度
#define Delay_T 10 //延时时间
//使用RGB模式控制ws2812类型灯带
Adafruit_NeoPixel strip(WS2812_NUM, WS2812_PIN, NEO_GRB + NEO_KHZ800);
uint32_t Rainbow(byte WheelPos);
/**
* @brief WS2812的初始化
* @param 无
* @retval 无
**/
void WS2812_Init(void)
{
//Adafruit_NeoPixel strip(LED_NUM, LED_PIN, NEO_GRB + NEO_KHZ800);
strip.begin(); //初始化灯带
strip.setBrightness(Bright);//设置亮度数值S(max=255)
strip.show(); //灯带显示
}
/**
* @brief 点亮第n到m个彩色LED灯(慎用,会进入死循环)
* @param Start,开始的灯珠
* @param Stop,结束的灯珠
* @retval 无
**/
void WS2812_Start_ContinuousColoredLight(uint8_t Start, uint8_t Stop)//
{
uint8_t x=0,y=0;
for (uint8_t j = 0; j < 256; j++)
{
//--------灯珠颜色------起始灯珠-------结束灯珠-------//
strip.fill(Rainbow(j & 255), Start, Stop);//连续点亮多个灯珠
// Serial.println("x=");
// Serial.println(x);
//strip.setPixelColor(1, Rainbow(j & 255));//点亮一个灯珠
strip.show();
// Serial.println("y=");
// Serial.println(y);
//x++;
// y++;
delay(Delay_T);
}
//Serial.println("ok");
}
/**
* @brief 关闭第n到m个彩色LED灯
* @param Start,开始的灯珠
* @param Stop,结束的灯珠
* @retval 无
**/
void WS2812_StopAppointLight(uint8_t Start, uint8_t Stop)
{
strip.fill(strip.Color(0, 0, 0), Start, Stop);//熄灭点亮多个灯珠
strip.show();
delay(Delay_T);
}
/**
* @brief 设置第n到m个LED灯
* @param Start,开始的灯珠
* @param Stop,结束的灯珠
* @param Color, LED的颜色
* @retval 无
**/
void WS2812_ColoredLight(uint8_t Start, uint8_t Stop, uint8_t Color)//
{
//--------灯珠颜色------起始灯珠-------结束灯珠-------//
strip.fill(Rainbow(Color), Start, Stop);
strip.show();
delay(Delay_T);
//Serial.println("ok");
}
/**
* @brief 点亮第n个LED灯,颜色自定
* @param location,第几个灯珠
* @param Colored,色号(0 <= Colored < 256)
* @retval 无
**/
void WS2812_OneLight(uint8_t location, uint8_t Colored)
{
strip.setPixelColor(location, Rainbow(Colored));//点亮一个灯珠
strip.show();
delay(Delay_T);
}
/**
* @brief 关闭所以灯
* @param 无
* @retval 无
**/
void WS2812_Clear(void)
{
strip.clear();
strip.show();
strip.fill(strip.Color(0, 0, 0), 0, WS2812_NUM);//熄灭点亮多个灯珠
// strip.show();
// delay(Delay_T);
}
/**
* @brief 颜色循环函数
* @param WheelPos,颜色
* @retval 无
**/
uint32_t Rainbow(byte WheelPos)
{
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
本人第一次写博客,记录学习到的内容,有问题请指正!!!