LED SEQUENZA NEOPIXEL

buongiorno a tutti

ho creato questo programma, però al momento mi ritrovo 2 problemi:

  1. vorrei snellire il programma inserendo delle variabili per evitare di riscrivere mille volte le stesse righe

  2. è possibile utilizzando il comando a infrarossi, interrompere subito la sequenza in esecuzione invece di aspettare la fine e poi eseguire il comando? perché quando vado a inserire il ciclo lucentezza non riesco a spegnere i led

allego link video per far capire la sequenza corretta che devo realizzare

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
int t = 50;
#define EL 5
#define PIN 6
int c = 0;
int lucentezza = 100; 
int incremento = 10;
int x = 0;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(EL, PIN, NEO_GRB + NEO_KHZ800);
#include <IRremote.h>
int RECV_PIN = 8;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  irrecv.enableIRIn(); // Start the receiver
  Serial.begin(9600);
  pixels.begin();
  pixels.show();
}


void loop() {
 
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
    }
 
 if (results.value == 0xFF30CF) {
  pixels.setPixelColor(0, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(0, 0,0,0);
  pixels.show();
  pixels.setPixelColor(1, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(1, 0,0,0); 
  pixels.setPixelColor(2, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(2, 0,0,0); 
  pixels.setPixelColor(3, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(3, 0,0,0);
  pixels.setPixelColor(4, 0,150,150);
  pixels.show();
  delay(1000); 


  pixels.setPixelColor(0, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(0, 0,0,0);
  pixels.show();
  pixels.setPixelColor(1, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(1, 0,0,0); 
  pixels.setPixelColor(2, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(2, 0,0,0); 
  pixels.setPixelColor(3, 0,150,150);
  pixels.show();
  delay(1000);


  pixels.setPixelColor(0, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(0, 0,0,0);
  pixels.show();
  pixels.setPixelColor(1, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(1, 0,0,0); 
  pixels.setPixelColor(2, 0,150,150);
  pixels.show();
  delay(1000);

  pixels.setPixelColor(0, 0,150,150);
  pixels.show();
  delay(t);
  pixels.setPixelColor(0, 0,0,0);
  pixels.show();
  pixels.setPixelColor(1, 0,150,150);
  pixels.show();
  delay(1000);

  pixels.setPixelColor(0, 0,150,150);
  pixels.show();
    }

 if (results.value == 0xE318261B) {
  pixels.setPixelColor(0, 0,0,0);
  pixels.setPixelColor(1, 0,0,0);
  pixels.setPixelColor(2, 0,0,0);
  pixels.setPixelColor(3, 0,0,0);
  pixels.setPixelColor(4, 0,0,0);
  pixels.show();
   }  


 
if (results.value == 0xFF18E7) {
 
lucentezza = lucentezza + incremento; 
if (lucentezza == 40 || lucentezza == 200) 
 {
 incremento = incremento *-1; 
 }
  pixels.setBrightness(lucentezza); 
 pixels.show();
delay (100);
irrecv.resume();
  }
 }

Buona sera,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del nostro regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie. :slight_smile:

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

Molto semplice. Spegni tutti i LED e solo dopo accendi tutte quelle che devono essere accese.
Visto che scrivi solo nel buffer e trasmetti i dati ai LED solo a termine di settaggio.
Cosí non perdi tempo nel aggiornare i LED.

Non conoscendo il Tuo sketch non so dire niente a riguardo.

Hai provato con for?

Ciao Uwe

ok

>thewolf87: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non avrai sistemato il codice come richiesto, nessuno ti potrà rispondere, quindi ti consiglio di farlo al più presto. :wink:

chiedo scusa, post sistemato, ho riletto tutto il regolamento, non ci dovrebbero più essere problemi ora

Ti rispondo per punti:

  1. non servono variabili ma cicli, il for potrebbe fare al caso tuo ovvero dentro
if (results.value == 0xFF30CF) {

fai un for che va da zero a quattro e utilizzi la variabile del for al posto del primo parametro della funzione setPixelColor
La stessa cosa la puoi fare dentro l'if che spegne tutta la striscia
2) Qui ci sono due cose da dire, la parte del tuo programma che setta i vari colori se la pensi senza l'uso del delay e del for ma con millis() e una logica differente allora si che puoi interrompere l'animazione quando ricevi un nuovo comando.
Per quanto riguarda invece la parte dove setti la lucentezza il discorso è differente ovvro, la funzione setBrightness setta la lucentezza di tutti i led, e qui non puoi intervenire in alcun modo se non modificando la libreria che gestisce i neopixel.
La cosa non è difficile, è difficilissima, i neopixel hanno bisogno di tempistiche molto precise e strette quindi toccare la libreria presuppone un livello di conoscenza del C e delle logiche di programmazione avanzatissima.
Per permettere al tuo programma di poter gestire istantaneamente la ricezione dei comandi dal telecomando ir secondo me dovresti spostarti sugli APA102 (più volte suggeriti da Guglielmo sul forum) che sono tipo i neopixel ma che ti permettono di comandarli in modo meno "permaloso" dei neopixel e quindi potresti interrompre gli aggiornamenti quando più ti pare e piace.
Chiaramente anche la gestione degli APA102 con la logica che interrompe alla ricezione di un nuovo comando non è un banale cambio di codice ma presupporrà un gran lavoro di programmazione

non ho bisogno di spegnerli tutti.
poniamo una sequenza a 5 led:
accendo il primo, si spegne, si accende il secondo e cosi via, arrivato al cinque questo resta acceso, la sequenza ricomincia etc, se posso ti invio via mail il video di quello che fa.
il programma di per se funziona, solo che ora che sono 5 è gestibile, finito il modello ne avrà 25 diventa molto complicato

per il telecomando si, devo studiarci su, sopratutto per i disturbi

Non ho capito cosa intendi, nell'if che corrisponde al comando 0xE318261B spegni tutti i led (da zero a cinque in questo caso) se diventeranno 25 dovrai comunque spegnerli tutti. Se usi il for come ti ho consgliato che i led siano 5, 25 o 200 poco importa cambierai solo la condizione del for. La domanda è: Che dunni hai sull'iso del for?
Il problema della lucentezza ti resterà in eterno comunque perché quello è un comando secco gestito dalla libreri, quando chiami il metodo show a seguito del setBrightness la libreria setta la luminosità di tutti i led che hai nella strip e li non ci sono workaround possibili, dovrai attendere finché non ha finito l'aggiornamento.
Intanto dti consiglio di rivedere il rpogramma con l'uso del for, poi lo posti se hai problemi e vediamo come aiutarti

fabpolli:
Non ho capito cosa intendi, nell'if che corrisponde al comando 0xE318261B spegni tutti i led (da zero a cinque in questo caso) se diventeranno 25 dovrai comunque spegnerli tutti. Se usi il for come ti ho consgliato che i led siano 5, 25 o 200 poco importa cambierai solo la condizione del for.

In realtà la libreria contiene il metodo Clear, che credo sia comunque più veloce rispetto ad assegnare singolarmente setPixelColor(n, 0,0,0), visto che è definita come

void Adafruit_NeoPixel::clear(void) {
  memset(pixels, 0, numBytes);
}

Sbaglio a pensarla così?

Federico

Non sbagli, è che non conoscendo la libreria ( e non avendo nessuna intenzione di conoscerla :slight_smile: visto che ho acquistato gli APA102 che giacciono tristi nella loro bobina per mancanza di tempo) non sapevo dell'esistenza di quel metodo. Più veloce sarà di certo visto che usa una funzione di base.

fabpolli:
Non sbagli, è che non conoscendo la libreria ( e non avendo nessuna intenzione di conoscerla :slight_smile: visto che ho acquistato gli APA102...

Io invece ho scoperto gli APA dopo essermi scontrato con i problemi neopixel :frowning: quindi sto cercando (per ora positivamente) di ottimizzare.
Saprò se ci sono riuscito solo quando riuscirò (tempo permettendo) a montare la matrice (17x17)!!!

Federico

Come dice @fabpolli, dovresti rivedere tutto il programma (cicli for), aggiungo anche per quanto riguarda l'uso del telecomando, cosi com'è avrai dei problemi. Ti consiglio la lettura di questo articolo.

In merito alla luminosità, dovresti evitare di aggiornare la strip (pixels.show()) ogni volta che la modifichi.
Se, come credo, vuoi modificarla mentre la sequenza è in corso, allora metti in una variabile quella nuova, un'altra quella vecchia. Prima di ricominciare la sequenza, le confronti, e se sono diverse, allora cambi la luminosità (pixels.setBrightness(nuova)).
In questo modo ti risparmi l'aggiornamento di tutti i pixel per la sola luminosità, che non è poco!

Federico

la luminosità la reimposta solo se arriva dal telecomando il giusto comando e visto che usa un solo tasto credo che voglia avere comunque un feedback immeiato della luminosità impostata. Dentro l’if del comando fa incrementi di uno ogni pressione del tasto, quando arriva al massimo inizia a decrementare. Se non aggiorna la luminosità ad ogni comando non “vede” a che punto è.

Federico66:
... quindi sto cercando (per ora positivamente) di ottimizzare.

Ricordati che, con gli APA102, il metodo più veloce per trasmettere dati è usare il bus SPI (se non hai altri device SPI che lo utilizzano ... dato che, ovviamente, gli APA102 NON hanno il pin di SS/CS :smiley:).

Guglielmo

P.S.: io, a suo tempo, per usarli sul bus SPI assieme a veri device SPI, mi ero fatto una schedina con un MC74VHC125 che, appunto, li separava dal bus se non era arrivo il pin SS :wink:

fabpolli:
la luminosità la reimposta solo se arriva dal telecomando il giusto comando e visto che usa un solo tasto credo che voglia avere comunque un feedback immeiato della luminosità impostata. Dentro l'if del comando fa incrementi di uno ogni pressione del tasto, quando arriva al massimo inizia a decrementare. Se non aggiorna la luminosità ad ogni comando non "vede" a che punto è.

Vero, mi sono dimenticato di aggiungere che (visto che deve riscrivere il programma) dovrebbe gestirli (+o-) a STATI, perchè cosi com'è, quando cambia la luminosità, interrompe la sequenza (resta acceso solo l'ultimo), e deve ri-comadare per far ripartire l'intera sequenza con la nuova luminosità, altrimenti cambia la luminosità solo di quello acceso.

Usando una logica a stati, la nuova luminosità è solo un nuovo parametro prima dello show.
Risparmia la sequenza di aggiornamenti per la sola luminosità, ed ha una risposta quasi immediata mentre la sequenza è in corso.

Federico

PS
Sto usando questa logica per il mio WordClock, dove la luminosità la regolo manualmente con uno slider dallo smarphone, o automaticamente con una fotoresistenza e un LDR :wink:

gpb01:
Ricordati che, con gli APA102, il metodo più veloce per trasmettere dati è usare il bus SPI...

... si ma io sto ottimizzando con i neopixel, gli APA li ho nel carrello degli acquisti per un futuro progetto :wink:

Federico

Federico66:
... si ma io sto ottimizzando con i neopixel, gli APA li ho nel carrello degli acquisti per un futuro progetto :wink:

Guglielmo

ho inserito nel post iniziale un video per far capire la sequenza corretta.

il regolare la luminosità, è un passo successivo che viene effettuato solo a sequenza primaria terminata.

La sequenza era chiara, modifica il tuo codice con l'uso del for, se dopo averlo modificato non funziona come vuoi tu o hai problemi postalo che ti aiutiamo.
La luminosità poi la vediamo in un secondo momento (non è che ci sia molto da fare comunque)