Go Down

Topic: Lettura Potenziometro e Oversampling (Read 3667 times) previous topic - next topic

Codesound

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

Code: [Select]

// 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
}



nid69ita

#1
Mar 19, 2013, 10:42 pm Last Edit: Mar 19, 2013, 10:46 pm by nid69ita Reason: 1
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);
my name is IGOR, not AIGOR

Codesound

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

nid69ita

Ti riferisci a questo?
http://www.atmel.com/images/doc8003.pdf
my name is IGOR, not AIGOR

PaoloP

#4
Mar 19, 2013, 11:35 pm Last Edit: Mar 19, 2013, 11:48 pm by PaoloP Reason: 1

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
Code: [Select]
int valore = (analogRead(0)/8); // Lettura del valore del potenziometro

con

Code: [Select]

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.

leo72

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.

astrobeed


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.
Scientia potentia est

nid69ita

Bel link Leo, sembra il mio  :smiley-mr-green:

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
my name is IGOR, not AIGOR

leo72


Codesound

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

Go Up