Olá amigos! aqui vou demonstrar como acionar a fita de leds WS2812 com o ESP32, embora este exemplo possa também ser utilizado pelo ES8266, e usando o mesmo raciocínio é possível portar este código pra qualquer microcontrolador que consiga rodar numa frequência rápida o suficiente para gerar os sinais.
Como sempre recomendo a ler o datasheet da fita que você quer acionar pois estes tempos dos bits podem variar conforme o modelo de fita utilizado. Claro que você também pode usar uma biblioteca pronta como a "FASTLED" porem o intuito aqui é desmistificar o pensamento de que é difícil controlar os leds.
// CLIENTE: microcontroladores-c
// AUTOR: Aguivone M. Fógia
// HARDWARE: ESP32
// CONFIG = FREQUENCIA CPU ->240MHZ e FREQUENCIA FLASH -> 80MHZ
////////////////////////////////////////////////////
//acionando fita de led WS2812 sem usar nenhuma biblioteca
/////////////////////////////////////////////////////
void setup()
{
pinMode(13, OUTPUT); //pino D13
}
void BIT_0()//bit 0
{ // para outros modelos de fitas consultar datasheet
for(int a=0 ; a<8; a++)//aprox.400ns
{//só repete
REG_WRITE(GPIO_OUT_W1TS_REG, BIT13);
}
for(int a=0; a<16; a++)//aprox.850ns
{
REG_WRITE(GPIO_OUT_W1TC_REG, BIT13);
}
}
void BIT_1()//bit 1
{// para outros modelos de fitas consultar datasheet
for(int a=0 ; a<17; a++)//aprox.800ns
{//só repete
REG_WRITE(GPIO_OUT_W1TS_REG, BIT13);
}
for(int a=0; a<7; a++)//aprox.450ns
{
REG_WRITE(GPIO_OUT_W1TC_REG, BIT13);
}
}
void pacote(char BLUE,char RED,char GREEN)//1 pacote de 24bits
{
uint32_t dados = (GREEN<<16) + (RED<<8) + BLUE;//verificar sequencia
uint32_t aux = 1;
while(aux<0X1000000)
{
if((dados & aux)>1)
{//bit 1
BIT_1();
}
else
{
BIT_0();
}
aux = aux<<1;
}
}
void apagar_fita(long num_leds)
{
long aux = 0;
num_leds = num_leds*24; // 24bits por led
while(aux<num_leds)
{
BIT_0();
aux++;
}
}
void preencher_fita(long num_leds)
{//com as 3 cores é mais rapido assim // cor branca
long aux = 0;
num_leds = num_leds*24; // 24bits por led
while(aux<num_leds)
{
BIT_1();
aux++;
}
}
void preencher_cor(char GREEN,char RED,char BLUE,long num_leds)
{//preenche com a cor desejada
long aux = 0;
num_leds++;
while(aux<num_leds)
{
pacote(GREEN,RED,BLUE);//só repete o pacote
aux++;
}
}
void preencher_cor_tempo(char GREEN,char RED,char BLUE,long num_leds,long milisegundos)
{//preenche com a cor desejada de tempo em tempo
long aux = 1;
while(aux<num_leds)
{
preencher_cor(GREEN,RED,BLUE,aux);//só repete o pacote
aux++;
delay(milisegundos);
}
}
void move_ponto(char GREEN,char RED,char BLUE,long Pos)
{
uint32_t dados = (GREEN<<16) + (RED<<8) + BLUE;//verificar sequencia
apagar_fita(Pos-1);
uint32_t aux = 1;
while(aux<0X1000000)
{
if((dados & aux)>1)
{//bit 1
BIT_1();
}
else
{
BIT_0();
}
aux = aux<<1;
}
}
void loop()
{
apagar_fita(500);//limpa fita toda(ver numero de leds totais)
for(;;)
{
// a barra vai sendo preencida ate um determinado led e depois apaga e começa novamente
preencher_cor_tempo(0,25,0,49,200);
apagar_fita(100);//se quiser apagar toda a fita colocar o numero total de leds
delay(500);
move_ponto(0,25,0,5);
delay(100);
move_ponto(0,25,0,10);
delay(100);
move_ponto(0,25,0,20);
delay(100);
move_ponto(0,25,0,30);
delay(100);
move_ponto(0,25,0,40);
delay(100);
move_ponto(0,25,0,50);
delay(100);
}
}
bom projetos pra vocês!
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!