due output comandati da un pulsante solo

Ciao a tutti , mi sto scervellando da una mezza giornata cercando di fare quadrare il cerchio , ma dopo numeorsi tentativi falliti chiedo aiuto per cercare di sbandolare la matassa.
Dovrei , nelle mie intenzioni , cercare di far andare due uscite digitali alternandole alla pressione di un pulsante in comune.
Dovrebbe funzionare cosi :

inizio ciclo:

  • Premo pulsante -------> si attiva pin 10
  • Rilascio pulsante --------> si disattiva pin 10
  • Premo pulsante ----------> si attiva pin 11
  • Rilascio pulsante---------> si disattiva pin 11
    Fine ciclo torno a inizio ciclo.

Finora ho provato di tutto , ma non avendo dimestichezza con la programmazione ( la mia conoscenza si ferma al plc siemens del '94) e cercando con i manuali e il forum di fare funzionare
il programma , ho scritto , modificato e corretto una ventina di volte lo sketch , arrivando a questo maledetto punto :

#include <Bounce.h>

// This code turns a led on/off through a debounced button
// Build the circuit indicated here: http://arduino.cc/en/Tutorial/Button

#define BUTTON 2              // pulsante di comando
#define RELAISON 10           // prima uscita digitale
#define RELAISOFF 11          // seconda uscita digitale


  Bounce bouncer = Bounce( BUTTON,5 );  // Instantiate a Bounce object with a 5 millisecond debounce time

  void setup() {
    pinMode(BUTTON,INPUT); 
    pinMode(RELAISON,OUTPUT);
    pinMode(RELAISOFF,OUTPUT);
  }

  void loop() {
   bouncer.update ( );  // Update the debouncer
  int pulsante1 = bouncer.read(); // Get the update value
  int memrelaison = 0;           // conteggio delle pressioni del pulsante
    
   while ( pulsante1 == HIGH) {               // se il pulsante è premuto
     memrelaison++ ;                              // aumenta il contatore
    } 
  
   if (( pulsante1 == HIGH) && ( memrelaison == 1)) {                     // se il contatore è a 1 e il pulsante è premuto
    digitalWrite( RELAISON , HIGH );       // attiva la prima uscita 
    digitalWrite( RELAISOFF , LOW );      //  tieni spenta la seconda
     memrelaison++ ;                             // e aumenta il contatore di uno
   }
   else {                                               // se no spegni la prima uscita
    digitalWrite( RELAISON , LOW );
   }
   
   if  (( pulsante1 == HIGH) &&( memrelaison == 2 )) {                   // se il contatore è a 2 e il pulsante è premuto
    digitalWrite( RELAISOFF , HIGH );     // attiva la seconda uscita
    digitalWrite( RELAISON , LOW );       // spegni la prima
   }
   else if( memrelaison == 2) {                                               // se no spegni la seconda uscita
    digitalWrite( RELAISOFF , LOW );      
    memrelaison=0 ;                             // e metti il contatore a 0
  }
 }

se potete consigliarmi dove erro o se lo sketch è completamente sbagliato per quello che voglio ottenere , magari motivando dove sia l’errore mi fareste un
grossissimo piacere :slight_smile:

edit : Modificato per avere il codice in rilievo (scusate ma non avevo visto il tag)

se ho capito bene durante la pressione di un bottone rimane acceso, quindi un debounce è sbagliato questa volta ;)

poi usiamo i tag code così rende tutto più leggibile :P

#define BUTTON 2              // pulsante di comando
#define RELAISON 10           // prima uscita digitale
#define RELAISOFF 11          // seconda uscita digitale

  void setup() {
    pinMode(BUTTON,INPUT); 
    pinMode(RELAISON,OUTPUT);
    pinMode(RELAISOFF,OUTPUT);
  }

  void loop() {
    while(digtalRead(BUTTON) != HIGH);
    digitalWrite(RELAISON, HIGH);
    while(ditigalRead(BUTTON) != LOW);
    digitalWrite(RELAISON, LOW);
    // fine parte sull'uscita 10
    while(digtalRead(BUTTON) != HIGH);
    digitalWrite(RELAISOFF, HIGH);
    while(ditigalRead(BUTTON) != LOW);
    digitalWrite(RELAISOFF, LOW);
 }

il codice inizia ed aspetta che arrivi corrente sul pin (ovvero quando premi il bottone) quindi setta l'uscita come alta, poi aspetta che il bottone sia rilasciato e quando accade porta basso il pin (10). stessa cosa per il pin 11.

come collegamenti un capo del bottone a 5V, l'altro al pin 2 di arduino e metti una resistenza di pull down di 10k ohm tra il pin 2 e massa

Ecco ... cio dimostra che non avevo capito na mazza..... lol Superlol sei un grande... Ho solo messo tra il pin 10 e il pin 11 un delay perche mi dava problemi di sequenza

#define BUTTON 2              // pulsante di comando
#define RELAISON 10           // prima uscita digitale
#define RELAISOFF 11          // seconda uscita digitale

  void setup() {
    pinMode(BUTTON,INPUT); 
    pinMode(RELAISON,OUTPUT);
    pinMode(RELAISOFF,OUTPUT);
  }

  void loop() {
    while(digtalRead(BUTTON) != HIGH);
    digitalWrite(RELAISON, HIGH);
    while(ditigalRead(BUTTON) != LOW);
    digitalWrite(RELAISON, LOW);  // fine parte sull'uscita 10
    delay(50);
    while(digtalRead(BUTTON) != HIGH);
    digitalWrite(RELAISOFF, HIGH);
    while(ditigalRead(BUTTON) != LOW);
    digitalWrite(RELAISOFF, LOW);
 }

Ma il codice cosi in teoria non dovrebbe attivare tutti e due i pin assieme? Perchè aspetta che le condizioni siano vere e poi passa al successivo?

Comunque funziona alla grande :)

no in teoria, fa esattamente quello che dici.

comunque prova a caricarlo su arduino e vedi subito ;)

Caricato e funziona in sequenza come volevo , cioè se premo una volta il pulsante accende la 10 , poi la spegne quando rilascio , se ripremo il pulsante accende la 11 , poi la spegne quando rilascio , se ripremo accende la 10 poi la spegne quando rilascio. Niente da dire , sono un niubbo della domenica. Però continuo a non capire il perchè del funzionamento in sequenza e non , come lo leggo io lo sketch , se premo il pulsante si accendono tutti e due e se rilascio si spengono tutti e due... Va bene che è un loop ma qui si esagera :D

non vi è multitasking, il programma viene svolto esattamente come lo leggi.

ho usato un while(); così ferma il programma fino alla verifica della condizione nella parentesi

quindi se allo sketch aggiungo altre parti , tipo il comando per un lcd o la lettura di alcune sonde di temperatura, non funzionano perchè il comando while mi blocca lo sketch fino a quando non rileva che le condizioni sono quelle dell’istruzione ?

esattamente.

puoi fare il programma in altri modi, ottimi sarebbero gli interrupt

I problemi del Tuo codice:

  void loop() {
   bouncer.update ( );  // Update the debouncer
  int pulsante1 = bouncer.read(); // Get the update value
  int memrelaison = 0;           // conteggio delle pressioni del pulsante

Ogni volta che passa il loop() viene messo memrelaison a zero.

   while ( pulsante1 == HIGH) {               // se il pulsante è premuto
     memrelaison++ ;                              // aumenta il contatore
    }

Viene incrementato finche non molli il pulsante percui avrai numeri tra 100 e 10000

quindi modificando sia la parte iniziale che quella dove incremento dovrebbe andare? maro che casino... direi che ci penso domani.....

In linea di massima sí. Ciao Uwe

Ho modificato tutto di nuovo mantenendo la stessa linea di programmazione ma togliendo il while che sinceramente non posso usare. Questo è quello che al momento mi sembra il piu logico( mamma mia mi sono tirato la zappa sui piedi) :

const int BUTTON = 2;     // the number of the pushbutton pin
const int RELAISON = 10;      // the number of the LED pin
const int RELAISOFF = 11;


 int buttonState = 0;         // variable for reading the pushbutton status
 int memrelaison = 1;

void setup() {
   pinMode(RELAISON, OUTPUT);
   pinMode(RELAISOFF, OUTPUT);
   pinMode(BUTTON, INPUT);     
}

void loop(){
  buttonState = digitalRead(BUTTON);

  
  if ((buttonState == HIGH)&&(memrelaison == 1)) {     
    digitalWrite(RELAISON, HIGH);
    digitalWrite(RELAISOFF, LOW);
    memrelaison = 2 ;
  } 
  else {
    digitalWrite(RELAISON, LOW); 
  }
  
  if ((buttonState == HIGH)&&(memrelaison == 2)) {     
    digitalWrite(RELAISOFF, HIGH);
    digitalWrite(RELAISON, LOW);
    memrelaison = 1 ;
  } 
  else {
    digitalWrite(RELAISON, LOW); 
  }
}

Stasera quando arrivo a casa vedo se funziona o no.....

Chi visse sperando , mori ca..... meglio che non lo scrivo...........

Posso dirti subito: non funziona:

if ((buttonState == HIGH)&&(memrelaison == 1)) {     
    digitalWrite(RELAISON, HIGH);
    digitalWrite(RELAISOFF, LOW);
    memrelaison = 2 ;
  } 
  ...  
  if ((buttonState == HIGH)&&(memrelaison == 2)) {     
    digitalWrite(RELAISOFF, HIGH);
    digitalWrite(RELAISON, LOW);
    memrelaison = 1 ;
  }

Togliendo quello che non serve vedi che se tieni premuto il tasto ti si accende il primo led e poi subito il secondo. e restano accesi tutti due.

Devi farlo con la variabile memrelaison ma con 4 stati. - Premo pulsante -------> si attiva pin 10 ----> memrelaison diventa 2 - Rilascio pulsante --------> si disattiva pin 10 ---->memrelaison diventa 3 - Premo pulsante ----------> si attiva pin 11 ---->memrelaison diventa 4 - Rilascio pulsante---------> si disattiva pin 11 ---->memrelaison diventa 1

Ciao Uwe

hai assolutamente ragione Uwe , in effetti ora che ci ragiono a freddo( un po di aria condizionata non fa male) e senza che qualcuno dei miei colleghi mi rompa i zebedei (termine colorito della mitica bologna) ogni 3 secondi con una domanda durante la pausa pranzo , direi che rifaccio tutto :) maro che caldo mi sciolgoooooooooooooooooooooo

Grazie ancora a tutti , mi sembra di essere tornato a scuola , piu che altro per la pazienza delle risposte , visto che saranno in molti a chiedere , e rispondere sempre le stesse cose dopo un po frantuma.... i zebedei :)

Rifaccio e testo :)

Ecco qua il risultato dire perfetto è troppo ma per me è un buon risultato(anche grazie hai consigli di Superlol e Uwe) :

const int BUTTON = 2;     // Il pin del pulsante
const int RELAISON = 10;      // il pin dell' uscita 1
const int RELAISOFF = 11;    // il pin dell' uscita 2


 int buttonState = 0;         //variabile dello stato del pulsante
 int memrelaison = 1;        //variabile dello stato delle uscite
 
void setup() {
   pinMode(RELAISON, OUTPUT);    // dichiaro che RELAISON  è un uscita
   pinMode(RELAISOFF, OUTPUT);  // dichiaro che RELAISOFF è un uscita
   pinMode(BUTTON, INPUT);         // dichiaro che BUTTON è un ingresso
}

void loop(){
  buttonState = digitalRead(BUTTON);  // leggo lo stato di Button e lo memorizzo

  
  if ((buttonState == HIGH)&&(memrelaison == 1)) {      // se il pulsante è premuto e la variabile delle uscite è 1
    digitalWrite(RELAISON, HIGH);                                 // attiva RELAISON 
    memrelaison = 2 ;                                                    // e passa memrelaison al valore 2
  } 
  delay(18);                                                                 // salta 18 millisecondi di tempo
  
  if ((buttonState == LOW)&&(memrelaison == 2)) {      // se il pulsante è premuto e la variabile delle uscite è 2
   digitalWrite(RELAISON, LOW);                                   // disattiva RELAISON
    memrelaison = 3 ;                                                    // e passa memrelaison al valore 3
  }
   delay(18);                                                                // salta 18 millisecondi di tempo
   
   if ((buttonState == HIGH)&&(memrelaison == 3)) {     // se il pulsante è premuto e la variabile delle uscite è 3
   digitalWrite(RELAISOFF, HIGH);                                 // attiva RELAISOFF
    memrelaison = 4 ;                                                    // e passa memrelaison al valore 4
  }
   delay(18);                                                                // salta 18 millisecondi di tempo
   
   if ((buttonState == LOW)&&(memrelaison == 4)) {      // se il pulsante è premuto e la variabile delle uscite è 4
   digitalWrite(RELAISOFF, LOW);                                  // disattiva RELAISOFF
    memrelaison = 1 ;                                                    // e torna con memrelaison al valore 1
  }
   delay(18);                                                                // salta 18 millisecondi di tempo
}

Ok direi che per il momento puo bastare mi metto a tradurlo in pratica

Grazie di tutto a presto

perché hai messo i "delay(18);" tra i if? Ciao Uwe

per sicurezza , ho visto che premendo in maniera strana il pulsante ( direi asincrona veloce , ma mi sa che scrivo una cazzata) mi dava problemi di accensione della seconoda uscita , cosi ho provato a ritardardare la pressione del pulsante e direi che va benone , almeno non mi ha fatto piu l'accensione ultraveloce e spegnimento ultraveloce della seconda uscita. Poi non so se è legato a quello o a me che ero cotto :)

La cosa che mi é sembrata strana che hai messo i delay fuori dai if.
Ciao Uwe

sinceramente non ho pensato che andasse a creare problemi , mi sembrava la maniera piu logica( e daglie) per separare le varie funzioni if , se le mettevo all'interno della funzione pensavo che potesse legarsi alla funzione stessa , mentre io volevo che prendesse tempo fra una funzione e l'altra.... poi è la stessa cosa direi... mha... :D

Solo che un ritardo Ti serve solo quando cambia lo stato di un pulsante. MEssi cosí tr gli if ralenano solo il programma senza utilitá. Ciao Uwe