Mystery mientras maneja un anillo NeoPixel (WS2812) con un GEMMA (ATtiny85)

1

Estoy trabajando con un Adafruit GEMMA y NeoPixel Ring 16 LED (ATtiny85 y 16 WS2812 leds) y tratando de obtener un programa para encender los LED según mi estructura de" patrón "a continuación, que representa R, G, B, R, G, B, R, G, B.

El siguiente código funciona, pero puedes ver que no es el "código correcto" a lo que aspiro es que el bucle while(1) tenga este aspecto:

 while(1)
    {
      k++;
      for (i = 0; i < NUM_LEDS; i++) {
        uint8_t l = (i+k) % (PATTERN_LEN);
        uint8_t idx = l * 3; 
        set_color(buf, i, pattern[idx], pattern[idx+1], pattern[idx+2]);
      }
      if (k == NUM_LEDS * 10) k = 0;
      output_grb(buf, sizeof(buf));
      _delay_ms(90);
    }

Sin embargo, cuando muestro este código, obtengo lo que parece más un azar: obtengo rojo rojo magenta azul verde y cambia ...

Código que realmente hace lo que espero, que es un conjunto de LED rojos que disminuyen en intensidad y que dan vueltas alrededor del que está debajo, que creo que debería estar haciendo exactamente lo mismo que el de arriba.

No sé cómo depurar / diagnosticar el problema, sospecho que está relacionado con el compilador pero no estoy seguro de qué cambiar o cómo realizar la prueba.

La única diferencia entre los dos enfoques está en el while(1) loop

Cualquier puntero es bienvenido.

#define F_CPU   8000000

#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#include <string.h> 

#define NUM_LEDS      16
#define BUF_SIZE      (NUM_LEDS * 3)
#define PATTERN_LEN   8

const uint8_t pattern[PATTERN_LEN * 3] = {
  70, 0, 0 , 
  60, 0, 0 , 
  50, 0, 0, 
  40, 0, 0 , 
  30, 0, 0 , 
  20, 0, 0 , 
  10, 0, 0 , 
  0,  0, 0
}; 

// declaration of our ASM function
extern void output_grb(uint8_t * ptr, uint16_t count);

void set_color(uint8_t * p_buf, uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{
  uint16_t index = 3*led;
  p_buf[index++] = g/2;
  p_buf[index++] = r/2;
  p_buf[index] = b/2;  
}

int main(void)
{
    uint8_t buf[BUF_SIZE];

    // set PORTB0 as output.-   
    DDRB = 0b00000001;   // bit 0 is our output

    // Init to 0, all leds off     
    memset(buf, 0, sizeof(buf));
    output_grb(buf, sizeof(buf));
    uint8_t i,k = 0;

    while(1)
    {
      k++;
      for (i = 0; i < NUM_LEDS; i++) {
        uint8_t l = (i+k) % (PATTERN_LEN);
        uint8_t idx = l * 3; 
        switch (idx) 
        {
          case 0:
            set_color(buf, i, pattern[idx], pattern[idx+1], pattern[idx+2]);
            break;          
          case 3:
            set_color(buf, i, pattern[idx], pattern[idx+1], pattern[idx+2]);
            break;          
          case 6:
            set_color(buf, i, pattern[idx], pattern[idx+1], pattern[idx+2]);
            break;          
          case 9:
            set_color(buf, i, pattern[idx], pattern[idx+1], pattern[idx+2]);
            break;          
          case 12: 
            set_color(buf, i, pattern[idx], pattern[idx+1], pattern[idx+2]);
            break;          
          case 15: 
            set_color(buf, i, pattern[idx], pattern[idx+1], pattern[idx+2]);
            break;          
          case 18: 
            set_color(buf, i, pattern[idx], pattern[idx+1], pattern[idx+2]);
            break;          
          case 21: 
            set_color(buf, i, pattern[idx], pattern[idx+1], pattern[idx+2]);
            break;          
          default:
            set_color(buf, i, 0, 0, 0);
            break;
        }
      }
      if (k == NUM_LEDS * 10) k = 0;
      output_grb(buf, sizeof(buf));
      _delay_ms(90);
    }
}
    
pregunta webclimber

0 respuestas

Lea otras preguntas en las etiquetas