Controllo di 7 LED con un Potenziometro

Buongiorno a tutti,

tratto automazione industriale da un pò di tempo ma ultimamente ho deciso di dedicarmi alla programmazione su Arduino. Dato che questo è il mio primo sketch completo mi piacerebbe avere dei suggerimenti per migliorare il codice oppure dei consigli su come renderlo più efficiente.

Questo progetto è un'integrazione standart per qualsiasi altro progetto che necessiti di un potenziometro e di una visualizzazione dinamica della potenza applicata da esso, con la differenza che i Led essendo collegati su delle uscite PWM variano la loro intensità.

Il codice è il seguente:

/*  
  Autore: Andrea Verardi,
  Data: 16/08/2017,
  Titolo: Visualizzazione Potenza su 7 LED
  Progetto per Arduino UNO, modificabile per tutti i modelli.
  Descrizione: Codice da integrare per la visualizzazione dinamica
  della potenza applicata da un potenziometro 10kOhm su 6 LED 
  collegati su PWM. LON indica "Out of Range" se il valore è 0 oppure
  "Potenza Massima" se il valore raggiunge il fondoscala. 
*/
const int Pot = A0;   // Ingresso Potenziometro Modificabile
const int L1 = 3;   // Uscite PWM Modificabili in base al Modello
const int L2 = 5;
const int L3 = 6;
const int L4 = 9;
const int L5 = 10;
const int L6 = 11;
const int LON = 12;   
int PageON = 0;     //PageON è il debug in Locale
void setup()
{
  pinMode(Pot, INPUT);    //Setup dei Pin
  pinMode(L1, OUTPUT);
  pinMode(L2, OUTPUT);
  pinMode(L3, OUTPUT);
  pinMode(L4, OUTPUT);
  pinMode(L5, OUTPUT);
  pinMode(L6, OUTPUT);
  pinMode(LON, OUTPUT);
  Serial.begin(9600);   //Setup Monitor
  Serial.println("*Sistema Inizializzato*");    //Messaggio di Monitor ON
  

}

void loop()
{
  int PotValue = map(analogRead(Pot), 0, 1023, 0, 1020);//Mappatura Variabile del Potenziometro per renderla divisibile per 6
  int L1A;      //Stabilisco le Variabili Rimappate in base all' if
  int L2A;
  int L3A;
  int L4A;
  int L5A;
  int L6A;
  if (PotValue <= 0){ //Se il valore non è compreso nella scala da OUT OF RANGE
   PageON = 8;
  }
  if ((PotValue <= 170)&&(PotValue != 0)) { //L1 ON
   L1A = map(PotValue, 0, 170, 0, 255);
   PageON = 1;
   analogWrite(L1, L1A);
   digitalWrite(L2, LOW);
   digitalWrite(L3, LOW);
   digitalWrite(L4, LOW);
   digitalWrite(L5, LOW);
   digitalWrite(L6, LOW);
   digitalWrite(LON, LOW);
  }
  
  if ((PotValue > 170)&&(PotValue <=340)) { //L2 ON
   L2A = map(PotValue, 171, 340, 0, 255);
   PageON = 2;
    analogWrite(L2, L2A);
    digitalWrite(L1, HIGH);
    digitalWrite(L3, LOW);
    digitalWrite(L4, LOW);
    digitalWrite(L5, LOW);
    digitalWrite(L6, LOW);
    digitalWrite(LON, LOW);
}
  if ((PotValue > 340)&&(PotValue <=510)) { //L3 ON
   L3A = map(PotValue, 341, 510, 0, 255);
   PageON = 3;
    analogWrite(L3, L3A);
    digitalWrite(L1, HIGH);
    digitalWrite(L2, HIGH);
    digitalWrite(L4, LOW);
    digitalWrite(L5, LOW);
    digitalWrite(L6, LOW);
    digitalWrite(LON, LOW);
}
  if ((PotValue > 510)&&(PotValue <=680)) { //L4 ON
   L4A = map(PotValue, 511, 680, 0, 255);
   PageON = 4;
    analogWrite(L4, L4A);
    digitalWrite(L1, HIGH);
    digitalWrite(L2, HIGH);
    digitalWrite(L3, HIGH);
    digitalWrite(L5, LOW);
    digitalWrite(L6, LOW);
    digitalWrite(LON, LOW);
}
  if ((PotValue > 681)&&(PotValue <=850)) { //L5 ON 
   L5A = map(PotValue, 681, 850, 0, 255);
   PageON = 5;
    analogWrite(L5, L5A);
    digitalWrite(L1, HIGH);
    digitalWrite(L2, HIGH);
    digitalWrite(L3, HIGH);
    digitalWrite(L4, HIGH);
    digitalWrite(L6, LOW);
    digitalWrite(LON, LOW);
}
  if ((PotValue > 851)&&(PotValue < 1020)) {  //L6 ON
   L6A = map(PotValue, 850, 1020, 0, 255);
   PageON = 6;
    analogWrite(L6, L6A);
    digitalWrite(L1, HIGH);
    digitalWrite(L2, HIGH);
    digitalWrite(L3, HIGH);
    digitalWrite(L4, HIGH);
    digitalWrite(L5, HIGH);
    digitalWrite(LON, LOW);
}
if (PotValue >= 1020){        //Potenza Massima
PageON = 7;
digitalWrite(LON, HIGH);
digitalWrite(L1, HIGH);
digitalWrite(L2, HIGH);
digitalWrite(L3, HIGH);
digitalWrite(L4, HIGH);
digitalWrite(L5, HIGH);
digitalWrite(L6, HIGH);
}
/*  
FUNZIONE DI DEBUG:
Cancellare le seguenti stringe se non utilizzate
e rimpiazzare il } alla fine della stringa riportata 
qua sopra. Il tempo di reazione dei LED è influenzato dallo Switch
per rendere il debug più efficiente.
*/
switch (PageON){        
case 0 :
Serial.println("N/D");
delay(2000);
break;
case 1 :
Serial.print("L1:  ");
Serial.print(L1A, DEC);
Serial.print("  Valore Letto:");
Serial.println(PotValue, DEC);
digitalWrite(LON, LOW);
delay(2000);
break;
case 2 :
Serial.print("L1:  ");
Serial.println("ON  ");
Serial.print("L2:  ");
Serial.print(L2A, DEC);
Serial.print("  Valore Letto:");
Serial.println(PotValue, DEC);
delay(2000);
break;
case 3 :
Serial.print("L1:  ");
Serial.println("ON  ");
Serial.print("L2:  ");
Serial.println("ON  ");
Serial.print("L3:  ");
Serial.print(L3A, DEC);
Serial.print("  Valore Letto:");
Serial.println(PotValue, DEC);
delay(2000);
break;
case 4 :
Serial.print("L1:  ");
Serial.println("ON  ");
Serial.print("L2:  ");
Serial.println("ON  ");
Serial.print("L3:  ");
Serial.println("ON  ");
Serial.print("L4:  ");
Serial.print(L4A, DEC);
Serial.print("  Valore Letto:");
Serial.println(PotValue, DEC);
delay(2000);
break;
case 5 :
Serial.print("L1:  ");
Serial.println("ON  ");
Serial.print("L2:  ");
Serial.println("ON  ");
Serial.print("L3:  ");
Serial.println("ON  ");
Serial.print("L4:  ");
Serial.println("ON  ");
Serial.print("L5:  ");
Serial.print(L5A, DEC);
Serial.print("  Valore Letto:");
Serial.println(PotValue, DEC);
delay(2000);
break;
case 6 :
Serial.print("L1:  ");
Serial.println("ON  ");
Serial.print("L2:  ");
Serial.println("ON  ");
Serial.print("L3:  ");
Serial.println("ON  ");
Serial.print("L4:  ");
Serial.println("ON  ");
Serial.print("L5:  ");
Serial.println("ON  ");
Serial.print("L6:  ");
Serial.print(L6A, DEC);
Serial.print("  Valore Letto:");
Serial.println(PotValue, DEC);
delay(2000);
break;
case 7 :
Serial.println("Potenza Massima");
delay(2000);
break;
case 8 :
digitalWrite(L1, LOW);
digitalWrite(L2, LOW);
digitalWrite(L3, LOW);
digitalWrite(L4, LOW);
digitalWrite(L5, LOW);
digitalWrite(L6, LOW);
digitalWrite(LON, HIGH);
Serial.println("Out of Range");
delay(2000);
break;
 }
}

Credo che tu debba andare a presentarti qui

Ciao,
P.

>VA_Automation: essendo il tuo primo post, nel rispetto del regolamento (… punto 13, primo capoverso), 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.

Guglielmo

P.S.: Qui una serie di link utili, NON necessariamente inerenti alla tua domanda:
- serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections
- pinout delle varie schede by xxxPighi: Pinout
- link generali utili: Link Utili

Beh .. subito una prima ottimizzazione riguarda il risparmio di SRAM (... che su Arduino, con soli 2KB, è sempre poca :smiley:), per cui, tutto ciò che deve contenere valori che NON superano il limite di 255 (es. il numero dei pin ... A0, 3, 5, ...) può essere dichiarato byte invece di int con un rispramio immediato del 50% della memoria usata da quelle costanti/variabili.

Stessa cosa per le variabili locali che hai dichiarato int e che contengono in realtà il valore del PWM (0..255) ... :wink:

Altre cose particolari, al momento, non mi saltano all'occhio ... :grin:

Guglielmo

Ah ... si, un'altra cosa ...

Se hai delle condizioni che sono comunque mutualmente esclusive (i vari valori di PotValue su cui fai le IF), inutile fare eseguire TUTTE le IF sempre una dopo l'altra, tanto solo UNA sarà vera e le altre false, quindi ... più veloce metterle in una serie di :

if (condizione) {

} else if (condizione) {

} else if (condizione) {
...
...

... in modo che, alla prima condizione verificata NON esegue più tutti gli altri IF successivi :wink:

Guglielmo

A. Utilizzare la funzione F() sulle stringhe di messaggi:
Serial.print(" Valore Letto:"); diventa Serial.print(F(" Valore Letto:"));
In questo modo la stringa rimane in flash e non in SRAM.

B. mi sembrano inutili le variabili tipo int L1A; in quanto ad un valore del potenziometro devi mappare il valore per il pwm di UN singolo led, mi pare inutile memorizzarlo per i 7 led, quando solo UN valore pwm è attivo alla volta.

C. facendo uso di un vettore per i pin collegati ai led
puoi usare cicli for per agire su tutti i led in un colpo

byte pinLed[]={ 0,3,5,6,9,10,11,12 };
...
for(byte i=1;i<=7;i++)
{ pinMode( pinLed[i],OUTPUT);
}

e sfruttando PageOn con un ciclo for lavori su tutti i pin, meglio se in unica funzione:

void DisplayLed(byte pagina,byte valore_pwm)
{ for(byte i=1;i<=7;i++)
  { if(i<pagina)
    { digitalWrite(pinLed[i],HIGH);
    }
    else
    { digitalWrite(pinLed[i],LOW);
    } 
  }
  analogWrite(pinLed[pagina],valore_pwm);
}

che userai varie volte nel codice, esempio:

  if ( PotValue > 340 && PotValue <= 510 )  //L3 ON
  { byte pwm = map(PotValue, 341, 510, 0, 255);
    PageON = 3;
    DisplayLed(PageON,pwm);  
  }