I write below code, in order to discharge one of analog pin, but it does not work, example,
const int pin1 = A0;
oid setup() {
pinMode(pin1, OUTPUT);
digitalWrite(pin1, LOW); -> discharge the voltage
analogReadResolution(12); //default is 10 bit, for Due can go 12 bit
Serial.begin(115200);
}
void loop() {
delay (100);
pinMode(pin1, INPUT);
delay (10);
int val1 = analogRead(pin1);
delay (10);
int val2 = analogRead(pin1);
delay (10);
int val3 = analogRead(pin1);
delay (10);
int val4 = analogRead(pin1);
delay (10);
int val5 = analogRead(pin1);
...
}
The output for reading is expected to be 0, however, below is the output,
va11=182
val2=224
val3=265
val4=299
val5=329
You don't understand the Due architecture - a pin can either be a digital IO pin
or it can be connected to a peripheral (such as ADC, PWM, etc).
Thus the code that implements analogRead() remaps the pin to the ADC, at
which point it becomes floating and picks up charge from the analog
multiplexer.
If you add 1nF capacitor or so on the pin you'll see it holding voltage much better.
MarkT:
You don't understand the Due architecture - a pin can either be a digital IO pin
or it can be connected to a peripheral (such as ADC, PWM, etc).
Thus the code that implements analogRead() remaps the pin to the ADC, at
which point it becomes floating and picks up charge from the analog
multiplexer.
If you add 1nF capacitor or so on the pin you'll see it holding voltage much better.
Its a fundamental issue, you can't read any reliable value on the ADC if you don't drive it
with a low impedance source (< 10k is recommended, < 1k is best).
You could try this sequence.
digitalWrite (pinA, LOW) ; // drive pin to ground
analogRead (pinB) ; // precharge ADC's input cap to 0V, hopefully
val = analogRead (pinA) ; // connect A to ADC and read voltage.
Where pin B has a 1k resistor to ground.
But note that the act of taking a reading on the ADC will change the charge on the cap
as its multistage flash ADC I've no idea what exactly will happen.
MarkT:
Its a fundamental issue, you can't read any reliable value on the ADC if you don't drive it
with a low impedance source (< 10k is recommended, < 1k is best).
You could try this sequence.
digitalWrite (pinA, LOW) ; // drive pin to ground
analogRead (pinB) ; // precharge ADC's input cap to 0V, hopefully
val = analogRead (pinA) ; // connect A to ADC and read voltage.
Where pin B has a 1k resistor to ground.
But note that the act of taking a reading on the ADC will change the charge on the cap
as its multistage flash ADC I've no idea what exactly will happen.
Hi Mark, thank you, I'll try it and see how. Another questions, do you know how much time it takes when pin A switch from digital output to analog input?
It happens in two stages I think - recofigure the pin to ADC peripheral, then configure
the multiplexer in the ADC to route that pin to the ADC. Probably a few us at most.
You've got the code too, maybe you could look at it, don't be scared!!
[ Having done so myself I think its more complex. The ADC is input only so doesn't
have to reconfigure the pin at all.
However analogRead() first enables the ADC itself (which I think is an
idempotent operation, may take longer the first time). Then the relevant channel
is enabled for that pin, then a conversion is started. The conversion scans
each enabled channel (should only be one) switching the multiplexer as
necessary - this is when the pin gets charge from the ADC capacitor.