Usare le funzioni if ed else per accendere dei led con una determinata logica.

Ebbene sono nuovo del forum e ho poca dimestichezza con Arduino UNO ed il suo linguaggio di programmazione ma vorrei passo passo imparare ad usarlo e capire come funzioni.
Vorrei realizzare su tinkercad quanto di seguito:
Tre LED collegati sulla breadboard (con relativa resistenza) ai pin 11, 10, 9.
Tre pulsanti collegati sulla bredboard ai pin 7, 6, 5.
In breve quello che vorrei fare è questo.
Se premo il pulsante n.1(Pin5) vorrei che si accenda solamente il LED n.1. (Pin9);
Se premo il pulsante n.2(Pin6) vorrei che si accendano contemporaneamente il LED1 n.1. (Pin9) e il LED n.2 (Pin10);
Se premo il pulsanten.3(Pin7) vorrei che si accendano contemporaneamente tutti i LED. n.1 (Pin9) n.2 (Pin10) e n.3(Pin.11).
Qualcuno potrebbe aiutarmi a scrivere relativo codice, cosi che osservando lo stesso, possa capire come vadano scritte le istruzioni all’interno delle funzioni if ed else?
In teoria ho capito che se usate insieme if ed else permettono di eseguire il controllo del flusso, ad esempio un altro esercizio che sto cercando di fare è il seguente:
Due LED e un pulsante collegati ad Arduino UNO.
Vorrei che alla pressione del tasto si accenda il led n.1 quando rilascio lo stesso si accenda il LED n.2.
Posso usare le funzioni if ed else insieme per fare questo no?
Qualcuno che mi dia qualche dritta?

Altri esempi pratici da fare con if ed else da cui prendere spunto?

Grazie a tutti in anticipo!!

Quello che chiedi all’inizio è abbastanza semplice, tuttavia passando dalla simulazione al circuito reale (compreso di scketch) si devono fare i conti con i fenomeni reali. Uno di questi fenomeni riguarda il così detto “rimbalzo” di cui sono afflitti i pulsanti reali, in genere tutti componenti elettromeccanici che presentano dei contatti elettrici soffrono di “rimbalzo” o bounces e il relativo metodo antirimbalzo detto debounces.

Senza considerare il rimbalzo, le cose si semplificano.

Intanto inizierei il codice definendo i pin in modo da poterli chiamare e identificare.

// identificatori pulsanti 
#define pinButton1  5
#define pinButton2  6
#define pinButton3  7

// identificatori led
#define led1  9
#define led2  10 
#define led3  11

byte state = 0;

void setup() {
    // pin configurati in input con pull-up interna
    pinMode(pinButton1, INPUT_PULLUP);
    // qui gli altri pinMode

    // pin configurati come output 
    pinMode(led1, OUTPUT);
    // qui gli altri pinMode 
}

void loop() {

    switch (state) {
    case 1:
       digitalWrite(led1, HIGH);
       digitalWrite(led2, LOW);
       digitalWrite(led3, LOW);
       break;
    case 2:
    break;
    case 3:
       digitalWrite(led1, HIGH);
       digitalWrite(led2, HIGH);
       digitalWrite(led3, HIGH);
    break;


    }

}

Il codice non è testato ed è da completare. Mantenendo questa impostazione ci basta fare in modo che quando viene premuto il pulsante 1 si entra nella if(digitalRead(… e si imposta la variabile state a 1.

Spero possa essere un punto di partenza.

Ciao.

Jamming:
...
Vorrei che alla pressione del tasto si accenda il led n.1 quando rilascio lo stesso si accenda il LED n.2.
Posso usare le funzioni if ed else insieme per fare questo no?
...

Prova a fare un semplice schema logico in italiano. Ad esempio:

IF pulsante premuto
 accendo led1
ELSE
 accendo led2

Vedi che probabilmente manca una specifica. Questa

IF pulsante premuto
 accendo led1
 spengo led2
ELSE
 accendo led2

Vedi che probabilmente ne manca un'altra. Questa

IF pulsante premuto
 accendo led1
 spengo led2
ELSE
 accendo led2
 spengo led1

Poi fatti la domanda: quali sono le condizioni iniziali? Supponiamo siano queste

SETUP
 pulsante alzato
 led1 spento
 led2 spento

Il programma completo diventa

SETUP
 pulsante alzato
 led1 spento
 led2 spento
LOOP
IF pulsante premuto
 accendo led1
 spengo led2
ELSE
 accendo led2
 spengo led1

Prova a tradurlo in istruzioni.

Ciao,
P.

Maurotec:
Quello che chiedi all'inizio è abbastanza semplice, tuttavia passando dalla simulazione al circuito reale ....

Grazie per le dritte, ti dico subito che avevo impostato lo sketch in modo diverso tipo:
Avevo settato nella sezione prima di setup sia led che pulsanti con “int” anziché “#define” non so la differenza ma adesso ho settato tutto come da te indicato.
Avevo inoltre fatto qualche errore di scrittura tipo aver messo una lettera maiuscola o minuscola dove non ci stava, qualche punto e virgola mancante ed altri errori simili.
Ti riporto adesso lo sketch, da completare da me realizzato attualmente, mi sfugge come scrivere correttamente il tutto nella sezione loop.
Un’ultima cosa, con la seguente riga di codice cosa si vuole definire, indicare?
byte state = 0;
grazie
Piano piano spero di riuscirci a capire meglio come funziona questa parte riguardante if ed else e tanto altro.

//definizione dei pin (LED)
#define led1 11
#define led2 10
#define led3 9
//definizione dei pin (Pulsanti)
#define pinButton1 7
#define pinButton2 6
#define pinButton3 5

byte state = 0;


void setup()
{
  
  pinMode(pinButton1, INPUT_PULLUP);
  pinMode(pinButton2, INPUT_PULLUP);
  pinMode(pinButton3, INPUT_PULLUP);
  
  //impostazioni dei pin come uscite
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
 
  }

void loop(){
  if digitalRead(pinButton1 == HIGH)
{digitalWrite(led1, HIGH);
}
else
{digitalWrite(led3, HIGH);
}
}

Usa il CODE per racchiudere il codice! :slight_smile:

pgiagno:
Prova a fare un semplice schema logico in italiano. Ad esempio:

IF pulsante premuto

accendo led1
ELSE
accendo led2



P.

Grazie anche a te dell'utile consiglio.
Sicuramente aiuta ragionare in quel modo, un po' come per i diagrammi di flusso, per capire e definire la logica di funzionamento del sistema che si vuole realizzare ma scrivendo in normale linguaggio comprensibile a tutti.
Il fatto è che mi mancano proprio le basi della programmazione e finché non mastico un po' di codice, realizzo esempi, esercizi, vari avrò difficoltà a capire molti passaggi, concetti.
Grazie comunque
Vedrò di esercitarmi il più possibile.
Abbiate pazienza, nel frattempo, sopportatemi e supportatemi!!

Datman:
Usa il CODE per racchiudere il codice! :slight_smile:

Ma in Quick Reply c'è questa funzione?
Dove si trova?

No nel quick edit non c'è devi accedere alla funzione modify presente nell'elenco a discesa del link more in basso a destra del tuo post

Sì, infatti spesso senza preoccuparmene scrivo in Quick Reply, pubblico e poi devo ritornare in Modify per mettere il Code :frowning:

fabpolli:
No nel quick edit non c’è devi accedere alla funzione modify presente nell’elenco a discesa del link more in basso a destra del tuo post

Capito, una voltra entrato in quella modlaità per pubblicare correttamente il codice uso la funzione code? precisamente cliccando sull’icona </>?

Esatto racchiudendovi all'interno tutto il codice

Datman:
Sì, infatti spesso senza preoccuparmene scrivo in Quick Reply, pubblico e poi devo ritornare in Modify per mettere il Code :frowning:

Infatti dopo aver cliccato su post mi sono reso conto che forse il codice andava inserito nel post in altro modo. Adesso vedo di correggere.
Fatto!!
Corretto!!

Selezioni tutto il codice e poi vai sull'icona.

Avevo settato nella sezione prima di setup sia led che pulsanti con "int" anziché "#define" non so la differenza ma adesso ho settato tutto come da te indicato.

Si è ok anche con le variabili, ma poiché il tipi di dato int comporta una occupazione di memoria di 16-bit al suo posto usiamo il tipo byte che occupa solo 8-bit.

Inoltre poiché usiamo le variabili come identificatori che durante il corso del programma non devono mutare il loro valore ci aggiungiamo il qualificatore const

Quindi con le variabili sarebbe:

const byte pinButton1 = 5;
const byte pinButton2 = 6;
const byte pinButton3 = 7;

Un'ultima cosa, con la seguente riga di codice cosa si vuole definire, indicare?
byte state = 0;

Dichiaro che la variabile di nome state è di tipo byte e gli attribuisco un valore iniziale (la inizializzo).

Rileggi il codice che hai postato, dovrebbe apparirti disordinato, c'è una opzione nell'ide di arduino che
formatta il codice in modo ordinato CTRL-T, usalo prima di postare il codice.

if (digitalRead(pinButton1) == HIGH) {
    state = 1;
} else if (digitalRead(pinButton2) == HIGH) {
   state = 2;
else if (digitalRead(pinButton2) == HIGH) {
   state = 3; 
}

Il codice sopra è scritto direttamente sul forum. Si può anche scrivere al posto di "state = n;" le digitalWrite() che ho scritto in ogni switch case.

Ciao.

Aiutandomi con Tinkercad, attraverso l'uso dei blocchi, ecco qui il risultato da me ottenuto:
Tinkercad

Maurotec:
Si è ok anche con le variabili, ma poiché il tipi di dato int comporta una occupazione di memoria di ....

Grazie, inizio a capire qualcosa in più solamente che quello che mi manca è un pò di pratica per capire quando scegliere impostare un tipo di variabile int opure #define ecc....

Qualche link a riguardo dove poter approfondire?

Servirebbe un libro sul C/C++ per comprendere la differenza tra variabile e macro (che sarebbero le #define).
Le macro vengono risolte dal preprocessore C/C++, il quale "si dice" espande le macro, banalmente effettua delle sostituzioni. Una copia del sorgente viene generato e modificato dal preprocessore, poi segue su questo file la vera compilazione da sorgente a binario.

Wikipedia tratta abbastanza bene l'argomento tipo di dati, ma puoi approfondire cercando "C data types" con google.
C data type

In aggiunta ai tipi standard del C, occorre prendere atto che il programma non sarà eseguito sul pc dove le risorse abbondano, ad esempio la RAM su PC è virtualmente infinita. Tutto il contrario su una MCU tipo il Atmega328 dove hai solo 2048 locazioni di memoria e quelle ti devi fare bastare. Se il dato che devo salvare in memoria è possibile rappresentarlo con 8-bit (in decimale da 0÷255) perché usare un tipo di dato che impegna 2 byte?

Quindi userò il tipo di dato appena sufficientemente ampio a contenere il dato che voglio salvare.

Ciao.

Jamming:
con Tinkercad, attraverso l'uso dei blocchi, ecco qui il risultato da me ottenuto: Tinkercad

Serve un account Tinkercad che non tutti hanno.

I blocchi e uno sguardo al codice prodotto in automatico, possono certamente aiutare a capire la sintassi e l'annidamento gerarchico delle istruzioni. Sono comunque troppo macchinosi per qualcosa di appena più che elementare/dimostrativo.

Tra l'altro uno specifico problema può avere diversi tipi di soluzioni, tutte funzionanti, ma basate su strategie/design/idee/astrazioni diverse, che a codice sono facilmente implementabili, mentre a blocchi potrebbe essere impossibile.

Giusto come esempio di quanto possono essere diverse altre soluzioni, il problema in questione, fermo restando il buon esercizio originario sull'uso di if/else, si poteva anche risolvere pensandolo a livello elettrico con due espressioni logiche OR, che riporto come spunto di approfondimento futuro, assieme all' immagine dello schema simulato dal codice:

void loop()
{
    p1 = digitalRead(5);  //  1 quando premuto
    p2 = digitalRead(6);
    p3 = digitalRead(7);
    led1 = p1 || p2 || p3;
    led2 = p2 || p3;
    digitalWrite(9,  led1);  // 1 = acceso
    digitalWrite(10, led2);
    digitalWrite(11, p3);
}

jamming_3led.png

Ah, altra cosa che di solito confonde... HIGH e true sono la stessa cosa di 1, mentre LOW e false sono la stessa cosa di 0. Sarebbero da usare una o l'altra per chiarezza stilistica a seconda di cosa si sta maneggiando (livelli di ingresso/uscita, variabili booleane), ma usare sempre e solo 1 o 0 funziona benissimo lo stesso.

jamming_3led.png