Lettura Potenziometro e Oversampling

Carissimi, sono alle prese con la lettura di un potenziometro:

con il seguente codice ed un semplice potenziometro da 10K (nuovo di stecca), collegato correttamente alla porta analogica (0) di un Arduino Mega 2560 Rev.3, alimentato via USB dal PC, è CHIARO che, ruotando LENTAMENTE il potenziometro, (e aggiustandolo INTENZIONALMENTE), si arriva a quel SOTTILE PUNTO in cui il potenziometro genera QUEL VALORE DI TENSIONE che sarebbe in mezzo fra, ad esempio, 64 e 65, generando, sul serial monitor, una lettura instabile della variabile ‘numero’ (vedi codice esempio) (esso infatti fluttuerà fra 2 e 3).

Dal momento che vorrei realizzare una capillare lettura stabile di 1024/8=128 valori dati dal convertitore, è chiara la FITTA RETE di ‘if else’ (vedi codice esempio) che dovrò scrivere nel codice e quindi quanta confusione questo codice genererebbe sul serial monitor…
(più è fitta la rete, più spesso verrà lasciato il potenziometro a cavallo dei famosi due valori…)
L’unico modo che ho trovato per risolvere questo problema è il Sovracampionamento (con Vref di 5V) a 11 o addirittura a 12bit. Tuttavia NON so come applicare detta tecnica al codice che vi ho esposto.
Qualcuno può aiutarmi? Ovvero, come posso sovracampionare la lettura di questo potenziometro?
Grazie, Ruben

// Codice by Tonetta Ivan(Ruben) in data 19.03.2013
byte numero = 0;

void setup() { Serial.begin(9600); }
void loop() {
  int valore = (analogRead(0)/8); // Lettura del valore del potenziometro
  if (valore <= 32)                      { numero = 1; }
  else if (valore > 32 && valore <= 64)  { numero = 2; }
  else if (valore > 64 && valore <= 96)  { numero = 3; }
  else if (valore > 96 && valore <= 128) { numero = 4; }
  Serial.println(numero); // invio valori al serial monitor per la stampa
  delay(10); // attendi 10ms
}

Se non ho capito male, ti risolve tutto una istruzione software, la map()
http://arduino.cc/en/Reference/Map

int val = analogRead(0);
val = map(val, 0, 1023, 0, 255); // un valore tra 0-1023 trasformato in uno proporzionale 0-255

nel tuo caso: val=map(val,0,1023,1,4);

carissimo, anche la funzione map arriva fino ad un certo punto...
E' PROPRIO UN LIMITE HARDWARE dato dal fatto che necessito di un paio di bit in piu rispetto ai 10 che offre arduino

grazie, Ruben

Ti riferisci a questo?
http://www.atmel.com/images/doc8003.pdf

Codesound:
L'unico modo che ho trovato per risolvere questo problema è il Sovracampionamento (con Vref di 5V) a 11 o addirittura a 12bit. Tuttavia NON so come applicare detta tecnica al codice che vi ho esposto.
Qualcuno può aiutarmi? Ovvero, come posso sovracampionare la lettura di questo potenziometro?

Sostituisci

int valore = (analogRead(0)/8); // Lettura del valore del potenziometro

con

byte numerocampioni = 16;
unsigned long valore = 0;
for (byte j=0; j>numerocampioni; j++)
 {
  valore += (analogRead(0)/8); // Lettura del valore del potenziometro
  }
valore /= numerocampioni;

In questo modo fai una medi su n campioni, ma non stai sovracampionando.

Per l’oversampling ti passo questo doc:
http://www.atmel.com/images/doc8003.pdf

Per ogni bit in più di risoluzione devi campionare 22n volte in più. Quindi per 1 bit devi fare 4 letture, per 2 bit, 16 letture ecc. Riduci quindi la velocità di campionamento.

Potresti risolvere via software mettendo un controllo che ti memorizzi i precedenti 2 valori e se ti accorgi che il 3° è uguale al primo e differisce solo di 1 dal 2° allora vuol dire che il valore letto sta oscillando di 1 unità in su ed in giù.
es.
62-63-62-63…
Al 3° valore, non stampi la nuova unità ma replichi la 2a lettura.

Codesound:
Qualcuno può aiutarmi? Ovvero, come posso sovracampionare la lettura di questo potenziometro?

Non puoi usare l'oversampling con un potenziometro perché questa tecnica ha come prerequisito la presenza di rumore, con distribuzione uniforme, sul segnale.
In tutti i casi tutti gli ADC hanno sempre l'instabilità di +/- 1 count, indipendentemente dalla risoluzione avresti sempre dei punti dove la cifra, non importa se rappresenta una frazione della risoluzione, oscilla.
Unica soluzione possibile è fare una media mobile su almeno 16 campioni, in questo modo non elimini completamente il problema, però lo attenui moltissimo.
La media mobile si fa tramite un ring register, sopra scrivi continuamente tutti i campioni presi dal ADC partendo dalla prima posizione fino alla fine, poi riparti dalla prima posizione, ad ogni campionamento fai la media di tutti i valori del ring register, in questo modo ottieni l'andamento ideale del segnale pulendolo dal rumore e dalle fluttuazioni del ADC stesso.

Bel link Leo, sembra il mio :grin:

Dal codice del primo post sembrava volessi fare semplicemente una map;
tra l'altro bastava un calcolo invece di quei if infiniti
val=int((valore_letto-1)/32)+1 // solo valore 0 da 0, perciò al max un if

nid69ita:
Bel link Leo, sembra il mio :grin:

...azz.... :sweat_smile:

Grazie a tutti voi. Appena posso provo il tutto e vi faccio sapere. Scusate il ritardo ma ho appena saputo di essere papà. ..

Impiego un po a scrivere anche perché non ho internet. ..
Grazie ancora. A presto