impedire input

Buongiorno, vorrei chiedervi come si puo' fare per impedire di leggere un segnale in ingresso.
Ovvero: se ho due pulsanti,esempio, puls1 e puls2, quando premo puls1 vorrei che puls2 non venga letto in nessun modo.

ho fatto questa prova e molte altre per cercare una soluzione ma non c'è verso.....

int button1 = 8;
int button2 = 9;
int state1 = LOW;
int state2 =LOW;
void setup() {
 pinMode ( button1, INPUT);
 pinMode ( button2, INPUT);
Serial.begin (9600);
}

void loop() {
  Serial.print( state1,DEC);
  Serial.println (state2,DEC);
 state1=digitalRead ( button1);
 state2= digitalRead (button2);
  if ( state2==LOW ){
    if (digitalRead ( button1) == HIGH){
  state2= LOW;
  
    
    if ( digitalRead (button2) ==HIGH){
     
   state2=LOW;
  
    } 
    }
  }
  
 
 
}

anche questo

int button1 = 8;
int button2 = 9;
int state1 = LOW;
int state2 =LOW;
void setup() {
 pinMode ( button1, INPUT);
 pinMode ( button2, INPUT);
Serial.begin (9600);
}

void loop() {
  Serial.print( state1,DEC);
  Serial.println (state2,DEC);
 state1=digitalRead ( button1);
 state2= digitalRead (button2);
  if ( state2==LOW ){
    if (digitalRead ( button1) == HIGH){
  state2= LOW;
  }
    
    if ( digitalRead (button2) ==HIGH){
      if (state2== LOW){
   
    }
      
    }
  }
  
 
 if ( state1==LOW  & digitalRead (button2)== HIGH){
    state1=LOW;
    if ( digitalRead (button1) ==HIGH and state1==LOW){
      state1= LOW;
    }
  }
}

potreste aiutarmi a capire? grazie

Semplice, leggi con la digitalRead il pulsante 1, se è premuto fai ciò che vuoi e li ti fermi, se NON è premuto (else) allora leggi il pulsante 2 e in base al suo stato decidi cosa far fare al programma

int button1 = 8;
int button2 = 9;
int state1 = LOW;
int state2 =LOW;
void setup() {
 pinMode ( button1, INPUT);
 pinMode ( button2, INPUT);
Serial.begin (9600);
}

void loop() {
  Serial.print( state1,DEC);
  Serial.println (state2,DEC);
 state1=digitalRead ( button1);
 state2= digitalRead (button2);
  
   
   if (digitalRead ( button1) == HIGH){
       state1 = HIGH;
    }
     else{
           (digitalRead (button2)== HIGH);
    state2=HIGH;
     }
    
      
  }

ho provato questo, ma non funge, mentre premo button1, premo anche button2 gli stati cambiano.
mentre quello che vorrei è che, se premo e tengo premuto button1, e premo button2 lo stato di button1 non cambi.
In campo elettrico si chiama " interdizione" , ma saprei farlo con dei rele e pulsanti connessi a contatti nc e na.

grazie

Hai già usato state1 e state2 per leggere i pulsanti!

int button1 = 8;
int button2 = 9;
int state1 = LOW;
int state2 =LOW;
void setup() {
 pinMode ( button1, INPUT);
 pinMode ( button2, INPUT);
Serial.begin (9600);
}

void loop() {
  Serial.print( state1,DEC);
  Serial.println (state2,DEC);
// state1=digitalRead ( button1);
// state2= digitalRead (button2);
  
   
   if (digitalRead ( button1) == HIGH){
       state1 = HIGH;
       state2 =LOW;
    }
     else  {state1=LOW;
           if (digitalRead (button2)== HIGH){
    state2=HIGH;
    state1=LOW;
    }
     }
    
      
  }

ok adesso gli stati non dipendono dagli ingressi.
se premo button uno e contemporaneamente il button2, tutto ok
ma se faccio il contrario no.
Sto andando giu di testa.......

grazie

Prova a vedere se così riesci, leggi il valore del pulsante uno e assegni il suo valore alla variabile di stato.
Se questa è HIGH allora l'altro stato lo metti a LOW, ALTRIMENTI (else) leggi il pulsante e assegni il valore alla seconda variabile

Scrivilo sulla carta, prima!

int button1 = 8;
int button2 = 9;
int state1 = LOW;
int state2 =LOW;
void setup() {
 pinMode ( button1, INPUT);
 pinMode ( button2, INPUT);
Serial.begin (9600);
}

void loop() {
  Serial.print( state1,DEC);
  Serial.println (state2,DEC);
// state1=digitalRead ( button1);
// state2= digitalRead (button2);
  
   
   if (digitalRead ( button1) == HIGH){
       state1 = HIGH;
   }
    else{state1 = LOW;}
      
    if (state1 ==HIGH){
        state2=LOW;
    }
    
     
     if (digitalRead (button2)== HIGH){
         state2=HIGH;
    }
     else{state2 = LOW;}
    
    if (state2 ==HIGH){
        state1=LOW;
    }
      
  }

con questo se premo 1 e poi 2 state2 non cambia
ma se premo 2 e poi 1 state 2 va a 0 e state1 a 1

....cosa intendi per scriverlo su carta?
proprio carta e penna? perchè?

grazie

p.s. no scusate il contrario di quanto scritto prima....

Perché non è un problema di programmazione ma di logica su come scrivere il programma, se ti metti li su carta e lo scrivi in italiano e poi usando qualcosa tipo un diagramma di flusso, uno struttogramma o qualsivoglia rappresentazione che trasforma il problema in italiano in un possibile flusso esecutivo poi non ti resta che codificarlo con il linguaggio un uso (C in questo caso).
Se rileggi quello che ti ho scritto in italiano è quello che hai codificato? Risposta no
Prova a rileggere il post #5 e trasformare in codifica quanto descritto in italiano, se non ti trovi su carta fallo direttamente in C ma io darei retta anche a @Datman e mi metterei a ragionare su carta per capire il flusso del programma e come codificarlo

ok provo grazie

int button1 = 8;
int button2 = 9;
int state1 = LOW;
int state2 =LOW;
void setup() {
 pinMode ( button1, INPUT);
 pinMode ( button2, INPUT);
Serial.begin (9600);
}

void loop() {
  Serial.print( state1,DEC);
  Serial.println (state2,DEC);
// state1=digitalRead ( button1);
// state2= digitalRead (button2);
  
   
   if (digitalRead ( button1) == HIGH & state2==LOW){
       state1 = HIGH;
   }
    else {state1=LOW;}
      
    if (state1 ==HIGH){
        state2=LOW;
    }
    else if  (digitalRead (button2)== HIGH)
    {
     state1 =LOW;
     state2=HIGH;
     
     }
     else{state2=LOW;
    }
   
   
      
}

cosi' funziona....ma non so se è quello che mi hai chiesto, fabpolli....

Allora, c’è un errore nell’if

if (digitalRead ( button1) == HIGH & state2==LOW){

la condizione di and va specificata con due e commerciali cioè &&
Poi per andare bene magari va anche bene ma è un po’ prolisso
in pseudo codice potrebbe essere:
variabile1 = leggoPorta(1);
SE variabile1==HIGH E variabile2==LOW ALLORA
//fai qualcosa o forse anche niente (dipende da cosa deve fare il programma) ma non serve assegnare nulla a nessuna variabile
ALTRIMENTI
variabile2 = leggoPorta(2);
SE variabile2==HIGH ALLORA
//fai qualcosa o forse anche niente (dipende da cosa deve fare il programma) ma non serve assegnare nulla a nessuna variabile

Quello sopra è un esempio di cosa è possibile fare su un foglio per studiare una possibile soluzione e relativo flusso del programma
Il tutto a patto di fare un bel debounce hardware altrimenti sperimenterai anomalie di funzionamento causa rimbalzi del pulsante.

int button1 = 8;
int button2 = 9;
int state1 = LOW;
int state2 =LOW;
int sx = LOW;
int dx = LOW;
void setup() {
 pinMode ( button1, INPUT);
 pinMode ( button2, INPUT);
Serial.begin (9600);
}

void loop() {
  Serial.print( state1,DEC);
  Serial.println (state2,DEC);
// state1=digitalRead ( button1);
// state2= digitalRead (button2);
  
   sx = digitalRead(button1);
   dx = digitalRead( button2);
   if (sx == HIGH && state2==LOW){
       state1 = HIGH;
   }
    else {state1=LOW;}
      
    if (state1 ==HIGH){
        state2=LOW;
    }
    else if  (dx== HIGH)
    {
     state1 =LOW;
     state2=HIGH;
     
     }
     else{state2=LOW;
    }
   
   
      
}

ok modifiche apportate.grazie
il fatto è che adesso mi mancano due passaggi.
Primo, il fatto che invece che dalla sola pressione per procedere nel programma, dovrei farli diventare interruttori, sempre tramite i pulsanti.
Secondo, che, se alla pressione dei due pulsanti contemporanei succeda qualcosa d’altro, sempre come se fossero interruttori, ma che impediscano la lettura di quelli singoli.

vista cosi sembra un po incasinata la faccenda…in pratica, sto cercando di costruire delle frecce con i comandi doppi invece che con il comando a blocco, normalmente usato, ovvero come ci sono su alcuni modelli di moto, ma in particolare sulle Harley Davidson.Dove ci sono due pulsanti sul manubrio, a sinistra e a destra, con i quali si comandano le singole frecce, ma che premuti contemporaneamente le accendono insieme, effetto blinker.
Da quello che ho notato, pero’, ogni pressione ne impedisce il contrario, compreso quella contemporanea.

Mamma mia, solo a spiegarlo mi si incasina il cervello.

Il tutto mi piacerebbe farlo con il vostro aiuto, in modo di cercare di capire un po di piu la programmazione di Arduino.

Comunque grazie

Io qui mi fermo perché le modifiche agli impianti automotive sono vietati dalla legge e quindi dal nostro regolamento.
Come avviso ti posso dire che usare Arduino sulla moto è fonte di una marea di problemi derivanti da un sacco di disturbi elettromagnetici, anche se riuscirai a far funzinare tutto “sul banco” messo in opera avrai, quasi certamente, malsunzionameni casuali, operatività incerta, ecc.
Certo che a tutto si può avviare ma servono ottime conoscenze di elettronica

infatti non ho mai detto che lo voglia mettere in opera, so che per legge non si possono fare altrimenti si va incontro al sequestro della moto.....anche perchè mettere mano agli impianti elettrici delle moto, è un casino ne so qualcosa quando alcuni amici mi dicono di avere problemi elettrici con vecchie moto.

Mi sembra però un buon esempio per capire la logica di programmazione.

Se però mi dici di no allora lascio stare.

grazie

Ok, se ti riferisci ad un modello di test che resta sul banco si può proseguire. In realtà non ho capito come deve essere il funzionamento, prova a schematizzarlo in modo più chiaro se puoi perché così giuro che non lo capisco, soprattutto questo:

Da quello che ho notato, pero', ogni pressione ne impedisce il contrario, compreso quella contemporanea.

Per il resto simulare un interruttore con un pulsante si può ma bisogna identificare un qualche "evento" che resetti lo stato, es. premo il pulsante la luce resta accesa finché non lo premo di nuovo

allora usiamo dei nomi cosi è piu semplice;
leftnew=pulsante sinistro
rightnew= pulsante destro
conte= leftnew e rightnew contemporanei
ogni pressione sia singola che contemporanea deve avere la ritenuta, come se fossero interruttori,
...premo e lascio -> fa qualcosa
ripremo e rilascio -> smette di fare

1: premo e lascio leftnew -> funzione che fa accendere i led ws2812 con un gioco finchè
1a: ripremo e rilascio leftnew -> esce dalla funzione

2: e 2a come sopra ma per i led di destra

ma se ho avviato la funzione dei led di sinistra e per caso premo il pulsante di destra, la funzione di di destra non si deve attivare, quindi anche il contrario.

3: premo e lascio contemporaneamente leftnew e rightnew parte la funzione di blinker
3a: ripremo e rilascio contemporaneamente leftnew e rightnew esco dalla funzione blinker

ma se ho attivato la funzione blinker e premo o il sinistro da solo o il destro da solo, non si devono attivare le funzioni singole.

in pratica ogni volta che ho attivato una delle tre funzioni non posso eseguirne un'altra finchè non esco da quella selezionata.

Spero di essere stato un po più chiaro

grazie

Si, solo che contemporaneamente devi definirlo meglio, contemporaneamente non esiste “informaticamente” parlando.
Ovvero secondo me devi ragionare con la logica rilevo che un pulsante è stato premuto, se entro N millisecondi non ho premuto anche l’altro allora faccio qualcosa, altrimenti faccio l’altra cosa. E’ molto difficile che riesci a premere i due pulsanti e nel solito giro di loop rilevi entrambe le pressioni, o meglio non è così sicuro che venga rilevato.
Detto questo ribadisco che devi immediatamente dotare i pulsanti di un hardware di debounce (cerca nel forum e ne trovi mille di discussioni in merito) e poi parti a scrivere un programma che faccia il minimo ovvero:
Rilevo che un pulsante è stato premuto, a quel punto faccio partire il gioco di luci finché non lo ripremo, a quel punto spengo il gioco di luci.
Il tutto senza l’uso dell’istruzione delay.
Aggiungo anche che devi documentarti sull’uso della “macchina a stati finiti” (e anche questa sul forum di discussione ne trovi tante) che è forse il modo più efficente di gestire questo genere di operazioni
Insomma di cose da studiare ne hai un bel po’ :wink:

conosco tutto quello da te descritto, e di prove con switch case e millis per i debouce e millis per i ritardi alla pressione ne ho già provati, solo che non riuscendo a trovare una soluzione volevo ripartire da capo magari con suggerimenti diversi per vedere dove sbagliavo.

tutti e due i pulsanti hanno resistenze di pullup esterne.

#include <Adafruit_NeoPixel.h>

#define PIN 6
#define PIN 7

const int left =2;
const int right= 3;
boolean toggle = false ;
boolean toggle1= false;
boolean toggle2 = false;
bool leftNew ;
bool rightNew;
bool leftLast = 1;    
bool rightLast = 1;
bool left_state ;
bool right_state;
long buttonTimer = 0;
long rightTimer =0;
long leftTimer =0;
long longLeftTime = 500;
long longRightTime = 500;
long longPressTime = 200;
bool longPressActive = false;
bool longLeftActive = false;
bool longRightActive =false;
bool LEDLeftState=false;
bool LEDRightState = false;
bool LED2State= false;
int dt(50);
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(6, 6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(4, 7, NEO_GRB + NEO_KHZ800);

void setup() {
  pinMode ( left, INPUT);
  pinMode (right, INPUT);
  
  strip1.begin();
  strip2.begin();
  strip1.show();
  strip2.show();
  Serial.begin(9600);
}

void loop() {
  //Serial.println(right,DEC);

    leftNew = digitalRead(left);
           delay(dt);
    rightNew = digitalRead(right);
            delay(dt);
/* if (leftNew && rightNew) {
    if (!toggle1 && !toggle && !toggle2) {
      toggle2 = true;
      buttonTimer = millis();
    }
    if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {

      longPressActive = true;
      LED2State = !LED2State;
    }
  } else {
         if (toggle2 == true ) {
            if (longPressActive == true) {
               longPressActive = false;
            } 
         }
          toggle2 = false;
    }*/
  
   // ritardo destro

   if ( toggle1== false && rightNew == true && leftNew == false  ) {
    //if ( !toggle2  && !toggle1) {
      if (toggle == false ){
         toggle = true;
        
         rightTimer = millis();
   }
    //}
     if ((millis() - rightTimer > longRightTime) && (longRightActive == false)) {

      longRightActive = true;
      LEDRightState = !LEDRightState;
    }
  } else {
         if (toggle == true ) {
            if (longRightActive == true) {
               longRightActive = false;
            } 
         toggle = false;
        
         }
    }
  
   // ritardo sinistro
    
 if ( toggle == false && leftNew == true && rightNew == false  ) {
   // if ( !toggle2  && !toggle) {
      if (toggle1 == false ){
         toggle1 = true;
        
         leftTimer = millis();
   }
   // }
     if ((millis() - leftTimer > longLeftTime) && (longLeftActive == false)) {

      longLeftActive = true;
      LEDLeftState = !LEDLeftState;
    }
  } else {
         if (toggle1 == true ) {
            if (longLeftActive == true) {
               longLeftActive = false;
            } 
         toggle1 = false;
        
         }
    }
  
  if (LED2State){    
      Blinker (strip2.Color(255, 40, 0),200);
  }
   else{
        Blinker (strip2.Color(0, 0, 0),0);
       }
 

if (LEDLeftState){    
       ArrowLeft(strip1.Color(255, 40, 0),500,90);  //orange
  }
   else{
         ArrowLeft(strip1.Color(0, 0, 0),0,0);
       }
 
 
  if (LEDRightState){    
      ArrowRight(strip2.Color(255, 40, 0),500,150); //orange
  }
   else{
         ArrowRight(strip2.Color(0, 0, 0),0,0); //orange
       }
} 
  
  
  
  
  void Blinker(uint32_t c, uint8_t wait) {
     
         strip1.fill(c, 0,6);
         strip2.fill(c, 0,4);
         strip1.show();
         strip2.show();
         delay(wait);

         strip1.fill(0, 0,6);
         strip2.fill(0, 0,4);
         strip1.show();
         strip2.show();
         delay(wait);
      
  }

  void ArrowLeft(uint32_t c,uint8_t wait,uint8_t wait1 ) {
       strip1.fill(c, 0,6);
       strip1.show();
       delay(wait);
     
      for (uint16_t i =strip1.numPixels(); i<=6;  i --) {
           strip1.setPixelColor(i, 0);
           strip1.show();
           delay(wait1);
       }
       
  }
  void ArrowRight(uint32_t c,uint8_t wait,uint8_t wait1) {
      strip2.fill(c, 0,4);
      strip2.show();
      delay(wait);
    
    for (uint16_t i = strip2.numPixels(); i<=4; i -- ) {
           strip2.setPixelColor(i, 0);
           strip2.show();
           delay(wait1);
    }
   
}

questa è una delle ultime soluzioni che ho provato, in pratica mettendo un ritardo alla pressione singola.
e un ritardo piu corto alla pressione contemporanea, ma nonostante la negazione degli stati singoli, quando premo il contemporaneo e poi premo uno dei singoli, la funzione del singolo si attiva lo stesso.

dagli un’occhiata

grazie

Non bastano le pullup esterne serve anche il condensatore altrimenti non filtri i rimbalzi alla pressione del pulsante, il codice poi lo guardo, a prima vista si capisce poco