注意别把灯带接反了,哪边是输入确认一下!!
刚开始想到的是用STM32中的DMA传输来实现,但是ESP8266 NONOS_SDK中似乎没有这种功能。
可以基于NODEMCU开发,类似NODE.JS的语法来写,懒得学,又要在Linux环境下编译固件(也可以在NODEMCU官网上自己选择需要的功能,编译好了通过邮件发送给你)就放弃了,以后再尝试。
最终还是用安信可的SDK来做。
项目开发期间使用nodemcu的开发板,接线、下载的时候方便多了。
尝试了下面三种方法。
①试过直接用操作IO电平的函数是不行的,频率太低,不知道是什么原因。
②还可以用串口的方法输出数据,只需将串口配置成6位数据位,无奇偶校验,1位停止位(低电平),起始位必须有1位(低电平),这样就可以使每一帧数据都是8位数据(方便计算所需的波特率),再配置电平翻转(这样两边都是高电平),通过控制6位数据位,控制这一帧数据的高电平时间,从而使WS2812区分出0或1(即串口输出的一帧数据对应WS2812接收到的0或者1)。这个方法比较麻烦,但它不是阻塞式的,将数据存储在串口发送缓冲区即可,后面的电平输出由串口发送中断自动完成。具体参考
③基于NONOS_SDK_2.2.0 ,就是安信可官方的那一套,直接用WRITE_PERI_REG函数来将数据输出,该函数在eagle_soc.c 。
贴代码:
Adafruit_NeoPixel.c
#include "Adafruit_NeoPixel.h"
#include "ets_sys.h"
#include "osapi.h"
/*
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
gpio_output_set(bit_value<>= 1;
}
ets_intr_unlock();
}
//GRB format,MSB firsr.
void //ICACHE_FLASH_ATTR
WS2812BSend_24bit(uint8_t R, uint8_t G, uint8_t B) {
WS2812Send_8bit(G);
WS2812Send_8bit(R);
WS2812Send_8bit(B);
}
//delay for millisecond
void HAL_Delay(int time) {
os_delay_us(time * 1000);
}
static uint8_t rBuffer[PIXEL_MAX] = { 0 };
static uint8_t gBuffer[PIXEL_MAX] = { 0 };
static uint8_t bBuffer[PIXEL_MAX] = { 0 };
void setOneColor(uint16_t n, uint32_t c) {
rBuffer[n] = (uint8_t) (c >> 16);
gBuffer[n] = (uint8_t) (c >> 8);
bBuffer[n] = (uint8_t) c;
}
void setAllColor(uint32_t c) {
uint8_t r, g, b;
r = (uint8_t) (c >> 16);
g = (uint8_t) (c >> 8);
b = (uint8_t) c;
uint8_t i;
for (i = 0; i < PIXEL_MAX; i++) {
rBuffer[i] = r;
gBuffer[i] = g;
bBuffer[i] = b;
}
}
void cleanOneColor(uint16_t n, uint32_t c) {
rBuffer[n] = 0;
gBuffer[n] = 0;
bBuffer[n] = 0;
}
void cleanAllColor() {
uint8_t i;
for (i = 0; i < PIXEL_MAX; i++) {
rBuffer[i] = 0;
gBuffer[i] = 0;
bBuffer[i] = 0;
}
}
void setAllPixel(void) {
uint8_t i;
for (i = 0; i < PIXEL_MAX; i++) {
WS2812BSend_24bit(rBuffer[i], gBuffer[i], bBuffer[i]);
}
}
uint32_t Color(uint8_t r, uint8_t g, uint8_t b) {
return ((uint32_t) r << 16) | ((uint32_t) g << 8) | b;
}
uint32_t Wheel(uint8_t WheelPos) {
WheelPos = 255 - WheelPos;
if (WheelPos < 85) {
return Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if (WheelPos < 170) {
WheelPos -= 85;
return Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for (j = 0; j < 256; j++) {
for (i = 0; i < PIXEL_MAX; i++) {
setOneColor(i, Wheel((i + j) & 255));
}
HAL_Delay(wait);
}
setAllPixel();
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
for (i = 0; i < PIXEL_MAX; i++) {
setOneColor(i, Wheel(((i * 256 / PIXEL_MAX) + j) & 255));
}
HAL_Delay(wait);
}
setAllPixel();
}
//Theatre-style crawling lights.o??¨¹¦Ì?
void theaterChase(uint32_t c, uint8_t wait) {
int i, j, q;
for (j = 0; j < 10; j++) { //do 10 cycles of chasing
for (q = 0; q < 3; q++) {
for (i = 0; i < PIXEL_MAX; i = i + 1) //turn every one pixel on
{
setOneColor(i + q, c);
}
HAL_Delay(wait);
for (i = 0; i < PIXEL_MAX; i = i + 1) //turn every one pixel off
{
setOneColor(i + q, 0);
}
}
}
setAllPixel();
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
int i, j, q;
for (j = 0; j < 256; j++) { // cycle all 256 colors in the wheel
for (q = 0; q < 3; q++) {
for (i = 0; i < PIXEL_MAX; i = i + 1) //turn every one pixel on
{
setOneColor(i + q, Wheel((i + j) % 255));
}
HAL_Delay(wait);
for (i = 0; i < PIXEL_MAX; i = i + 1) //turn every one pixel off
{
setOneColor(i + q, 0);
}
}
}
setAllPixel();
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
uint16_t i = 0;
for (i = 0; i < PIXEL_MAX; i++) {
setOneColor(i, c);
HAL_Delay(wait);
}
}
void //ICACHE_FLASH_ATTR
WS2812B_Init(void) {
setAllColor(0);
setAllPixel();
}
void WS2812B_Test(void) {
//HAL_Delay(500);
// rainbowCycle(20);
// theaterChaseRainbow(50);
}
Adafruit_NeoPixel.h
#ifndef _Adafruit_NeoPixel_H
#define _Adafruit_NeoPixel_H
#include "c_types.h"
#include "user_interface.h"
#include "ets_sys.h"
#include "gpio.h"
//thanks for https://github.com/cnlohr/ws2812esp8266
//thanks for https://github.com/adafruit/Adafruit_NeoPixel
#define WSGPIO 0 //must use the ESP8266 GPIO0 as the pin to drive WS2812B RGB LED!!!
//user can change
#define PIXEL_MAX 12//the total numbers of LEDs you are used in your project
//You will have to os_intr_lock(); os_intr_unlock();
//void setAllColor(uint8_t r, uint8_t g, uint8_t b);
void setOneColor(uint16_t n, uint32_t c);
void setAllColor(uint32_t c);
void cleanOneColor(uint16_t n, uint32_t c);
void cleanAllColor(void);
void setAllPixel(void);
uint32_t Color(uint8_t r, uint8_t g, uint8_t b);
uint32_t Wheel(uint8_t WheelPos);
void rainbowCycle(uint8_t wait) ;
void theaterChase(uint32_t c, uint8_t wait);
void theaterChaseRainbow(uint8_t wait);
void colorWipe(uint32_t c, uint8_t wait);
void WS2812B_Test(void);
void ICACHE_FLASH_ATTR WS2812B_Init(void);
uint32_t changeL(uint32_t rgb, float k);
#endif
改变亮度的话看网上别人说的:RGB转HSV后,将V值乘以系数[0,1] ,再HSV转RGB。
发现好像直接将RGB值都乘以系数,结果是一样的。。。
uint32_t changeL(uint32_t rgb, float k) {
uint8_t r, g, b;
float h, s, v;
uint8_t cmax, cmin, cdes;
r = (uint8_t) (rgb >> 16);
g = (uint8_t) (rgb >> 8);
b = (uint8_t) (rgb);
os_printf("1: 0x%x \r\n", rgb);
os_printf("1: %d %d %d \r\n", r, g, b);
cmax = r > g ? r : g;
if (b > cmax)
cmax = b;
cmin = r < g ? r : g;
if (b < cmin)
cmin = b;
cdes = cmax - cmin;
v = cmax / 255.0f;
s = cmax == 0 ? 0 : cdes / (float) cmax;
h = 0;
if (cmax == r && g >= b)
h = ((g - b) * 60.0f / cdes) + 0;
else if (cmax == r && g < b)
h = ((g - b) * 60.0f / cdes) + 360;
else if (cmax == g)
h = ((b - r) * 60.0f / cdes) + 120;
else
h = ((r - g) * 60.0f / cdes) + 240;
//////
v *= k;
float f, p, q, t;
float rf, gf, bf;
int i = ((int) (h / 60) % 6);
f = (h / 60) - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i) {
case 0:
rf = v;
gf = t;
bf = p;
break;
case 1:
rf = q;
gf = v;
bf = p;
break;
case 2:
rf = p;
gf = v;
bf = t;
break;
case 3:
rf = p;
gf = q;
bf = v;
break;
case 4:
rf = t;
gf = p;
bf = v;
break;
case 5:
rf = v;
gf = p;
bf = q;
break;
default:
break;
}
r = (uint8_t) (rf * 255.0);
g = (uint8_t) (gf * 255.0);
b = (uint8_t) (bf * 255.0);
uint32_t returnColor = ((uint32_t) r << 16) | ((uint32_t) g << 8) | b;
os_printf("2: %d %d %d \r\n", (int) r, (int) g, (int) b);
os_printf("2: 0x%x \r\n\r\n", returnColor);
return returnColor;
}