sexta-feira, 29 de agosto de 2025

Acionando fita de leds (WS2812) endereçável sem nenhuma biblioteca externa.

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!