Pages: [1]   Go Down
Author Topic: Misurare pressione bottone  (Read 1283 times)
0 Members and 1 Guest are viewing this topic.
Milan,Italy
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Allora prima di tutto vi metto il circuito fatto con fritzing:
https://www.dropbox.com/s/ebc5xxgxaaep5lw/Schema_fritz.jpg
adesso vi spiego il mio "problema".
Quello che voglio provare a fare è accendere i led in sequenza a distanza di un secondo l'uno dall'altro,se e solo se il bottone rimane premuto.
Con questo codice:
Code:
const int v = 2;
const int r1=3;
const int r2 = 4;
const int r3=5;
const int g = 6;
const int bottone = 12;
int statoBottone;
void setup(){
  pinMode(v,OUTPUT);
  pinMode(r1,OUTPUT);
  pinMode(r2,OUTPUT);
  pinMode(r3,OUTPUT);
  pinMode(g,OUTPUT);
  pinMode(bottone,INPUT);
}
void loop(){
  statoBottone=digitalRead(bottone);
  if(statoBottone==HIGH){
    delay(1000);
    digitalWrite(v,HIGH);
    delay(1000);
    digitalWrite(r1,HIGH);
    delay(1000);
    digitalWrite(r2,HIGH);
    delay(1000);
    digitalWrite(r3,HIGH);
    delay(1000);
    digitalWrite(g,HIGH);
  }
  if(statoBottone==LOW){
    for(int i=2;i<=6;i++) digitalWrite(i,LOW);
  }
}
Più o meno ottengo quello che voglio,però ovviamente quando smetto di schiacciare il bottone non è detto che i Led si spengano subito..
Qui http://arduino.cc/playground/Code/HoldButton e qui http://arduino.cc/playground/Code/AvoidDelay ho letto un po' sulla funzione millis() che forse è quella che mi serve,ma non riesco ad utilizzarla,ho provato così,ma non funziona:
Code:
const int v = 2;
const int r1=3;
const int r2 = 4;
const int r3=5;
const int g = 6;
const int bottone = 12;
unsigned long int timer;
int statoBottone;
void setup(){
  pinMode(v,OUTPUT);
  pinMode(r1,OUTPUT);
  pinMode(r2,OUTPUT);
  pinMode(r3,OUTPUT);
  pinMode(g,OUTPUT);
  pinMode(bottone,INPUT);
}
void loop(){
  statoBottone=digitalRead(bottone);
  if(statoBottone==HIGH){
    timer = millis();
    if(millis()-timer >=1000) digitalWrite(v,HIGH);
    if(millis()-timer >=2000) digitalWrite(r1,HIGH);
    if(millis()-timer >=3000) digitalWrite(r2,HIGH);
    if(millis()-timer >=4000) digitalWrite(r3,HIGH);
    if(millis()-timer >=5000) digitalWrite(g,HIGH);
  }
  if(statoBottone==LOW){
    for(int i=2;i<=6;i++) digitalWrite(i,LOW);
  }
}
Ho provato in questo modo perchè se ho ben capito millis() restituisce i millisecondi passati dal momento in cui si avvia il microprocessore della scheda arduino,quindi se a timer assegno i millisecondi che sono passati quando premo il bottone millis()-timer dovrebbe essere il tempo in cui il bottone rimane schiacciato.
Sicuramente è sbagliato perchè non funziona:)
Grazie in anticipo per l'aiuto e chiedo scusa per il messaggio un po' lungo..
Logged

Bergamo
Offline Offline
God Member
*****
Karma: 1
Posts: 663
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao

devi cambiare un po' l'approccio:

1) parti dalla condizione bottone non premuto, il loop() continuerà ad essere eseguito senza far nulla;
2) non appena rilevi che il bottone è premuto, salvati in una variabile il valore in quel momento di millis(), in questo modo sai quando il bottone ha iniziato ad essere premuto, nel caso accendi anche un led (se uno va acceso subito). Salvati anche in una variabile che hai rilevato il bottone premuto
3) se ora sei nella condizione "ho rilevato il bottone premuto" e il bottone è ancora premuto, confronta il millis() attuale con quello salvato, se è maggiore di 1000 la differenza (= trascorso un secondo) accendi il led; se invece il bottone non è più premuto torna alla condizione iniziale
Logged

lucadentella.it

Milan,Italy
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho seguito il tuo consiglio,ma ancora non riesco a capire una cosa;dato che non riesco ancora a farlo andare ho provato a stampare a video il valore di millis()-timer in questo modo(scrivo in pseudo-codice):
if(bottone_premuto)
      timer=millis;
      if(bottone ancora premuto) serial.println(millis-timer)
Quando eseguo il codice così però ottengo che millis-timer è sempre uguale a 0,non dovrebbe invece crescere misurando appunto la durata della pressione del pulsante?I am confused! smiley-roll-sweat
Grazie mille per l'aiuto e la pazienza comunque smiley
Logged

Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 573
Posts: 12633
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho seguito il tuo consiglio,ma ancora non riesco a capire una cosa;dato che non riesco ancora a farlo andare ho provato a stampare a video il valore di millis()-timer in questo modo(scrivo in pseudo-codice):
if(bottone_premuto)
      timer=millis;
      if(bottone ancora premuto) serial.println(millis-timer)
Quando eseguo il codice così però ottengo che millis-timer è sempre uguale a 0,non dovrebbe invece crescere misurando appunto la durata della pressione del pulsante?I am confused! smiley-roll-sweat
Grazie mille per l'aiuto e la pazienza comunque smiley
intanto dopo millis devi sempre mettere ()temo che il processore vada un po' più veloce della funzione millis smiley Se imposti timer=millis e all'istruzione successiva vuoi leggere millis-timer per me è naturale aspettarmi 0; per capirci prova a mettere (anche se non ti serve) un delay (100) subito dopo la riga timer=millis; in questo caso dovresti ottenere un valore prossimo a 100.
Logged


Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7183
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Prova così:
Code:
const int v = 2;
const int r1=3;
const int r2 = 4;
const int r3=5;
const int g = 6;
const int bottone = 12;
unsigned long int timer;
int statoBottone;

void setup(){
  pinMode(v,OUTPUT);
  pinMode(r1,OUTPUT);
  pinMode(r2,OUTPUT);
  pinMode(r3,OUTPUT);
  pinMode(g,OUTPUT);
  pinMode(bottone,INPUT);
}

void loop(){
  statoBottone=digitalRead(bottone);
  if(statoBottone==HIGH){
  // quando è premuto il pulsante calcola la differenza tra timer e millis.
    if(millis()-timer >=1000) digitalWrite(v,HIGH);
    if(millis()-timer >=2000) digitalWrite(r1,HIGH);
    if(millis()-timer >=3000) digitalWrite(r2,HIGH);
    if(millis()-timer >=4000) digitalWrite(r3,HIGH);
    if(millis()-timer >=5000) digitalWrite(g,HIGH);
  }
  if(statoBottone==LOW){
  //quando non è premuto nessun pulsante memorizza timer
    timer = millis();
    for(int i=2;i<=6;i++) digitalWrite(i,LOW);
  }
}

Ho spostato solamente "timer = millis();" dalla condizione HIGH alla condizione LOW.
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Milan,Italy
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

PaoloP ho provato il tuo codice e così funziona esattamente come volevo io:)Non mi è chiaro il motivo però smiley-lol smiley-confuse
Logged

Milan,Italy
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ragionandoci un po' forse ci sono arrivato,correggimi se sbaglio.In pratica finchè il bottone è LOW timer e millis assumono lo stesso valore,poi una volta che il pulsante viene premuto millis continua a scorrere mentre timer rimane "bloccato" al valore di prima e quindi millis-timer misura correttamente quanto il pulsante rimane premuto..Comunque grazie a tutti per l'aiuto:)
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7183
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ragionandoci un po' forse ci sono arrivato,correggimi se sbaglio.In pratica finchè il bottone è LOW timer e millis assumono lo stesso valore,poi una volta che il pulsante viene premuto millis continua a scorrere mentre timer rimane "bloccato" al valore di prima e quindi millis-timer misura correttamente quanto il pulsante rimane premuto..Comunque grazie a tutti per l'aiuto:)
Esatto.  smiley-lol
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Milan,Italy
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ottimo:) Adesso voglio spingermi anche più in là!:)
Con questo codice:
Code:
const int v = 2;
const int r1=3;
const int r2 = 4;
const int r3=5;
const int g = 6;
const int bottone = 12;
unsigned long int timer;
int statoBottone;

void setup(){
  pinMode(v,OUTPUT);
  pinMode(r1,OUTPUT);
  pinMode(r2,OUTPUT);
  pinMode(r3,OUTPUT);
  pinMode(g,OUTPUT);
  pinMode(bottone,INPUT);
}

void loop(){
  statoBottone=digitalRead(bottone);
  if(statoBottone==HIGH){
  // quando è premuto il pulsante calcola la differenza tra timer e millis.
    if(millis()-timer==1000) digitalWrite(v,HIGH);
    if(millis()-timer ==2000) digitalWrite(r1,HIGH);
    if(millis()-timer ==3000) digitalWrite(r2,HIGH);
    if(millis()-timer ==4000) digitalWrite(r3,HIGH);
    if(millis()-timer ==5000) digitalWrite(g,HIGH);
    if(millis()-timer ==6000) digitalWrite(g,LOW);
    if(millis()-timer ==7000) digitalWrite(r3,LOW);
    if(millis()-timer ==8000) digitalWrite(r2,LOW);
    if(millis()-timer ==9000) digitalWrite(r1,LOW);
    if(millis()-timer ==10000)digitalWrite(v,LOW);
  }
  if(statoBottone==LOW){
  //quando non è premuto nessun pulsante memorizza timer
    timer = millis();
    for(int i=2;i<=6;i++) digitalWrite(i,LOW);
  }
}
Ottengo un effetto a scala,nel senso che i led si accendono uno dopo l'altro e poi si spengono in ordine inverso(sempre e solo se tengo il bottone premuto).
Io vorrei provare a rendere la cosa ciclica,nel senso che una volta che si sono accesi e poi spenti tutti se io continuo a tenere premuto ricominciato ad accendersi,il problema è che avendo tenuto premuto il pulsante millis()-timer supera i 10 secondi.
Pensavo ad un if((millis()-timer)%1000==0) ma ovviamente non può andare bene..Ho pensato anche di provare ad usare goto,ma sembra anche peggio:)Aiutino:)?
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7183
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nooooooooooooooo i goto... noooooooooooo. Non li sopporto.  smiley-twist smiley-twist smiley-twist

Aggiungi questo dopo l'ultimo if
Code:
if(millis()-timer == 11000) timer = millis(); // Resetto la variabile timer e reinizio il ciclo dopo 11 secondi
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Milan,Italy
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perfetto e più semplice non poteva essere:)Grazie mille:)Ecco il codice conclusivo comunque:
Code:
const int v = 2;
const int r1=3;
const int r2 = 4;
const int r3=5;
const int g = 6;
const int bottone = 12;
unsigned long int timer;
int statoBottone;

void setup(){
  pinMode(v,OUTPUT);
  pinMode(r1,OUTPUT);
  pinMode(r2,OUTPUT);
  pinMode(r3,OUTPUT);
  pinMode(g,OUTPUT);
  pinMode(bottone,INPUT);
}

void loop(){
  statoBottone=digitalRead(bottone);
  if(statoBottone==HIGH){
  // quando è premuto il pulsante calcola la differenza tra timer e millis.
    if(millis()-timer==1000) digitalWrite(v,HIGH);
    if(millis()-timer ==2000) digitalWrite(r1,HIGH);
    if(millis()-timer ==3000) digitalWrite(r2,HIGH);
    if(millis()-timer ==4000) digitalWrite(r3,HIGH);
    if(millis()-timer ==5000) digitalWrite(g,HIGH);
    if(millis()-timer ==6000) digitalWrite(g,LOW);
    if(millis()-timer ==7000) digitalWrite(r3,LOW);
    if(millis()-timer ==8000) digitalWrite(r2,LOW);
    if(millis()-timer ==9000) digitalWrite(r1,LOW);
    if(millis()-timer ==10000){digitalWrite(v,LOW);timer=millis();}
  }
  if(statoBottone==LOW){
  //quando non è premuto nessun pulsante memorizza timer
    timer = millis();
    for(int i=2;i<=6;i++) digitalWrite(i,LOW);
  }
}
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22936
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nooooooooooooooo i goto... noooooooooooo. Non li sopporto.  smiley-twist smiley-twist smiley-twist
Viva Edsger Dijkstra  smiley-grin
Logged


Pages: [1]   Go Up
Jump to: