Gestione multipulsante

Ciao a tutti.

Ho in mente un progetto, ma non riesco a trovare una soluzione per il software..
All'arduino sono collegati 8 pulsanti normalmente aperti e in uscita svariati led,
ho bisogno che alla pressione del primo pulsante (premo e poi lo lascio subito) si accendano determinati led e restino accesi fino alla pressione di un altro pulsante che, fa spegnere quelli accesi e ne accende altri..
Una sorta di autoritenuta però senza pulsante di spegnimento..

Come posso fare??

Prima di ricevere una risposta, passa alla sezione presentazione e fai una piccola presentazione, dicendo
quali conoscenze hai di elettronica e programmazione.

Poi sono lieto di darti una possibile soluzione, che da quanto ho capito dovrebbe essere abbastanza semplice. Almeno da quello che si può capire da ciò che hai scritto :slight_smile:

Presentati e poi ne parliamo :slight_smile:

**>Lorenzo_Agliodo: **come ti ha giustamente già chiesto torn24, 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

Chiedo scusa per la presentazione, ma ho fatto l'iscrizione e il Topic di fretta e non ho letto,
ho scritto ora la presentazione!

ciao Lorenzo,

quando dai il comando: digitalWrite(pin, statopin) questo lo mantiene tale fino al comando opposto; quindi a te basta usare una serie di if:

if(un pulsante è premuto){
faccio qualche cosa tra cui tutti i digitalWrite(pin, statopin);
}
if(altro pulsante premuto){
faccio altro
}

Ciao, io farei una cosa del genere.

  1. Alla pressione di ogni pulsante vado a spegnere tutti i led tramite un ciclo for()
  2. Per ogni pulsante premuto accendo tramite una serie di digitalWrite(), tutti i led che voglio accendere.

Per spegnere i led tramite ciclo for(), questi devono o usare pin in sucessione, esempio 1-2-3-4, o usare un array dove inserire i pin dei led, in questo caso, se si usa un array, i pin possono essere anche in ordine sparso, ad esempio 1-2-9-11.

Visto che immagino tu stia utilizzando un arduino Mega, visto il numero di pin elevato. Ti propongo un esempio che usa un array.

byte led[10]={1,2,3,4,5,10,23,34,36,40}; //Dieci pin scelti casualmente
void setup(){

}

void loop{

    /*per ogni pulsante scrivo una riga come questa*/
    if(digitalRead(pulsanteUno)==HIGH){


        SpegnimentoLed();//Spengo tutti i led

        /*Accendo i led che voglio*/
        digitalWrite(1,HIGH);
        digitalWrite(2,HIGH);
    
    }else if(digitalRead(pulsanteDue)==HIGH){


        SpegnimentoLed();//Spengo tutti i led

        /*Accendo i led che voglio*/
        digitalWrite(1,HIGH);
        digitalWrite(2,HIGH);
    
    }


}


void SpegnimentoLed(){

    int i=0;
    for(i=0;i<10;i++){// conto da 0 a 9, al posto di 10 mettere il numero giusto di led


        digitalWrite(led[i],LOW);
    }



}

Si potrebbe anche fare una cosa tipo
1)sento un tasto premuto, e me lo ricordo
2) spengo i led
3) una switch case sul valore di tasto mi dice quale di una serie di array leggere, ciascuno contiene i pin dei led che il tasto deve accendere
4) leggo l'array (nella case) con un for sufficiente (tipo limite 50). Se l'elemento che leggo non é 000 (fine array) allora la digitalWrite accende quel pin. In caso contrario il valore del for diventa il limite, e quindi esce
5) il ricordo torna a 0

@torn24
non usare il Pin 1 per i LED. Questo pin serve per il collegamento al PC attraverso l' adattatore USB. Se colleghi qualcosa ai pin 0 e 1 puó non funzionare piú la seriale e l'upload.

  1. mettere la tabella quale LED accendere per quale pulsante in un array bidimensionale. Tipo ledstato [ 0 ][ 0 ] = 1; oppure =0; (pulsante 0, led 0: acceso o spento). Per caricarlo veloce vedi http://www.w3ii.com/it/arduino/arduino_multi_dimensional_arrays.html
byte ledstato[8][10] = { 
  {1,1,1,1,1,0,0,0,0,0},    // stato dei led correspondenti al primo pulsante 
  {0,0,0,0,0,1,1,1,1,1},
 .... 
};
byte pinpulsante[8] = {2,3,4,5,6,7,8,9,10}  // 8 pin dei pulsanti
byte pinled[10] = {30,31,32,33,34,35,36,37,38,39}  // 10 pin dei LED su un Arduino MEGA2560

Stessa cosa per i pin dei pulsanti e i pin dei led con un array monodimensionale.
2) poi fai un for per leggere i pulsanti uno dopo l' altro e secondo for per leggere lo stato di ogni led corrispondente al pulsante. Scrivi il contenuto del elemento sul pin del LED.

for (int i  = 0;i<8;i++)  //legge un pulsante dopo l' altro. premuto = HIGH
  {
  if (digitalread (pinpulsante[i] == 1) // se premuto accendi/spegni i LED
    {
    for(int j=0; j<10;j++)
    {
    digitalWrite(pinled[j], ledstato[i][j]);  // accendi/spegni i led in funzione del pulsante e del led
    }
  }
}

In questo modo i LED vengono accesi o spenti automaticamente.

Ciao Uwe

Grazie a tutti per le risposte!
Nel caso invece io volessi alla pressione di un pulsante non una luce fissa ma un gioco di luci (ad es. strobo)?

Non so esattamente cosa intendi, ma mi viene in mente un po le luci dell'albero di natale che premendo un pulsante cambia effetto.

Comunque secondo me l'approccio sarebbe diverso, io farei qualcosa del genere...

Leggo la pressione dei pulsanti nel loop(), per ogni pulsante premuto richiamo una specifica funzione che mi crea l'effetto luminoso.

In ogni funzione per gli effetti luminosi, metto anche li il codice per la lettura dei pulsanti.
Ad esempio in una funzione che mi genera l'effetto luminoso, ho un ciclo for() o while() per ripetere la sequenza di istruzioni, all'interno dei cicli leggero anche se viene premuto qualche pulsane, in questo caso
richiamo la nuova funzione per il nuovo effetto luminoso, e esco dal ciclo con break.
Comunque diviene una cosa più complessa a seconda dell'effetto che si vuole ottenere... :slight_smile:

È piú semplice creare le varie funzioni con gli effetti usando per le temporizzazioni millis() e non delay().
Poi una variabile di stato dove ogni pulsante corrisponde a un valore.
Con un switch case nell loop salti alla funzione giusta.
vedi "finite state machine" Automa a stati finiti - Wikipedia

ciao Uwe

Ho sentito parlare di una funzione che comprende la lettura di tutti i pulsanti come un unico numero binario, possibile?

Lorenzo_Agliodo:
Ho sentito parlare di una funzione che comprende la lettura di tutti i pulsanti come un unico numero binario, possibile?

Non è una "funzione" ... è che se fisicamente tutti i pin sono collegati alla stessa PORTA della MCU allora con un comando di lettura dello specifico port hai un byte in cui, ogni bit, rappresenta uno specifico pin del PORTA.

Quindi ... devi conoscere le PORTE del ATmega328P, devi sapere a quali pin di Arduno corrispondono e devi collegare i bottoni su quei specifici pin.

Il datasheet del ATmega328P può aiutarti a capire ... ::slight_smile:

O anche quest'immagine:


PB, PC e PD sono le possibili PORTE, mentre, ad esempio, PB0, PB1, ... PB7 i singoli pin della porta PB :slight_smile:

Guglielmo

... nello specifico puoi inoltre leggere QUI :slight_smile:

Guglielmo