Pages: [1] 2   Go Down
Author Topic: Problema con analogRead  (Read 2059 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho uno strano problema con analogRead() e non riesco a capire perchè mi succede.

Uso tre ingressi analogici e un lcd per vedere i valori letti.
Uno lo uso come un digitale, quindi nel setup() ho messo pinMode INPUT numerando il pin secondo i pin analogici ma da 14 a 19 anzichè da 0 a 5.
Agli altri due pin ho collegato dei potenziometri.
Con un analogRead() leggo il primo valore analogico dal potenziometro.
Il secondo valore analogico dell'altro potenziometro lo leggo solo quando vedo che il pin che uso come digitale è alto, per farlo uno digitalRead() e un interruttore.
Se lascio l'interruttore aperto vedo il primo valore analogico correttamente.
Se invece chiudo l'interruttore il secondo valore analogico lo vedo correttamente, ma il primo che continuo a leggere sale e scende da solo...
Non capisco perchè succeda, ho letto che servono almeno 100us per ricaricare il condensatore dell'analogRead(), ma anche mettendo 10 millisecondi di delay tra un analogRead() e l'altro non cambia...
Logged

Offline Offline
God Member
*****
Karma: 9
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

domanda banale: il primo ingresso analogico è collegato a qualcosa con tensione fissa,quando lo vedi flottare?
Logged

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21271
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Come hai collegato l'interuttore? usi una resistenza pullup/pulldown?
Ciao Uwe
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

dopo varie prove ho scoperto che se prima di leggere quello che mi serve metto un'analogRead() a vuoto funziona tutto correttamente.
Per esempio se invece di mettere
Code:
int a = analogRead(A0);
metto
Code:
analogRead(A0);
int a = analogRead(A0);
funziona.
Ma è normale che faccia così?
Logged

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

La prima volta che si usa l'ADC è bene fare una lettura a vuoto per calibrare il circuito S&H interno. Questo vale anche nel caso di ADC spento per motivi di sleep o altro.
Potresti postare lo sketch usato per capire cosa può succedere?
Logged


0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Allora, ecco quello che ho scoperto:

Code:
#include "LiquidCrystal.h"
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  lcd.begin(16, 2);
}

void loop() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(analogRead(A0));
  lcd.setCursor(8, 0);
  lcd.print(analogRead(A2));
  lcd.setCursor(0, 1);
  lcd.print(analogRead(A1));
  lcd.setCursor(8, 1);
  lcd.print(analogRead(A3));
 
  delay(500);
}

Con questo codice stampo sull'lcd quello che leggo dai pin analogici 0, 1, 2 e 3.
Quello che c'è collegato ai pin A0 e A1 lo lascio fisso, mentre faccio variare quello collegato ai pin A2 e A3:
  • se alzo A3 cambia anche il valore di A0
  • se alzo A2 cambia anche il valore di A1
Quando alzo A2 o A3 vedo correttamente i valori di A2 e A3 (almeno sembra che salgano correttamente), mentre gli altri valori si alzano di un po' ma non in modo stabile, rimangono sempre più alti del normale ma un po' salgono e un po' scendono.


Se invece faccio:
Code:
#include "LiquidCrystal.h"
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  lcd.begin(16, 2);
}

void loop() {
  lcd.clear();
  lcd.setCursor(0, 0);
  analogRead(A0);
  lcd.print(analogRead(A0));
  lcd.setCursor(8, 0);
  lcd.print(analogRead(A2));
  lcd.setCursor(0, 1);
  analogRead(A1);
  lcd.print(analogRead(A1));
  lcd.setCursor(8, 1);
  lcd.print(analogRead(A3));
 
  delay(500);
}
funziona tutto correttamente.
Anche se non metto analogRead() a vuoto per i pin A2 e A3 funziona, forse perchè A0 e A1 rimangono sempre uguali?

Se invece degli analogRead() a vuoto metto un delay(10) i valori diventano instabili come all'inizio.

p.s. non ho collegato più nessun interruttore.

p.p.s.
La prima volta che si usa l'ADC è bene fare una lettura a vuoto per calibrare il circuito S&H interno. Questo vale anche nel caso di ADC spento per motivi di sleep o altro.
Intendi una lettura a vuoto all'inizio di tutto e poi basta o ogni volta prima di leggere da un pin analogico?
Perchè se metto una lettura a vuoto in setup() non funziona l'lcd.
edit: forse non si era resettato bene l'lcd smiley-wink ho riprovato e funziona ma i valori sono instabili come all'inizio.
« Last Edit: December 13, 2012, 02:51:56 pm by d407336 » Logged

Selvazzano Dentro - Padova
Offline Offline
Edison Member
*
Karma: 37
Posts: 1310
"Chi sa fa, chi non sa insegna"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Non vedo nel setup l'assegnazione degli ingressi analogici.

Se non lo fai, è normale che tu debba effettuare una "lettura a vuoto", poiché con essa Arduino capisce che quell'ingresso è di input.
Logged

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

Non vedo nel setup l'assegnazione degli ingressi analogici.

Se non lo fai, è normale che tu debba effettuare una "lettura a vuoto", poiché con essa Arduino capisce che quell'ingresso è di input.
Se si usano i pin analogici come ingressi appunto analogici, non è necessario dichiarare i pin come input usando pinMode dato che questo controlla l'ingresso digitale del pin e non l'ADC, che viene agganciato al pin in oggetto dalla funzione analogRead.
Logged


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

@d407376:
esiste una modalità di lettura, descritta nel datasheet, detta "Free Running Mode", in cui si possono eseguire più letture una dietro l'altra. Se però in questa modalità si cambia canale (cioè pin letto), la prima lettura dopo il cambio di canale rispecchierà il canale precedente e solo quella successiva sarà riferita al nuovo canale.
Ora, analizzando l'analogRead dell'Arduino mi pare che sia impostata proprio questa modalità per cui il problema riscontrato potrebbe essere dato da questo. Quindi la lettura a vuoto per ricalibrare l'ADC è necessaria affinché esso cambi canale correttamente.
Logged


0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

pinMode per i pin analogici sò che non va usato, come ha detto leo.

@d407376:
esiste una modalità di lettura, descritta nel datasheet, detta "Free Running Mode", in cui si possono eseguire più letture una dietro l'altra. Se però in questa modalità si cambia canale (cioè pin letto), la prima lettura dopo il cambio di canale rispecchierà il canale precedente e solo quella successiva sarà riferita al nuovo canale.
Ora, analizzando l'analogRead dell'Arduino mi pare che sia impostata proprio questa modalità per cui il problema riscontrato potrebbe essere dato da questo. Quindi la lettura a vuoto per ricalibrare l'ADC è necessaria affinché esso cambi canale correttamente.
Grazie, ho capito il perchè smiley-wink
Mettendo un analogRead() a vuoto prima non è un grand problema, ma se si volesse mettere non in free running sarebbe possibile?
Questa modalità riguarda proprio l'altmega o come è scritta la funzione?
Logged

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

se si volesse mettere non in free running sarebbe possibile?
Questa modalità riguarda proprio l'altmega o come è scritta la funzione?
La risposta semplice è no. Devi cambiare il core dell'Arduino ed ovviamente poi tutto quello che fa uso dell'analogRead non funzionerebbe più per come era stato inizialmente pensato per cui lascia perdere.  smiley-wink
Logged


0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok
un'altra cosa, se all'interno del programma metto analogReference(INTERNAL) per leggere da un pin, poi rimetto analogReference(DEFAULT) per leggere da un altro pin e lo faccio in continuazione non ci sono problemi?
Logged

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

ok
un'altra cosa, se all'interno del programma metto analogReference(INTERNAL) per leggere da un pin, poi rimetto analogReference(DEFAULT) per leggere da un altro pin e lo faccio in continuazione non ci sono problemi?
Non collegare nulla al pin AREF, però.
Logged


0
Offline Offline
Full Member
***
Karma: 0
Posts: 111
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

no, non collego niente smiley-wink
chiedevo solo per sapere se fare continuamente queste operazione è troppo "stressante" per l'atmega
Logged

Selvazzano Dentro - Padova
Offline Offline
Edison Member
*
Karma: 37
Posts: 1310
"Chi sa fa, chi non sa insegna"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ha ragione Leo quando dice che non è indispensabile usare il pinmode per gli ingressi analogici, ma io lo uso lo stesso per attivare o disattivare il resistore interno.
Logged

Pages: [1] 2   Go Up
Jump to: