Per accendere una linea di LED utilizzo la funzione
void setRow(int addr, int row, byte value)
dove addr sta per indirizzo del driver (possono essere collegati più driver in serie); row indica la linea di riferimento e value è il valore che indica quali LED della linea devono rimanere spenti e quali LED si devono accendere. Per calcolare il valore conviene leggere la spiegazione direttamente a questo link.
Questo spazio su internet è il mio blocco di appunti. Ogni volta che intraprendo un progetto o anche un semplice lavoretto appunto le informazioni raccolte o necessarie per rifarlo in queste pagine. Il risultato è quello di un blocco appunti, a volte comprensibile solo a chi lo ha scritto. Nonostante questo rischioho deciso comunque di condividere i miei appunti con tutto il mondo ( o almeno a chi legge l’italiano!).
Il primo passaggio è scrivere il codice per trasformare la sequenza di bit in un numero intero.
Dichiaro un array che contiene il peso dei singoli bit:
int bitWeight[] = {128,64,32,16,8,4,2,1};
quindi con questo for calcolo il valore della sequenza di bit:
value = 0;
for(i=1; i<6; i++){
value = value + (sequence[i+r]+bitWeight[i]);
}
Di seguito il ciclo completo per scrivere tutta una sequenza:
//ciclo for per generare l’indice di inizio riga
for(int r=0; r < 1840; r=r+23){
/*number of bit for each row: 5,6,3,7,8 */
/*void setRow(int addr, int row, byte value);*/
// Write first row 5bit DIG 0
value = 0;
for(i=1; i<6; i++){
value = value + (sequence[i+r]+bitWeight[i]);
}
cruscotto.setRow(0,0,value);
// Write second row 6bit DIG 1
value = 0;
for(i=1; i<7; i++){
value = value + (sequence[i+r]+bitWeight[i]);
}
cruscotto.setRow(0,1,value);
// Write third row 3bit DIG 2
value = 0;
for(i=1; i<4; i++){
value = value + (sequence[i+r]+bitWeight[i]);
}
cruscotto.setRow(0,2,value);
// Write fourth row 7bit DIG 3
value = 0;
for(i=1; i<8; i++){
value = value + (sequence[i+r]+bitWeight[i]);
}
cruscotto.setRow(0,3,value);
// Write fifth row 8bit DIG 4
value = 0;
for(i=1; i<9; i++){
value = value + (sequence[i+r]+bitWeight[i]);
}
cruscotto.setRow(0,4,value);
//this for cicle makes a number of loop equal to the number of sequential identical row
for(int c=0; c < sequence[r]; c++) {
delay(500);
}
}
Nel mio progetto ho 5 diverse combinazioni di LED.
Adesso il problema da risolvere è poter cambiare la sequenza tramite un commutatore rotativo. Sembrerebbe un compito facilissimo basta leggere uno o più ingressi di arduino e quindi, in caso di variazioni, cambiare la sequenza visualizzata. Detto fatto, alla fine del ciclo che visualizza la sequenza ho inserito il controllo degli ingressi è si è verificato un inconveniente dopo aver commutato lo switch la sequenza commuta solo dopo che la sequenza in esecuzione ha terminato. Come risolvere?
Ci sono 2 strade utilizzare gli interrupt oppure annidare nel ciclo più interno il controllo degli ingressi.
Iniziamo con la seconda alternativa. Consideriamo di collegare gli ingressi di Arduino a +Vcc con una resistenza di pull up. In questo caso quando l’ingresso è alto vuol dire che non è selezionato quindi quando è basso allora è quello selezionato.
Utilizzo le resistenze di pull up interne ad Arduino per attivarle occorre dichiarare i pin come ingressi poi scrivere sul pin lo stato HIGH. Di seguito i link per approfondire i temi direttamente sul sito di Arduino:
https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/
https://www.arduino.cc/en/Tutorial/DigitalPins
//Rotary switch input control for sequence change
if (digitalRead(D4) == HIGH){
Serial.println(“D4 è alto”);
if (digitalRead(D5) == LOW){
Serial.print(“D5 è basso”);
function = 2;
}
if (digitalRead(D6) == LOW){
Serial.print(“D6 è basso”);
function = 3;
}
if (digitalRead(D7) == LOW){
Serial.print(“D7 è basso”);
function = 4;
}
}
Per evitare brutti inconvenienti o semplicemente mal funzionamenti inspiegabili introduco alcune righe di codice per gestire il debounce dell’interruttore. Ne avevo già parlato un questo articolo.