I am having a hard time understanding why I can't read one analog pin's output with another analog pin. The docs state to put a delay in between, which I've done (I've tried up to one second with the same results). I've got this minimized code:
void setup() {
Serial.begin(9600);
pinMode(A0, INPUT);
pinMode(A5, OUTPUT);
}
void loop() {
for (int i=0; i<1024; i++){
analogWrite(A5, i);
delay(100);
Serial.println(analogRead(A0));
}
Serial.println("done");
delay(10000);
}
When it starts, it displays 6-9 for a few dozen iterations, then suddenly jumps to ~1018 and remains throughout the rest of the run.
A5
is connected directly to A0
via a 4" jumper cable. Nothing is connected to AREF
. If I connect AREF
to 5v, the output does not change but by a single digit. If I connect it to ground, it immediately outputs 1023
.
I'm hoping this is a "do'h" moment here. Can someone please let me know what I'm not doing correctly?
Update: This is a legit Arduino Uno R3 board. When I connect A0
directly to 5v+, I get 1023
as expected as the output.
-
I do realize that PWM has a max value of 255, but updating the sketch changes nothing; the result is the same.stevieb– stevieb07/22/2017 01:13:26Commented Jul 22, 2017 at 1:13
-
1This page show several Arduino Capacitance Meters (circuitbasics.com/how-to-make-an-arduino-capacitance-meter). The last one (Capacitance Meter for 470 uF to 18 pF Capacitors) use two analog pins for charging/reading voltages. It may be useful in your project.user31481– user3148107/22/2017 08:31:19Commented Jul 22, 2017 at 8:31
3 Answers 3
For a start, A5 is not a valid pin to do analogWrite to. On a Uno they are marked with the "~" symbol, and are pins: 3, 5, 6, 9, 10, 11.
Thus the code will treat it as a digitalWrite, and will write LOW up to 127 and HIGH after that. From the code in wiring_analog.c:
case NOT_ON_TIMER:
default:
if (val < 128) {
digitalWrite(pin, LOW);
} else {
digitalWrite(pin, HIGH);
}
You are then just reading back (close to) 0 or 1023.
Second, PWM output is not what you can read back using analogRead. An analogRead reads a voltage level, whereas PWM output is just 0s and 1s interleaved at the PWM frequency, and with a width of the duty cycle.
See https://www.arduino.cc/en/Reference/AnalogWrite, in particular:
The analogWrite function has nothing to do with the analog pins or the analogRead function.
Third, writing 1023 to analogWrite is out of range. See the documentation from the page linked above:
Parameters
pin: the pin to write to.
value: the duty cycle: between 0 (always off) and 255 (always on).
You can see that the most you can write is 255 (not 1023).
References
More information about the ADC (analogRead) at my page about the ADC converter.
More information about PWM output at my page about timers.
-
This is a fantastic piece of feedback, and I realize that I need to do further research and testing. There has been an obvious disconnect between my understanding, and what's actually realistic. Thanks for this... after glancing at the board and with the understanding I have, it has put me in the proper direction of where to look and what to do.stevieb– stevieb07/22/2017 03:00:00Commented Jul 22, 2017 at 3:00
-
I'm accepting this answer not because I've tested it, but because it is thorough and makes sense. I'm confident it'll prove true :)stevieb– stevieb07/22/2017 03:01:50Commented Jul 22, 2017 at 3:01
-
I have to admit that I did not understand that
A'n'
pins were not necessarilyanalogWrite()
capable. I totally overlooked that in everything I've done. It explains quite a bit. I think my Arduino experience will be much nicer moving forward with this new comprehension.stevieb– stevieb07/22/2017 03:08:42Commented Jul 22, 2017 at 3:08 -
1
analogRead
andanalogWrite
are confusingly named as they are not symmetrical. A better name foranalogWrite
might have beenPWMwrite
.07/22/2017 03:12:35Commented Jul 22, 2017 at 3:12 -
...that would have made one think, at minimum. Thanks Nick.stevieb– stevieb07/22/2017 03:13:37Commented Jul 22, 2017 at 3:13
Can someone please let me know what I'm not doing correctly?
the analog (output) pins on those chips are not exactly analog: they are pwm output pins. as such, their output is either 0 or 1, nothing in between, with the chance of being 1 equal the duty cycle.
that kind of output can be a steady "analog" if you run it through a low pass filter - the simplest would be an rc filter where the r is in serial with the c.
so if you hook th epwm pin up to a rc filter and adc the output of that rc filter, you will get a real "analog".
Your program is correct and I suspect the error is in the hardware. Arduino uses its internal timer and creates a high frequency PWM on the corresponding pin upon a analogueWrite()
is called. Here what we should notice is the DC switching in the appropriate pin is not noticeable in most cases. (If you give it to an LED you can adjust its brightness).
But what you have done now is not correct. Since there is no current flowing in the pin there will not be a analogue voltage actuality. It is 5V and 0V switching in a high frequency. Those are the values which the A0
pin will see.
So try fixing a capacitor between the pin and the ground. and a 1k resistor to create a slight current flow to stabilize the voltage. then let us know your readings.
schematic
simulate this circuit – Schematic created using CircuitLab
-
Thanks for this, but I believe the answer that states that I was incorrectly assuming that the
A'N'
pins wereanalogWrite()
capable is correct. I definitely know I had current flow without need of a resistor, capacitor or other intermediaries. I made bold mis-assumptions as to what pins can do what.stevieb– stevieb07/22/2017 03:11:51Commented Jul 22, 2017 at 3:11 -
This answer completely misses the issue. No, you do not need the pin to source current in order to have a well defined voltage. And your 1 µF capacitor can damage the output pin due to the inrush current.Edgar Bonet– Edgar Bonet07/22/2017 12:00:32Commented Jul 22, 2017 at 12:00
-
@EdgarBonet Srry, it should be .1uf. So do you mean to use
analogueRead()
and read a PWM value insted of a real analogue voltage between 0v and 5v.danial weaber– danial weaber07/22/2017 12:09:51Commented Jul 22, 2017 at 12:09 -
You wrote: "do you mean to use
analogueRead()
and read a PWM value [...]". No, I mean what I wrote, nothing more.Edgar Bonet– Edgar Bonet07/22/2017 13:15:08Commented Jul 22, 2017 at 13:15