Go Down

Topic: LED SEQUENZA NEOPIXEL (Read 458 times) previous topic - next topic

thewolf87

Nov 08, 2019, 05:52 pm Last Edit: Nov 12, 2019, 10:14 pm by thewolf87
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

https://youtu.be/osoX0aNEUkk


Code: [Select]


#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();
  }
 }


fabpolli

#1
Nov 08, 2019, 06:00 pm Last Edit: Nov 08, 2019, 07:27 pm by gpb01
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. :)

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. ;)

uwefed

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

thewolf87

#3
Nov 09, 2019, 12:04 pm Last Edit: Nov 09, 2019, 12:40 pm by thewolf87
ok

gpb01

#4
Nov 09, 2019, 12:12 pm Last Edit: Nov 09, 2019, 12:13 pm by gpb01
>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. ;)
Search is Your friend ... or I am Your enemy !

thewolf87

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

fabpolli

Ti rispondo per punti:
1) non servono variabili ma cicli, il for potrebbe fare al caso tuo ovvero dentro
Code: [Select]

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

thewolf87

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

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. 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

Federico66

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

Code: [Select]

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


Sbaglio a pensarla così?

Federico
"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

fabpolli

Non sbagli, è che non conoscendo la libreria ( e non avendo nessuna intenzione di conoscerla :) 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.

Federico66

Non sbagli, è che non conoscendo la libreria ( e non avendo nessuna intenzione di conoscerla :) visto che ho acquistato gli APA102...
Io invece ho scoperto gli APA dopo essermi scontrato con i problemi neopixel :( quindi sto cercando (per ora positivamente) di ottimizzare.
Saprò se ci sono riuscito solo quando riuscirò (tempo permettendo) a montare la matrice (17x17)!!!

Federico
"La logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

Federico66

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 logica vi porterà da A a B. L'immaginazione vi porterà dappertutto." A. Einstein

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 è.

gpb01

#14
Nov 12, 2019, 11:47 am Last Edit: Nov 12, 2019, 11:50 am by gpb01
... 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  :D).

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  ;)
Search is Your friend ... or I am Your enemy !

Go Up