Go Down

Topic: [RISOLTO] Problema visualizzazione valore su display 7 segnenti (Read 759 times) previous topic - next topic

gianlu81

Oct 15, 2012, 02:25 pm Last Edit: Oct 17, 2012, 08:58 pm by gianlu81 Reason: 1
Ciao a tutti, ho un problema con un programma. Spiego brevemente come funziona il programma:dopo la pressione di uno dei tasti modifica il valore della variabile cont,e in base al valore acquisito da cont,con switch case, va a pilotare un cd4511(cod. bcd )che decodifica per rappresentare sul display in questione il valore di cont.Fin qui tutto bene visto che il programma che posterò a seguitio funziona correttamente. Quello che però non va, o per lo meno non va bene a me,è il fatto che finchè non rilascio il pulsante non mi cambia lo stato (switch case) che pilota il cd4511, mentre il valore di cont cambia prima del rilascio del pulsante(visto dal serial monitor).Spero di essere riuscito a spiegarmi correttamente nel caso chiedete pure se qualcosa non è chiaro grazie per l'aiuto e buona continuazione.
Code: [Select]

//contatore da 0 a 6 base con due pulsnti
//con visualizzazione su monitor
//seriale del valore acquisito da cont
//e visualizzazione del numero su display
//led 7 digit con interfaccia cd4511

int up =8;
int down =7;
int attup =13;
int attdown =12;
int val_up;
int val_down;
int cont;
int pausa =250;
int led1 =10;
int led2 =11;
int led3 =2;


void setup(){
 pinMode(up, INPUT);
 pinMode(down, INPUT);
 pinMode(attup, OUTPUT);
 pinMode(attdown, OUTPUT);
 pinMode(led1, OUTPUT);
 pinMode(led2, OUTPUT);
 pinMode(led3, OUTPUT);
 Serial.begin(9600);
}

void loop(){

 Serial.println(cont);

 val_up = digitalRead(up);
 val_down = digitalRead(down);
 
 if ( val_up == HIGH && cont <= 5) {
   digitalWrite (attup, HIGH);
   delay (pausa);
   digitalWrite (attup, LOW);
   cont++;
   Serial.println(cont);
   while (digitalRead(up)){
   }
 }

 else if ( val_down == HIGH && cont != 0) {
   digitalWrite(attdown, HIGH);
   delay (pausa);
   digitalWrite(attdown, LOW);
   cont--;
   Serial.println(cont);

   while (digitalRead(down)){
   }
 }

 else {
   digitalWrite(attup, LOW);
   digitalWrite(attdown, LOW);
 }

 switch (cont) {

 case 0:
   digitalWrite(led1, LOW);
   digitalWrite(led2, LOW);
   digitalWrite(led3, LOW);
   break;

 case 1:
   digitalWrite(led1, LOW);
   digitalWrite(led2, LOW);
   digitalWrite(led3, HIGH);
   break;

 case 2:
   digitalWrite(led1, LOW);
   digitalWrite(led2, HIGH);
   digitalWrite(led3, LOW);
   break;

 case 3:
   digitalWrite(led1, LOW);
   digitalWrite(led2, HIGH);
   digitalWrite(led3, HIGH);
   break;

 case 4:
   digitalWrite(led1, HIGH);
   digitalWrite(led2, LOW);
   digitalWrite(led3, LOW);
   break;

 case 5:
   digitalWrite(led1, HIGH);
   digitalWrite(led2, LOW);
   digitalWrite(led3, HIGH);
   break;

 case 6:
   digitalWrite(led1, HIGH);
   digitalWrite(led2, HIGH);
   digitalWrite(led3, LOW);
   break;
 }

 delay (15);
}

mancio

Potresti farti due cicli di attesa che vanno a controllare se è stato premuto il tasto up o down semplicemente con una variabile di stato

Code: [Select]
bool isHigh; //true = HIGH, false = LOW
int count = 0;

if(digitalRead(up) == HIGH){
   while(digitalRead(up)==HIGH)
   isHigh = true;
   if(count<6) count++;
}

if(digitalRead(down) == HIGH){
   while(digitalRead(down)==HIGH)
   isHigh = false;
   if(count>0) count--;
}

//a questo punto hai la nella variabile isHigh il tasto premuto (se non ti serve questa info puoi togliere le righe con isHigh tanto dovrebbe funzionare lo stesso
//e in count il valore da mostrare

...switch...

gianlu81

Purtroppo il codice postato lo avevo provato successivamente,e avevo ottenuto risultati peggiori. Nel senso che, oltre al ritardo di incremento sul display, il ritardo lo avevo anche sul serial monitor...(per ritardo intendo che finchè non rilascio il pulsante,non avviene la variazione di cont o del display).avrei bisogno qualcosa che mi permettesse di incrementare del valore prescelto il display nonostante che il pulsante sia ancora premuto.comunque grazie lo stesso!!!  ;)

PaoloP

#3
Oct 16, 2012, 11:16 pm Last Edit: Oct 16, 2012, 11:30 pm by PaoloP Reason: 1

Quello che però non va, o per lo meno non va bene a me,è il fatto che finchè non rilascio il pulsante non mi cambia lo stato


E' normale. Il codice viene bloccato qui
Code: [Select]

while (digitalRead(up)){ }

e qui
Code: [Select]

while (digitalRead(down)){    }


Prova a commentare quelle 2 righe.

Aggiungi una variabile di stato e controllala nell'if in modo da non rientrare se tieni premuto il pulsante.

EDIT:
Modificando l'esempio di mancio
Code: [Select]
bool isUp, isDown; //true = HIGH, false = LOW
int count = 0;

if(digitalRead(up) == HIGH && isUp==false){
  delay(10); // debounce
   isUp = true;
  if(count<6) count++;
} else isUp = false;

if(digitalRead(down) == HIGH && isDown==false){
  delay(10); // debounce
   isDown = true;
  if(count>0) count--;
} else isDown = false;

Codice non testato. Verifica se compila o correggilo.  :smiley-roll-sweat:

leo72


E' normale. Il codice viene bloccato qui
Code: [Select]

while (digitalRead(up)){ }


In un altro thread chiedeva di bloccare il codice fino al rilascio del pulsante, e gli avevo consigliato quel while. Ora però se cambia la logica del programma, va rivisto tutto.

mancio

si è bloccante in quei due punti ma l'avevo fatto apposta..non penso sia "peggiore"..cambia solamente la logica del programma..ovviamente dipende dall'applicazione che devi fare..se devi fare un "tester" per la velocità dei riflessi allora non deve essere bloccante (troppo margine d'errore per il pulsante) e quindi appena c'è un cambia di stato LOW-HIGH lo consideri come momento buono per incrementare. Se invece ti serve per contare quante volte è stato premuto il pulsante allora va bene anche il mio sketch perchè da un certo punto di vista considera anche l'antirimbalzo del pulsante sul fronte LOW-HIGH..non so se sono stato chiaro.

gianlu81

#6
Oct 17, 2012, 08:31 pm Last Edit: Oct 17, 2012, 09:30 pm by gianlu81 Reason: 1
Ringrazio per i consigli.Al momento sono riuscito ad ottenere cio che volevo un po' ragionado,un po' con delle prove e molto per c..o  XD .
Mancio non volevo sminuire il tuo consiglio/programma quando ho scritto peggiore era solo per dire che non andava bene nemmeno lui per il mio scopo.
Come avrete ben capito purtroppo sono alle prime armi e non avendo nessuno che mi insegni chiedo qui qualche consiglio dopo che magari ho già perso molte ore a
cercare informazioni, provare e leggere nei vari corsi online senza riuscire a venirne a capo.Spero di non stressarvi troppo in futuro.comunque grazie a tutti.
Questo è il codice "giusto" per il mio scopo non sarà il massimo da leggersi forse si riusciva a fare risparmiando memoria però in compenso sono soddisfatto.
Grazie leo72 per quel while senno neanche il c..o poteva aiutarmi....
P.S. critiche e consigli sempre ben accetti!!!!!
Code: [Select]


//contatore da 0 a 6 base con due pulsnti
//con visualizzazione su monitor
//seriale del valore acquisito da cont
//e visualizzazione del numero su display
//led 7 digit con interfaccia cd4511

int up =8;
int down =7;
int attup =13;
int attdown =12;
int val_up;
int val_down;
int count;
int pausa =250;
int led1 =10;
int led2 =11;
int led3 =2;


void setup(){
  pinMode(up, INPUT);
  pinMode(down, INPUT);
  pinMode(attup, OUTPUT);
  pinMode(attdown, OUTPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  Serial.begin(9600);
}

void loop(){

  Serial.println(count);

  val_up = digitalRead(up);
  val_down = digitalRead(down);

  if ( val_up == HIGH && count <= 5) {
    digitalWrite (attup, HIGH);
    delay (pausa);
    digitalWrite (attup, LOW);
    count++;
    Serial.println(count);
     
  }

  else if ( val_down == HIGH && count != 0) {
    digitalWrite(attdown, HIGH);
    delay (pausa);
    digitalWrite(attdown, LOW);
    count--;
    Serial.println(count);
   
  }

  else {
    digitalWrite(attup, LOW);
    digitalWrite(attdown, LOW);
  }
 
  switch (count) {

  case 0:
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    while (digitalRead(up)){
    }
    while (digitalRead(down)){
    }
    break;

  case 1:
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
    while (digitalRead(up)){
    }
    while (digitalRead(down)){
    }
    break;

  case 2:
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
    while (digitalRead(up)){
    }
    while (digitalRead(down)){
    }
    break;

  case 3:
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, HIGH);
    while (digitalRead(up)){
    }
    while (digitalRead(down)){
    }   
    break;

  case 4:
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    while (digitalRead(up)){
    }
    while (digitalRead(down)){
    }
    break;

  case 5:
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    digitalWrite(led3, HIGH);
    while (digitalRead(up)){
    }
    while (digitalRead(down)){
    }
    break;

  case 6:
    digitalWrite(led1, HIGH);
    digitalWrite(led2, HIGH);
    digitalWrite(led3, LOW);
    while (digitalRead(up)){
    }
    while (digitalRead(down)){
    }
    break;
  }

  delay (15);
}




Go Up