Problemi con la condizione

Salve, ho riscontrato problemi con questa condizione. Sto svolgendo un progetto scolastico riguardo un montacarichi sviluppato su 3 piani e ognuno di essi è formato da 9 led, tra cui uno per piano che serve per spostarsi tra un piano e l'altro. Non so per quale motivo la condizione arrivata alla stampa "si o no" non mi legge più i pulsanti mentre il resto del programma funziona tranquillamente. Mi potreste aiutare?

 if(val>=500 && val<=750 && (i==1 || i==11 || i==21)){
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Uso ascensore?");
      lcd.setCursor(0, 1);
      lcd.print("si o no");
      delay(200);
        if(val>=0 && val<=50){
          i=i;
        }
        if(val>=300 && val<=150){
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("salgo o scendo?");
          delay(200);
          while(val>=0 && val<=50 || val>=300 && val<=500){
            if(val>=0 && val<=50){
              i=i+10;
            }
            if(val>=300 && val<=500){
              i=i-10;
            }
          }
        }
      
  }

Buongiorno e benvenuto nella sezione Italiana del forum,

cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

Dal pezzo di codice che hai messo non si capisce molto, ad esempio manca tutta la lettura dei pulsanti ... metti il codice completo :slight_smile:

Guglielmo

Se

non può poi essere

val>=0 && val<=50

o, tantomeno

val>=300 && val<=150

che non accetta alcun valore di per sé!

Questo è quasi tutto il programma, non ho messo la parte finale che è semplicemente una ripetizione di "i==" che cambia da 1 a 29. Ogni valore di i compreso in quella soglia di valori accenderà un singolo led specifico, questo mi serve per il circuito che ho montato. Riguardo invece i valori che assumono i bottoni, sto usando un display lcd keypad shield che sfrutta un circuito partitivo resistivo per assegnare ad ogni bottone un range di valori.

#include <Wire.h>
int pin1=22;
int pin2=23;
int pin3=24;
int pin4=25;
int pin5=26;
int pin6=27;
int pin7=28;
int pin8=29;
int pin9=30;
int pin11=31;
int pin12=32;
int pin13=33;
int pin14=34;
int pin15=35;
int pin16=36;
int pin17=37;
int pin18=38;
int pin19=39;
int pin21=40;
int pin22=41;
int pin23=42;
int pin24=43;
int pin25=44;
int pin26=45;
int pin27=46;
int pin28=47;
int pin29=48;

int i;

#include<LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {
  lcd.begin(16, 2);
  pinMode(22, OUTPUT);
  pinMode(23, OUTPUT); 
  pinMode(24, OUTPUT);
  pinMode(25, OUTPUT);
  pinMode(26, OUTPUT);
  pinMode(27, OUTPUT); 
  pinMode(28, OUTPUT);
  pinMode(29, OUTPUT);
  pinMode(30, OUTPUT);
  pinMode(31, OUTPUT); 
  pinMode(32, OUTPUT);
  pinMode(33, OUTPUT);
  pinMode(34, OUTPUT);
  pinMode(35, OUTPUT); 
  pinMode(36, OUTPUT);
  pinMode(37, OUTPUT);
  pinMode(38, OUTPUT);
  pinMode(39, OUTPUT); 
  pinMode(40, OUTPUT);
  pinMode(41, OUTPUT);
  pinMode(42, OUTPUT);
  pinMode(43, OUTPUT); 
  pinMode(44, OUTPUT);
  pinMode(45, OUTPUT);
  pinMode(46, OUTPUT);
  pinMode(47, OUTPUT);
  pinMode(48, OUTPUT);

  for (int a = 0; a < 5; a++) {
  lcd.print(".");
  delay(500);
  }

  i=1;

}

void loop() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Comando carico");
  lcd.setCursor(0, 1);
  lcd.print("Posto");
  lcd.setCursor(6, 1);
  lcd.print(i);
  int val = analogRead(A0);

  if(val>=500 && val<=750){
    if(i!=1 && i!=11 && i!=21){
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Rilascio carico");
      lcd.setCursor(0, 1);
       for (int a = 0; a < 5; a++) {
       lcd.print(".");
       delay(500);
       }
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Rilascio carico");
      lcd.setCursor(0, 1);
       for (int a = 0; a < 5; a++) {
       lcd.print(".");
       delay(500);
       }
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Carico lasciato");
      delay(500);
    }
  }

  if(val>=500 && val<=750 && (i==1 || i==11 || i==21)){
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Uso ascensore?");
      lcd.setCursor(0, 1);
      lcd.print("si o no");
      delay(200);
        if(val>=0 && val<=50){
          i=i;
        }
        if(val>=300 && val<=150){
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("salgo o scendo?");
          delay(200);
          while(val>=0 && val<=50 || val>=300 && val<=500){
            if(val>=0 && val<=50){
              i=i+10;
            }
            if(val>=300 && val<=500){
              i=i-10;
            }
          }
        }
      
  }

  
  if(val>=150 && val<=300){
    if(i!=1 && i!=4 && i!=7 && i!=11 && i!=14 && i!=17 && i!=21 && i!=24 && i!=27){
      i=i-1;
         lcd.clear();
         lcd.setCursor(0, 0);
         lcd.print("Sposto carico");
         lcd.setCursor(0, 1);
          for (int a = 0; a < 5; a++) {
          lcd.print(".");
          delay(200);}
    } 
  }

  if(val>=50 && val<=150){
    if(i!=3 && i!=6 && i!=9 && i!=13 && i!=16 && i!=19 && i!=23 && i!=26 && i!=29){
      i=i+1;
         lcd.clear();
         lcd.setCursor(0, 0);
         lcd.print("Sposto carico");
         lcd.setCursor(0, 1);
          for (int a = 0; a < 5; a++) {
          lcd.print(".");
          delay(200);}
    }
  }

  if(val>=0 && val<=50){
    if(i!=7 && i!=8 && i!=9 && i!=17 && i!=18 && i!=19 && i!=27 && i!=28 && i!=29){
      i=i+3;
         lcd.clear();
         lcd.setCursor(0, 0);
         lcd.print("Sposto carico");
         lcd.setCursor(0, 1);
          for (int a = 0; a < 5; a++) {
          lcd.print(".");
          delay(200);}
    }
  }

  if(val>=300 && val<=500){
    if(i!=1 && i!=2 && i!=3 && i!=11 && i!=12 && i!=13 && i!=21 && i!=22 && i!=23){
      i=i-3;
         lcd.clear();
         lcd.setCursor(0, 0);
         lcd.print("Sposto carico");
         lcd.setCursor(0, 1);
          for (int a = 0; a < 5; a++) {
          lcd.print(".");
          delay(200);}
    }
  }

  if(i==1){
  digitalWrite(22, HIGH);
  digitalWrite(23, LOW); 
  digitalWrite(24, LOW);
  digitalWrite(25, LOW);
  digitalWrite(26, LOW);
  digitalWrite(27, LOW); 
  digitalWrite(28, LOW);
  digitalWrite(29, LOW);
  digitalWrite(30, LOW);
  digitalWrite(31, LOW); 
  digitalWrite(32, LOW);
  digitalWrite(33, LOW);
  digitalWrite(34, LOW);
  digitalWrite(35, LOW); 
  digitalWrite(36, LOW);
  digitalWrite(37, LOW);
  digitalWrite(38, LOW);
  digitalWrite(39, LOW); 
  digitalWrite(40, LOW);
  digitalWrite(41, LOW);
  digitalWrite(42, LOW);
  digitalWrite(43, LOW); 
  digitalWrite(44, LOW);
  digitalWrite(45, LOW);
  digitalWrite(46, LOW);
  digitalWrite(47, LOW);
  digitalWrite(48, LOW);
  }

Sto sfruttando quel tipo di condizione perchè sto usando un display lcd keypad shield, che sfrutta quel comando per assegnare un azione in base al pulsante premuto, e ogni pulsante ha un range di valori che viene letto poi dalla scheda.

Cestina quel pessimo programma, non vale nemmeno la pena di leggerlo, figuriamoci capirci i problemi,

riparti semplificando il tuo modus pensandi

ad esempio invece di elencare Hmila pin (stai usando una MEGA?)
usa un array e un ciclo


byte pin[19];
for (int i=0;i<19;i++){
   pin[i]=i+22;
   pinMode(pin[i],OUTPUT);
}

una cosa del genere, vedi tu i dettagli

anche l'inutile spatafiata finale di non so quante volte ripetere sempre gli stessi comandi
usa una funzione

void scarica(byte i){
   for (int i=0;i<19;i++){
      digitalWrite(pin[i],0);
   }
   digitalWrite(pin[i],1);
}

lasciamo a te scoprire per quale trucco funziona (cosi' magari ti rendi conto da te quando un programma e' mal scritto)

inoltre documenta (commenta) meglio le varie fasi del programma, che non si capisce cosa vuoi fare e sotto che condizioni

anche le if con intere "catene" di != sono inguardabili
anche quelle si possono ripensare in termini parametrici

Per quanto riguarda i pin, non so nemmeno quanto serva realmente. Comunque dei #define sarebbero più efficienti.
Per il finale, invece, basterebbe memorizzare la precedente uscita messa a HIGH e poi metterla a LOW:

digitalWrite(pin_prec, LOW);
digitalWrite(pin, HIGH);
pin_prec=pin;
1 Like

Scusa ma questo che significa ?? A che serve ??

Ma non stampa lcd.print("salgo o scendo?"); ??
NO, perchè come ti ha detto @Datman quella condizione è impossibile
if(val>=300 && val<=150){
val NON può essere maggiore di 300 ed ANCHE minore di 150

Quindi... val è il valore del pulsante premuto ? i è la fase in cui si trova il programma ?
Scrivetelo chiaro. Cambiate val con il nome bottone ad esempio o pulsante, più facile da capire.

Soprattutto questo è sbagliato:

Sarebbe anche utile sapere come dovrebbe funzionare.

Senza offesa @robymix però concordo...

Il tuo sketch è veramente "cervellotico", probabilmente ti conviene ripensarlo in modo più organizzato dal punto di vista logico sequenziale.

Ad esempio invece di tutta quella serie di if per determinare il pulsante premuto, potresti fare una funzione che ti ritorna un indice rappresentativo del pulsante premuto e poi con uno switch/case decidere cosa fare (e anche per questo io organizzerei le azioni con delle funzioni).

Anche qui ad esempio:

if(i!=7 && i!=8 && i!=9 && i!=17 && i!=18 && i!=19 && i!=27 && i!=28 && i!=29){

Sicuro che non c'è un modo migliore per determinare cosa fare?
Magari con una macchina a stati finiti viene tutto più semplice da implementare e soprattutto da manutenere/espandere eventualmente nel futuro.

Riguardo la prima domanda, con quella condizione volevo usare un pulsante per rispondere "no" ed andare direttamente alla fine. Riguardo la seconda invece, ho riscritto meglio quella parte sostituendo val, mentre la condizione maggiore di 300 e minore di 150 è stato un errore di battitura che non avevo notato in precedenza, quindi vi ringrazio per avermela fatta notare. "i" mi serve per sapere il valore che ha in quel momento e tramite quello lo assegno ad un singolo led. Il circuito è formato da un quadrante 3x3 di led che si ripete 3 volte (3 volte perchè ognuno di questi quadranti mi indica un piano diverso) e ho cercato di sfruttare varie condizioni per evitare che quando premessi un pulsante per andare in qualche direzione, non "sforasse" il quadrante o si muovesse in modo strano. (sto cercando di fare in modo tale che mi possa muovere in modo verticale o orizzontale). Il problema che ho riscontrato è la condizione "salgo o scendo", quando mi compare su schermo "si o no" non mi calcola completamente i pulsanti, ma non capisco quale punto della condizione sbaglio; è come se non ha la possibilità di ricevere più informazioni.

  if(button>=500 && button<=750 && (i==1 || i==11 || i==21)){
    //se il pulsante viene premuto e "i" è uguale a 1, 11 o 21 allora la condizione è vera
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Uso ascensore?");
      lcd.setCursor(0, 1);
      lcd.print("si o no");
      delay(200);
        if(button>=0 && button<=50){
          //il pulsante destro varrà come "no" e va direttamente alla fine
          i=i;
        }
        if(button>=150 && button<=300){
          //il pulsante sinistro varrà come "si" e continuerà con un'altra condizione
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("salgo o scendo?");
          delay(200);
          if(button>=0 && button<=50 || button>=300 && button<=500){
            //se viene premuto o il pulsante sopra o il pulsante sotto la condizione è vera
            if(button>=0 && button<=50){
              //se viene premuto il pulsante sopra, si potrà salire di un piano
              i=i+10;
            }
            if(button>=300 && button<=500){
              //se viene premuto il pulsante sotto, si potrà scendere di un piano
              i=i-10;
            }
          }
        }
      
  }

Vi chiedo scusa per il modo in cui ho scritto il mio sketch, purtroppo sono ancora agli inizi con lo studio di Arduino e ho cercato di sfruttare quelle poche conoscenze che ho imparato. Non ho avuto ancora tempo di poter studiare come usare ad esempio un array.

Ma figurati! Non devi assolutamente scusarti, anzi.

Il forum è proprio qui per questa ragione, condividere ed aiutare a risolvere problemi.

Ti invio la stessa parte di programma che ho inviato a @nid69ita. Spero che ora sia più comprensibile ciò che vorrei fare.

  if(button>=500 && button<=750 && (i==1 || i==11 || i==21)){
    //se il pulsante viene premuto e "i" è uguale a 1, 11 o 21 allora la condizione è vera
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Uso ascensore?");
      lcd.setCursor(0, 1);
      lcd.print("si o no");
      delay(200);
        if(button>=0 && button<=50){
          //il pulsante destro varrà come "no" e va direttamente alla fine
          i=i;
        }
        if(button>=150 && button<=300){
          //il pulsante sinistro varrà come "si" e continuerà con un'altra condizione
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("salgo o scendo?");
          delay(200);
          if(button>=0 && button<=50 || button>=300 && button<=500){
            //se viene premuto o il pulsante sopra o il pulsante sotto la condizione è vera
            if(button>=0 && button<=50){
              //se viene premuto il pulsante sopra, si potrà salire di un piano
              i=i+10;
            }
            if(button>=300 && button<=500){
              //se viene premuto il pulsante sotto, si potrà scendere di un piano
              i=i-10;
            }
          }
        }
      
  }

Mi spieghi come può il "bottone", se deve inizialmente essere compreso fra 500 e 750, essere poi compreso fra 0 e 50, fra 150 e 300 e fra 300 e 500?... Dipende da i? Che cosa rappresenta i? Che cosa rappresenta il "bottone"? Come può essere così complesso per solo 3 piani?...

Comunque l'indentazione corretta, fatta semplicemente con CTRL+T, è questa:

if (button >= 500 && button <= 750 && (i == 1 || i == 11 || i == 21)) {
  //se il pulsante viene premuto e "i" è uguale a 1, 11 o 21 allora la condizione è vera
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Uso ascensore?");
  lcd.setCursor(0, 1);
  lcd.print("si o no");
  delay(200);
  if (button >= 0 && button <= 50) {
    //il pulsante destro varrà come "no" e va direttamente alla fine
    i = i;
  }
  if (button >= 150 && button <= 300) {
    //il pulsante sinistro varrà come "si" e continuerà con un'altra condizione
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("salgo o scendo?");
    delay(200);
    if (button >= 0 && button <= 50 || button >= 300 && button <= 500) {
      //se viene premuto o il pulsante sopra o il pulsante sotto la condizione è vera
      if (button >= 0 && button <= 50) {
        //se viene premuto il pulsante sopra, si potrà salire di un piano
        i = i + 10;
      }
      if (button >= 300 && button <= 500) {
        //se viene premuto il pulsante sotto, si potrà scendere di un piano
        i = i - 10;
      }
    }
  }
}

Anche pulsante=500 non è molto più chiaro... Sono dei pulsanti con un partitore di tensione che entrano tutti insieme su un unico ingresso con ADC?
Con tutti quei pin a disposizione hai dovuto fare ciò, che può generare valori errati di passaggio a causa di falsi contatti e capacità parassite? Anzi, è sicuro che vengono generati valori errati transitorii, perché un segnale per passare da un livello a un altro impiega del rempo, seppure brevissimo! Per usare questa tecnica, devi mettere una logica che consideri valida la lettura solo dopo che si è stabilizzata, per esempio dopo 100ms che la selezione rimane la stessa. Per selezione non intendo il valore letto, ma quello corrispondente a quella gamma di valori.

Comunque metterei all'inizio una funzione che legge il valore in ingresso e fornisce la selezione effettuata:

uint8_t puls=0;

void leggi_puls();
  {
  analogRead(1); uint16_t x = analogRead(1);
  puls=0;
  if(x>=50 and x<100) puls=1; 
  else if (x>=150 and x<=300) puls=2;
  else if (x>=500 and x<=750) puls=3;
  ...
  }
1 Like

Si tratta di una shield che viene venduta già cosi e purtroppo accompagnata sempre da esempi pessimi :woozy_face:

1 Like

Temo che anche io concordi con i giudizi degli altri, perdonami la franchezza ma quel codice è inguardabile. Per dire, potresti iniziare a studiare un pochino come funzionano gli array. Potresti semplificare moltissimo quel codice, ad esempio per memorizzare i pin che intendi usare potresti fare semplicemente un array dei 29 valori (tra l'atro per i pin basta il tipo "byte" che occupa la metà dello spazio in memoria):

byte pin[29] = {22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48 };

e quindi per inizializzarlo basta un for():

void setup() {
  lcd.begin(16, 2);
  for (int p=0; p<29; ++p)
    pinMode(pin[p], OUTPUT);
...

Ma visto che sono persino in sequenza, potresti anche fare:

byte pin[29];
...
void setup() {
  lcd.begin(16, 2);
  for (int p=0; p<29; ++p) {
    pin[p] = 22 + p;
    pinMode(pin[p], OUTPUT);
  }
...

E tutta la sbrodolata di if() finali che hai omesso diventano semplicemente:

...
  for (int p=0; p<29; ++p) {
    if (p == i-1)
      digitalWrite(pin[p], HIGH);
    else
      digitalWrite(pin[p], LOW);
  }
...

Se poi i pin saranno sempre tutti in sequenza, puoi anche evitare del tutto l'array:

...
const byte PIN_MIN = 22;
const byte PIN_MAX = 48;
...
void setup() {
  lcd.begin(16, 2);
  for (byte p=PIN_MIN; p<=PIN_MAX; ++p)
    pinMode(p, OUTPUT);
...
  for (int p=PIN_MIN; p<=PIN_MAX ; ++p) {
    if (p == i-1+PIN_MIN) // Se i=1 significa il primo pin
      digitalWrite(p, HIGH);
    else
      digitalWrite(p, LOW);
  }
...

Ma sì: se proprio non vuole chiamarli con il proprio numero, basta scrivere n+21...

Comunque

#define pin1 22
#define pin2 23
...

a parte la prolissità è la soluzione più efficiente, perché in fase di compilazione vengono inseriti i numeri corrispondenti e non rimane traccia dei numeri sostituiti.

Tra l'altro, funziona anche una cosa del genere:

#define pin1 11
#define pin2 12
#define pin3 13
#define pin4 14
#define pin5 15

void setup()
{
for(uint8_t x=pin2; x<pin5; x++)
  {
  Serial.println(x+20);
  }
}

Risultato:

32
33
34