Tastiera a matrice per effetti di luce con Neopixel

Salve a tutti,

è il mio primo post e vi chiedo di perdonarmi per eventuali errori grossolani...

Il mio scopo è di poter far iniziare degli effetti di luce led Neopixel tramite la pressione di un tasto su di una tastiera a matrice e fin qui nessun problema.
Lo scoglio si presenta dovendo far iniziare un effetto durante l'esecuzione di un altro. Cerco di spiegarmi: l'effetto 1 dura 10 sec, se al sesto secondo premo l'effetto 5, l'effetto 1 continua fino al decimo secondo e, solo allora, posso far partire un'altro effetto tramite la pressione di un tasto.

Credo di dover creare una variabile alimentata dal valore del tasto premuto sulla tastiera a matrice che fa partire un effetto, di dover far continuamente verificare quel valore e, se diverso dal valore memorizzato precedentemente, far partire il nuovo effetto.

Grazie a chiunque può instradarmi correttamente!

[code]

#include <Servo.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif
#include <Keypad.h>

const byte ROWS = 4; //quattro righe
const byte COLS = 4; //quattro colonne
byte colPins[4] = {5,4,3,2}; // Pin a cui sono connesse le colonne
byte rowPins[4] = {9,8,7,6}; // Pin a cui sono connesse le righe
char Keys[4][4]= //creo la matrice dei tasti della tastiera.
{
{'1','2','3','A'} ,
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
Keypad keypad = Keypad(makeKeymap(Keys), rowPins, colPins,4,4);
Servo myservo;
int val;    // variable to read the value from the analog pin
int pos = 0;
#define PIN            13
#define NUMPIXELS      10
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);



void setup() {
   pixels.begin();
   pixels.show();
   myservo.attach(10);
   
}

void loop() {
   int key = keypad.getKey(); 
 if (key == '1'){// EFFETTO 1##################################################################
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(0,0,0)); //spenge tutto
    pixels.show(); 
    delay(0);}  
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(150,150,150)); // salita bianca
    pixels.show();
    delay(1000);}
  }  
if (key == '2'){// EFFETTO 2##################################################################
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(0,0,0)); //spenge tutto
    pixels.show();
    delay(0);}  
  for(int i=9;i<NUMPIXELS;i--){  
    pixels.setPixelColor(i, pixels.Color(150,0,0)); // discesa rossa
    pixels.show(); 
    delay(1000);}
  }

if (key == '3'){//EFFETTO 3##################################################################
for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(0,0,0)); //parte tutto SPENTO
    pixels.show();
    delay(0);}
    delay(0);
   for(int i=0;i<NUMPIXELS;i++){
//int   a = 5*i+20;
//int   b = 15*i+20;
//int   c = 20*i+20;
    pixels.setPixelColor(i, pixels.Color(150,150,150)); // salita bianca ALTA 150150150
    pixels.setPixelColor(NUMPIXELS-1-i, pixels.Color(150,150,150)); // salita bianca BASSA
    pixels.show();
    //delay(500);

 if (i == 5){
    delay(0);
    }   
 if (i != 5){
    delay(1000) ; 
     }   

    pixels.setPixelColor(i, pixels.Color(0,0,0)); //spenge tutto
    pixels.setPixelColor(NUMPIXELS-1-i, pixels.Color(0,0,0)); //spenge tutto
    pixels.show(); 
    delay(0);
    }   
  } 
if (key == '4'){//EFFETTO 4##################################################################
for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(150,0,0)); // salita rossa
    pixels.setPixelColor(i+1, pixels.Color(0,150,0)); // salita verde
    pixels.setPixelColor(i+2, pixels.Color(0,0,150)); // salita blu
    pixels.setPixelColor(i+3, pixels.Color(150,0,0)); // salita rossa
    pixels.setPixelColor(i+4, pixels.Color(0,150,0)); // salita verde
    pixels.setPixelColor(i+5, pixels.Color(0,0,150)); // salita blu
    pixels.setPixelColor(i+6, pixels.Color(150,0,0)); // salita rossa
    pixels.setPixelColor(i+7, pixels.Color(0,150,0)); // salita verde
    pixels.setPixelColor(i+8, pixels.Color(0,0,150)); // salita blu
    pixels.setPixelColor(i+9, pixels.Color(150,0,0)); // salita rossa
    
    pixels.setPixelColor(i-1, pixels.Color(0,150,0)); // salita verde
    pixels.setPixelColor(i-2, pixels.Color(0,0,150)); // salita blu
    pixels.setPixelColor(i-3, pixels.Color(150,0,0)); // salita rossa
    pixels.setPixelColor(i-4, pixels.Color(0,150,0)); // salita verde
    pixels.setPixelColor(i-5, pixels.Color(0,0,150)); // salita blu
    pixels.setPixelColor(i-6, pixels.Color(150,0,0)); // salita rossa
    pixels.setPixelColor(i-7, pixels.Color(0,150,0)); // salita verde
    pixels.setPixelColor(i-8, pixels.Color(0,0,150)); // salita blu
    pixels.setPixelColor(i-9, pixels.Color(150,0,0)); // salita rossa
    
    pixels.show(); 
    delay(1000);}
}

if (key == '5'){// EFFETTO 5##################################################################
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(0,0,150)); //parte tutto blu
    pixels.show(); 
    delay(0);}
    delay(0);
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(150,150,150)); // salita bianca
    pixels.show(); 
    delay(200);} 
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(150,0,0)); // salita rossa
    pixels.show(); 
    delay(200);}    
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(0,150,0)); // salita verde
    pixels.show(); 
    delay(200);} 
  for(int i=0;i<NUMPIXELS;i++){
    pixels.setPixelColor(i, pixels.Color(0,0,150)); // salita blu
    pixels.show(); 
    delay(200);} 
}
if (key == 'A'){
  val = map(val, 0, 1023, 0, 180);     
  myservo.write(180);                
  delay(1000);
}
if (key == 'C'){
  val = map(val, 0, 1023, 0, 180);    
  myservo.write(0);                  
  delay(1000);
}
}

[/code]

Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (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:

Guglielmo

2 grossisimi errori: che ti bloccano il programma
for(int i=0;i<NUMPIXELS;i++){
pixels.setPixelColor(i+9, pixels.Color(150,0,0)); // salita rossa
pixels.setPixelColor(i-9, pixels.Color(150,0,0)); // salita rossa
Ciao Uwe

gpb01:
Buongiorno,
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (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:

Guglielmo

Presentazione fatta! :slight_smile: Per il regolamento mi ci vorrà un po' più di tempo....

uwefed:
2 grossisimi errori: che ti bloccano il programma
for(int i=0;i<NUMPIXELS;i++){
pixels.setPixelColor(i+9, pixels.Color(150,0,0)); // salita rossa
pixels.setPixelColor(i-9, pixels.Color(150,0,0)); // salita rossa
Ciao Uwe

Non puoi usare dei indici che vanno fuori dalla grandezza del array creato dalla libreria in funzione del numero di Neopixel che tu indichi.

Ciao Uwe

Ok lo modifico ma funziona... l’unico effetto che blocca tutto è il secondo. Una volta finito non accetta altri comandi dalla tastiera e non so perché.

Quando definisci una variabile, o un array come nel tuo caso, se vai a scrivere dei valori al di fuori dell'area di memoria ad esso riservata (la fai in 18 casi, i primi 9 pixel con la seconda istruzione e gli ultimi 9 pixel con la prima istruzione all'interno del for) stai dicendo alla libreria di scrivere dei valori in aree di memoria riservate ad altre variabili.
il compilatore del C non ti avverte di queste operazioni e i risultati che possono derivare da scrivere in aree di memoria riservate ad altre variabili sono impredicibili.
Comunque quel for non è l'unico a soffrire di difetti di programmazione, ad esempio nell'effetto numero 2 hai definito:

for(int i=9;i<NUMPIXELS;i--){

Essendo NUMPIXEL una define di valore 10 quel for verrà eseguito finché non arriverà ali limine inferiore del tipo int (-32768), dopodichè verrà decrementato ancora e verrà valorizzato a 32767. Nel frattempo però sei andato fuori dall'indice di 32759 byte incasinando un bel po' di memoria, forse la libreria è furba e sotto l'indice 0 non fa nulla e questo potrebbe salvarti ma non è cosa buona programmare facendo affidamento alla robustezza del codice altrui che in futuro potrebbe cambiare e non garantire più questa funzionalità.
problema simile nell'effetto 4.
per verificare ciò che ti stiamo suggerendo prova ad eseguire alternativamente gli effetti 1 e 5, vedrai che non si blocca la lettura della tastiera, questo perché in entrambe i casi resti all'interno dell'area di memoria riservata all'array dei pixel

fabpolli:
Quando definisci una variabile, o un array come nel tuo caso, se vai a scrivere dei valori al di fuori dell'area di memoria ad esso riservata (la fai in 18 casi, i primi 9 pixel con la seconda istruzione e gli ultimi 9 pixel con la prima istruzione all'interno del for) stai dicendo alla libreria di scrivere dei valori in aree di memoria riservate ad altre variabili.
il compilatore del C non ti avverte di queste operazioni e i risultati che possono derivare da scrivere in aree di memoria riservate ad altre variabili sono impredicibili.
Comunque quel for non è l'unico a soffrire di difetti di programmazione, ad esempio nell'effetto numero 2 hai definito:

for(int i=9;i<NUMPIXELS;i--){

Essendo NUMPIXEL una define di valore 10 quel for verrà eseguito finché non arriverà ali limine inferiore del tipo int (-32768), dopodichè verrà decrementato ancora e verrà valorizzato a 32767. Nel frattempo però sei andato fuori dall'indice di 32759 byte incasinando un bel po' di memoria, forse la libreria è furba e sotto l'indice 0 non fa nulla e questo potrebbe salvarti ma non è cosa buona programmare facendo affidamento alla robustezza del codice altrui che in futuro potrebbe cambiare e non garantire più questa funzionalità.
problema simile nell'effetto 4.
per verificare ciò che ti stiamo suggerendo prova ad eseguire alternativamente gli effetti 1 e 5, vedrai che non si blocca la lettura della tastiera, questo perché in entrambe i casi resti all'interno dell'area di memoria riservata all'array dei pixel

Risolto con

for(int i=9;i!=-1;i--);

Ma nessuno mi sa aiutare con il mio quesito originale?

L'errore che commetti è sempre il solito in tutti i punti dove ti è stato segnalato nei post precedenti, il mio e quelli di uwe.
Devi sempre raqgionare con il valore minimo e massimo che usi nel ciclo, se dentro al ciclo aggiungi o sottrai valori (Es. i-9, i+2, ecc.) e questo ti porta ad andare fuori dall'array di pixel definito (Es. se inizializzi i a zero e poi dentro fai i-Qualcosa sicuramente stai sbagliando, così come se i<NUMPIXEL e fai i+Qualcosa) il programma avrà blocchi e comportamenti non predicibili. Per il punto che ti ho segnatato hai corretto correttamente il codice, applica un ragionamento analogo per tutti gli altri punti e posta il codice modificato che lo verifichiamo assieme

Supernuts1:
Risolto con

for(int i=9;i!=-1;i--);

Ma nessuno mi sa aiutare con il mio quesito originale?

Non cambia niente rispetto al uscire dal range del indice del array dei Neopixel.

Ciao Uwe

Con quel codice però non esce dall'array (in quel for usa sono i senza operazioni ulteriori), sono tutti gli altri for che sballano tutto. A meno che l'array dei neopixel parta da uno :o

Il problema non é il for ma che somma o sottrae qualcosa dalla variabile e la usa dopo come indice. Non si vede direttamente perché l'array é nella libreria.

pixels.setPixelColor(i+9, pixels.Color(150,0,0)); // salita rossa
pixels.setPixelColor(i-9, pixels.Color(150,0,0)); // salita rossa

Ciao Uwe

Mi sa che stiamo parlando di due punti differenti del programma, la modifica apportata a cui so facendo riferimento è in questo punto:

for(int i=9;i<NUMPIXELS;i--){ 
    pixels.setPixelColor(i, pixels.Color(150,0,0)); // discesa rossa
    pixels.show();
    delay(1000);}
  }

diventato

for(int i=9;i!=-1;i--){ 
    pixels.setPixelColor(i, pixels.Color(150,0,0)); // discesa rossa
    pixels.show();
    delay(1000);}
  }

Se non erro in questo punto specifico con la modifica apportata (e solo in questo punto) non esce dalla matrice dei pixel, mentre negli altri for con il codice che hai giustamente riportato tu ha ancora gli errori