Ciao a tutti, stavo giocando un po' con due strip neopixel ws2812b quando mi sono imbattuto in un errore che non riesco proprio a capire.
Parto dall'inizio:
con un promicro mando informazioni, tramite I2C, ad un nano che pilota due strisce da 10 led ws2812b, le informazioni sono banalmente quale delle due strisce accendere.
Ho provato a scrivere due codici per una coreografia ad onda, il primo impostando accensione e spegnimento dei lei con delay() all'interno di un ciclo for, il secondo memorizzando il tempo e sfruttando la ciclicità del void loop().
La prima versione non è molto performante in quanto non riesce ad avviare "l'onda" simultaneamente al comando del promicro (fin qui tutto ok essendo pieno di delay()), il problema nasce con la seconda versione che è perfetta in termini di latenza ma dopo un pò (qualche minuto) comincia a crashare: invece di un'onda mi ritrovo con uno squallidissimo strobo.
Questo è il codice incriminato, dove la coreografia 1 è la prima versione spiegata mentre la coreografia 2 è quella che mi da problemi.
Sapreste dirmi come mai succede questa cosa? La cosa più simpatica è che nel momento in cui avviene l'errore, switchando la coreografia, l'onda della prima versione funziona normalmente e ri-switchando sulla seconda versione il problema persiste
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define NUM_LED 10
#define STRIPS 2
Adafruit_NeoPixel Neo_0 = Adafruit_NeoPixel(NUM_LED, 6);
Adafruit_NeoPixel Neo_1 = Adafruit_NeoPixel(NUM_LED, 8);
Adafruit_NeoPixel strip[STRIPS];
#define BOTTOM 3
int Stato_Attuale = 0;
int Stato_Old = 0;
unsigned int precedenteMillis = 0;
unsigned int intervallo_min = 5;
bool Stato[STRIPS];
int Coreografia; // tipologia di coreografia
int MaxCoreogra;
int pulsante;
int j[STRIPS];
uint16_t s;
uint16_t q[STRIPS];
uint16_t t[STRIPS];
bool Andata[STRIPS];
unsigned int Tempo[STRIPS];
void setup() {
Wire.begin(5);
Wire.onReceive(Ricevi);
MaxCoreogra = 2;
strip[0] = Neo_0;
strip[1] = Neo_1;
Neo_0.begin();
Neo_1.begin();
Neo_0.show(); // Inizializza a off
Neo_1.show(); // Inizializza a off
for (int i = 0; i<STRIPS; i++) {
Stato[i] = false;
Andata[i] = true;
j[i] = 100;
}
pinMode(BOTTOM, INPUT_PULLUP);
Coreografia = 1;
}
void loop() {
Stato_Attuale = digitalRead(BOTTOM);
if ((millis() - precedenteMillis) > intervallo_min) {
if (Stato_Old != Stato_Attuale) {
precedenteMillis = millis();
if (Stato_Attuale == LOW) {
Coreografia++;
// j = 0; // Decommentare se vi vuole una dimostrazione appena schiacciato il pulsante
if(Coreografia == MaxCoreogra + 1) Coreografia = 1;
}
Stato_Old = Stato_Attuale;
}
}
for (s=0; s<STRIPS; s++) {
if (Stato[s] == true){
Stato[s] = false;
j[s] = 0;
}
if (Coreografia == 1) { // Prima Versione
if (Andata[s]) {
while (j[s]<NUM_LED){
if (Stato[s] == true) {
strip[s].fill(strip[s].Color(0,0,0), 0); // SPEGNI LED
strip[s].show();
break;
}
strip[s].setPixelColor(j[s], 200, 0, 0);
strip[s].setPixelColor(j[s] -1, 0);
strip[s].show();
delay(35);
j[s]++;
if (j[s] == NUM_LED - 1) Andata[s] = false;
}
}
else {
while (j[s]<NUM_LED){
if (Stato[s] == true) {
strip[s].fill(strip[s].Color(0,0,0), 0); // SPEGNI LED
strip[s].show();
break;
}
strip[s].setPixelColor(NUM_LED - j[s], 200, 0, 0);
strip[s].setPixelColor(NUM_LED - j[s] + 1, 0);
strip[s].show();
delay(35);
j[s]++;
if (j[s] == NUM_LED - 1) Andata[s] = true;
}
}
strip[s].fill(strip[s].Color(0,0,0), 0); // SPEGNI LED
strip[s].show();
}
if (Coreografia == 2) { // Seconda Versione
if (j[s] == 0) StopLuce(s);
if (j[s] < NUM_LED) {
if (Andata[s] & (millis() - Tempo[s]) >= 30) {
Tempo[s] = millis();
strip[s].setPixelColor(j[s], 255, 250, 100);
strip[s].setPixelColor(j[s] -1, 0);
strip[s].show();
j[s]++;
}
if (!Andata[s] & (millis() - Tempo[s]) >= 30) {
Tempo[s] = millis();
strip[s].setPixelColor(NUM_LED - j[s], 255, 250, 100);
strip[s].setPixelColor(NUM_LED - j[s] + 1, 0);
strip[s].show();
j[s]++;;
}
if (j[s] == NUM_LED) {
Andata[s] = !Andata[s];
StopLuce(s); // SPEGNI LED
}
}
}
}
}
void Ricevi() {
int n = Wire.read();
Stato[n-1] = true;
}
void StopLuce(int s) {
strip[s].fill(strip[s].Color(0,0,0), 0); // SPEGNI LED
strip[s].show();
}