Ciao a tutti, da alcune settimane sto usando Arduino e mi sono imbattuto in un problema che non riesco a risolvere, spero nel vostro aiuto: magari qualcuno più esperto nell'elettronica riconosce al volo qualcosa di noto.
Ho realizzato una pulsantiera di 8 pulsanti; usando le resistenze, devono trasmettere diversi valori ad un unico pin analogico A5.
Il PROBLEMA: una volta ogni tanto (qualche decina di pressioni) legge un valore errato. Premo il tasto 1, legge il valore del tasto 4 (o altro o, più spesso, il tasto 8 - valore circa 1020 ).
Con il debouncing ho ridotto il problema (inizialmente ogni volta che leggeva un tasto mi dava altri due o tre valori), ma non l'ho eliminato.
Con uno sketch un po' più complesso di questo, che non mi pare sia differente nella sostanza, i problemi sono anche maggiori.
Ho il sospetto che mentre il pulsante si apre e chiude ci siano dei picchi di tensione, fuori dal range creato dal partitore di tensione per un determinato pulsante.
E' normale questo? Ci sono soluzioni?
Ho seguito le istruzioni del Libro dei progetti (Tastiera musicale) ma invertendo la corrente: mi serviva che le resistenze andassero a massa.
Il circuito:
3 pulsanti: resistenze 0-220-500 ohm;
2 pulsanti: 500-4700 ohm, a ciascuna sommo 4.700 ohm fra pulsante e pin;
3 pulsanti: 4700-10000-10000000 ohm; a ciascuna si sommano 10.000 ohm
Al + va una resistenza da 4700 ohm.
int pulsante()
{
debounceTime = millis();
if(debounceTime < lastDebounceTime + DEBOUNCE_DELAY)
return 0;
else
lastDebounceTime = debounceTime;
valoreA5 = analogRead(A5); //Legge valore tasto
if (valoreA5 > 1020) //Premuto nulla
{
debouncePausa = 1; //Attiva pressione
return 0;
}
if (!debouncePausa) //non c'è stata pausa: esci
return 0;
debouncePausa = 0; //E' stato premuto qualcosa: disattiva pressione
if (valoreA5 < 22)
return 1;
if (valoreA5 < 72)
return 2;
if (valoreA5 < 317)
return 3;
if (valoreA5 < 609)
return 4;
if (valoreA5 < 728)
return 5;
if (valoreA5 < 801)
return 6;
if (valoreA5 < 923)
return 7;
if (valoreA5 < 1020)
return 8;
return 0;
}
Stampa con seiale.println() il valore analogico letto. Cosí ti rendi conto che valori vengono letti. forse un pulsante non fa bene contatto e percui il vlore analogico letto é errato.
Grazie mille Uwe. Nello sketch non c'è molto altro, riporto sotto.
Il pulsante 1 mi dovrebbe dare 0; su 30 colpi, ad esempio, mi ha dato 0 venti volte e altri valori tipo 13, 50, 180.
Sembra che dopo un po' di colpi (dopo che ho caricato lo sketch) comunque diventi più accurato.
Sotto provo ad allegare un'immagine.
int pulsante(); //Tasto appena premuto
const long DEBOUNCE_DELAY = 50; //Ritardo per debounce
long int lastDebounceTime = 0; //Per debounce
long int debounceTime; //Per debounce
boolean debouncePausa = 1; //pressione attivata
void setup()
{
Serial.begin(9600);
}
int valoreA5 = 0;/**/
void loop()
{
int i = pulsante();
if(i)
{
Serial.print (i);
Serial.print(" valore ");
Serial.println(valoreA5);
}
}
int pulsante()
{
debounceTime = millis();
if(debounceTime < lastDebounceTime + DEBOUNCE_DELAY)
return 0;
else
lastDebounceTime = debounceTime;
valoreA5 = analogRead(A5); //Legge valore tasto
if (valoreA5 > 1020) //Premuto nulla
{
debouncePausa = 1; //Attiva pressione
return 0;
}
if (!debouncePausa) //non c'è stata pausa: esci
return 0;
debouncePausa = 0; //E' stato premuto qualcosa: disattiva pressione
if (valoreA5 < 22)
return 1;
if (valoreA5 < 72)
return 2;
if (valoreA5 < 317)
return 3;
if (valoreA5 < 609)
return 4;
if (valoreA5 < 728)
return 5;
if (valoreA5 < 801)
return 6;
if (valoreA5 < 923)
return 7;
if (valoreA5 < 1020)
return 8;
return 0;
}
Mi sono permesso di modificare completamente i tuo sketch.
#define LETTURE 10
void setup() {
Serial.begin(9600);
}
void loop() {
int i = pulsante();
if (i) Serial.println(i);
}
byte pulsante() {
unsigned int Valore = 0;
for (byte I = 0; I < LETTURE; I ++) {
Valore += analogRead(A5); // Legge valore tasto e lo somma
}
Valore /= LETTURE; // valore medio
if (Valore < 22) return 1;
if (Valore < 72) return 2;
if (Valore < 317) return 3;
if (Valore < 609) return 4;
if (Valore < 728) return 5;
if (Valore < 801) return 6;
if (Valore < 923) return 7;
if (Valore < 1020) return 8;
return 0;
}
ahhh, grazie mille! A parte che è più bello, c'è il trucco! Poi lo collaudo.
Quindi è normale che il pulsante dia qualche valore sballato. Il mio cervello rifiutava la cosa al punto che non ho pensato a soluzioni.