In poche parole ho creato un' interfaccia grafica in html che mi permette di creare una rete di sensori, led, relay, etc. registrando tutti i parametri in un database. Questo database è letto da un server nodejs che comunica con un' altra interfaccia grafica (quella dell'utilizzatore) dalla quale oltre ai vari elementi, come pulsanti virtuali (creati dall'interfaccia admin) per attivare relay, immagini relative alla temperatura di un sensore, e cosi' via, ci sono anche delle palettes di colori con cursore che permettono di cambiare il colore di una o più serie di led. Il server node cattura l'informazione dall'utilizzatore tramite il modulo socket.io e ridistribuisce tramite socket udp l'informazione al raspbberry a cui l'azione è legata. Il raspberry poi a seconda dell'informazione puo' gestire gli apparecchi che sono attaccati a lui o ridistribuire altrove, tipo all'arduino.
L'arduino riceve un ciclo di informazioni in byte che generano l'azione finale, cioé quella di accendere determinati punti led su una o più serie di led
Sull'arduino il counter è quello che gestisce i vari livelli di trattamento dell'informazione
L'informazione è composta cosi'
111111 vuol dire che c'è un inizio, nel codice
if((counter<=5)&&(readch==1)){
counter++;
}
dopo aver verificato che sto per ricevere una seria di informazioni, registro il mio colore, sono tre valori r g b, cioé con counter 6 7 8
else if((counter>5)&&(counter<=8)){
colors[counter-6] = readch; //counter-6 vale la prima volta 0, poi 1 e poi 2
counter++;
}
dopo, quando il counter è compreso tra 8 e un numero di sicurezza per evitare che in caso di errore faccia un loop infinito, ricevo come informazione il numero di strip di leds da trattare
else if((counter>8)&&(counter < len)){
if(counter==9){
num_bandeau = readch; //bandeau è strip in francese, mi sa che cambio nome
}
poi, registro gli indici delle serie da trattare in un array. Ogni indice mi permetterà di chiamare l'array pin che contiene i parametri di ogni strip:
CRGB leds[MAX_LEDS] = l'array di colori di ogni led della serie
uint8_t single = numero di led da trattare singolarmente, quando non è per forza una catena, tipo
la led 1 - 5 - 10 - 12 - ..., è soltanto la quantità di led da trattare singolarmente,
servirà dopo
uint8_t multiple = numero di led da trattare in un ciclo perché si susseguono,
tipo le led da 1 fino a 100, è soltanto la quantità di cicli da trattare
servirà dopo
else if(bandeau_index<num_bandeau){
bandeau_id[bandeau_index] = readch;
bandeau_index++;
}
dopo ricevo un informazione su quante led trattare singolarente, e quante in un valori compresi tra x e y
else if(single_leds_index<num_bandeau){
if(readch!=0){
pin[bandeau_id[single_leds_index]]->single = readch;
single_leds[tot_single] = bandeau_id[single_leds_index];
tot_single++;
}
single_leds_index++;
}else if(multiple_leds_index<num_bandeau){
if(readch!=0){
pin[bandeau_id[multiple_leds_index]]->multiple = readch;
multiple_leds[tot_multiple] = bandeau_id[multiple_leds_index];
tot_multiple++;
}
multiple_leds_index++;
}
Dopo, in base al numero di led da gestire singolarmente, e poi al numero di fourchettes tra due valori
else if(actual_single<tot_single){
if((single_leds[actual_single])&&(pin[single_leds[actual_single]]->single)){
pin[single_leds[actual_single]]->leds[readch] = CRGB( colors[0], colors[1], colors[2]);
temp_single_index++;
if(temp_single_index==pin[single_leds[actual_single]]->single){
pin[single_leds[actual_single]]->single = 0;
actual_single++;
temp_single_index = 0;
}
}
}else if(actual_multiple<tot_multiple){
if((multiple_leds[actual_multiple])&&(pin[multiple_leds[actual_multiple]]->multiple)){
if(start==0){
start=1;
led_start = readch;
}else{
led_end = readch;
if((led_start<led_end)&&(led_start>=0)){
for(i=led_start; i<led_end; i++){
pin[multiple_leds[actual_multiple]]->leds[i] = CRGB( colors[0], colors[1], colors[2]);
}
}
start = 0;
temp_multiple_index++;
if(temp_multiple_index==pin[multiple_leds[actual_multiple]]->multiple){
pin[multiple_leds[actual_multiple]]->multiple = 0;
actual_multiple++;
temp_multiple_index = 0;
}
}
Poi verifico che ci sia una chiusura della totalità dell'informazione con readch che è 6 volte consecutive 0, se i valori combaciano allora accendo le leds con FastLED.show(), nel caso contrario tutti i valori vengono reinizializzati, incluso counter e il ciclo ricomincia
}else{
if(readch==0){
end_string++;
}else{
/*Serial.print("2");
Serial.flush();*/
end_string = 0;
//memset(colors, 0, sizeof colors);
counter = -1;
num_bandeau = 0;
//memset(bandeau_id, 0, sizeof bandeau_id);
bandeau_index = 0;
//memset(single_leds, 0, sizeof single_leds);
single_leds_index = 0;
//memset(multiple_leds, 0, sizeof multiple_leds);
multiple_leds_index = 0;
actual_single = 0;
actual_multiple = 0;
temp_single_index = 0;
tot_single = 0;
temp_multiple_index = 0;
tot_multiple = 0;
start = 0;
led_start = 0;
led_end = 0;
}
if(end_string==6){
end_string = 0;
FastLED.show();
//memset(colors, 0, sizeof colors);
counter = -1;
num_bandeau = 0;
//memset(bandeau_id, 0, sizeof bandeau_id);
bandeau_index = 0;
//memset(single_leds, 0, sizeof single_leds);
single_leds_index = 0;
//memset(multiple_leds, 0, sizeof multiple_leds);
multiple_leds_index = 0;
actual_single = 0;
actual_multiple = 0;
temp_single_index = 0;
tot_single = 0;
temp_multiple_index = 0;
tot_multiple = 0;
start = 0;
led_start = 0;
led_end = 0;
/*Serial.print("1");
Serial.print(freeRam());
Serial.flush();*/
}
}
counter++;
}
Dopodiché c'è la seconda eccezione, cioé il caso in cui counter > len o che la sequenza di inizio era errata
}else{
/*Serial.print("2");
Serial.flush();*/
end_string = 0;
//memset(colors, 0, sizeof colors);
counter = 0;
num_bandeau = 0;
//memset(bandeau_id, 0, sizeof bandeau_id);
bandeau_index = 0;
//memset(single_leds, 0, sizeof single_leds);
single_leds_index = 0;
//memset(multiple_leds, 0, sizeof multiple_leds);
multiple_leds_index = 0;
actual_single = 0;
actual_multiple = 0;
temp_single_index = 0;
tot_single = 0;
temp_multiple_index = 0;
tot_multiple = 0;
start = 0;
led_start = 0;
led_end = 0;
}
}
Per quanto possa sembrare bizzarro, non so se ci sono altre maniere per gestire un'informazione dinamica, e comunque funziona benissimo, ho fatto una funzione che lancia un'informazione ogni 40ms dal server node e non blocca mai, e nel caso di data corrotto ci sono comunque le eccezioni. Il problema sta quando non lo manipolo per un po' di tempo (anche 12 ore tipo), la prima informazione mi corrompe il sistema. Questa stessa informazione dopo n ore viene finalmente analizzata, infatti il colore delle led cambia inaspettatamente, ma solo quell'informazione e non tutte quelle che l'hanno seguita. All'inizio pensavo a un problema di bufferizzazione, ma avrebbe dovuto farmelo quando manipolo il sistema in maniera continua, e comunque il if(Serial.available()) dovrebbe svuotare il buffer