I've been trying to get temperatures using a simple 10k NTC thermistor and voltage divider circuit on the Oak's A0 pin, i.e.

Where R1 is a 10k, 1% metal film resistor, measures exactly 10.0k, and R2 is my thermistor.
Simple, right?
Only I've noticed the analogRead values were off.
I don't think it's the code, but here it is:
void setup() {
Particle.begin();
}
void loop() {
Particle.print(getTemp());
delay(1000);
}
float getTemp() {
return analogRead(A0);
//subsequent processing omitted for simplicity's sake
}Somewhere I had read that the Oak's A0 pin maxed out at 1V and wondered if that had anything to do with it. (See
https://github.com/digistump/OakCore/blob/master/doc/reference.md; I've seen it quoted elsewhere for the ESP8266, but not in any official documentation. I've looked.)
Turns out this is not true - using a 10k resistor for R2 should evenly split the voltage drop from VCC to A0 (measured at exactly 3.33V on my Oak). IF the A0 pin maxed out at 1V, applying 1.67V here should result in a max reading of 1023 (or 1024, depending on the ESP's design - turns out to be 1024 for values above max voltage). Actual analogRead() value - 528. More than the 512 we should get, but close.
The question then: is it predictably close, and can I adjust for it?
Using various known-good resistors I got the following:
| R1 | R2 | predicted voltage drop at R1 | predicted voltage at VA0 | predicted % voltage drop at R2 | predicted analogRead | actual analogRead | delta | notes | | 10000 | 220 | 3.258 | 0.072 | 97.8% | 22 | 0 | -2.2% | | 470 | 3.181 | 0.149 | 95.5% | 46 | 38 | -0.7% | | 10000 | 1.665 | 1.665 | 50.8% | 512 | 528 | 1.6% | | 606000 | 0.054 | 3.276 | 98.4% | 1006 | 1023 | 1.6% | *measured voltage 3.18V at A0
| | | | 47000 | 10000 | 2.746 | 0.584 | 17.5% | 179 | 175 | -0.4% | | 47000 | 1.665 | 1.665 | 50.0% | 512 | 494 | -1.8% | | 220000 | 0.586 | 2.744 | 82.4% | 843 | 790 | -5.2% | | 1000000 | 0.149 | 3.181 | 95.5% | 977 | 904 | -7.1% | | | | 220000 | 10000 | 3.185 | 0.145 | 4.3% | 44 | 33 | -1.1% | | 47000 | 2.744 | 0.586 | 17.6% | 180 | 162 | -1.8% | | 220000 | 1.665 | 1.665 | 50.0% | 512 | 396 | -11.3% | | 1000000 | 0.600 | 2.730 | 82.0% | 839 | 560 | -27.2% | | 3000000 | 0.228 | 3.102 | 93.2% | 953 | 610 | -33.5% |
|
As you can see, the variance from expected goes from minimal to large, and not in a fashion I can predict.
The Oak puts a 220-ohm resistor between the A0 pin and the ESP8266's ADC input (schematic at
https://s3.amazonaws.com/digistump-resources/files/6666015f_oak-prod-v1.pdf, and while I would expect that would alter (i.e. drop) the measured voltage slightly, I don't think it should have such an effect.
Anyone have any ideas? Have I missed something?
Give up on A0?
Interim solutions: run an ADS1015 or ADS1115 ADC board off I2C - you get four analog channels per board, can run up to four boards, and you get higher (12- or 16-bit) precision. Or use another temperature sensor; I'll be using the digital TMP102. With the Oak's limited number of pins, I've become very fond of I2C.