Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years, 11 months ago.
ADC readings on separate channels 'leak'
Hello,
I've been using mbed for about a day and could do with some help please.
I have 2x TEMP6000 light sensors that need to be connected to 2 analog pins.
If I only connect one sensor and only read for one pin I get 'sensible readings'. If I connect two sensors and read two analog readings I get a very similar reading for both pins, even if one is 'in darkness' and the other is 'in light'. If I only connect one sensor and perform readings fro two different pins the 'leak' appears. Both sensors work if connected individually when only reading one analog pin.
My initial thinking was that this is similar to a problem on the Arduino where there is only one ADC so the analog inputs are multiplexed and for that platform a 'simple' solution (depending on performance requirements) is to delay 'some time' (say 100ms) before reading from different pins.
However simply adding a 'wait' (varying from 0.1s to 1.0s) on mbed appears to make no difference; in my application on mbed I need to avoid any lengthy 'artificial' delays, if I can.
I have included the code below as there's probably a very a n00b-ish mistake.
Wiring temt6000 breakout: VCC(to VCC=3.3V), GND(to GND), SIG(to P0_1) temt6000 breakout: VCC(to VCC=3.3V), GND(to GND), SIG(to P0_2)
Serial pc(USBTX, USBRX);
AnalogIn s1Sensor(p1); AnalogIn s2Sensor(p2);
int main() { for(;;) {
float s1 = s1Sensor; float s2 = s2Sensor;
pc.printf("%f - %f\n", s1,s2); wait(0.1f); } }
Thanks Wayne
Question relating to:
2 Answers
9 years, 11 months ago.
Hi Wayne
The source for the Nordic AnalogIn functionality is here
and the mbed API code is here:
http://mbed.org/users/mbed_official/code/mbed-src/file/fb8edfff6ae1/api/AnalogIn.h
It looks like the code for Nordic microcontrollers sets the channel globally when you create the AnalogIn object, but does not change channel when you call the read() function. Therefore when you call read(), you get the value of the most recent AnalogIn pin that you created. I think this is a bug you could raise through the appropriate channel. If you look at the code for NXP microcontrollers, it does the channel change in the ADC read() function. For example here: http://mbed.org/users/mbed_official/code/mbed-src/file/fb8edfff6ae1/targets/hal/TARGET_NXP/TARGET_LPC11U6X/analogin_api.c
Best wishes
Alex
Thanks Alex, it looks like there's a bug.. ADC_CONFIG_PSEL_Pos should be set for each reading. I will look at it.
posted by 26 May 2014Hello,
I fixed the issue, #333 pull request on github mbed sources, will be fixed in the next mbed lib revision ;) Thx Wayne Keenan for reporting.
posted by 27 May 2014Thanks for taking the time to look Alex.
I have 2 workarounds:
#if 1 #define ADC_PIN_1 4 #define ADC_PIN_3 16 AnalogIn s1Sensor(P0_1); AnalogIn s2Sensor(P0_3); int main() { pc.baud(115200); pc.printf("Start\n"); for(;;) { NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling<< ADC_CONFIG_INPSEL_Pos) | (ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling << ADC_CONFIG_REFSEL_Pos) | (ADC_PIN_1 << ADC_CONFIG_PSEL_Pos) | (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); s1 = s1Sensor.read(); NRF_ADC->CONFIG = (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) | (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling<< ADC_CONFIG_INPSEL_Pos) | (ADC_CONFIG_REFSEL_SupplyOneThirdPrescaling << ADC_CONFIG_REFSEL_Pos) | (ADC_PIN_3 << ADC_CONFIG_PSEL_Pos) | (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos); s2 = s2Sensor.read(); pc.printf("%f - %f\n", s1,s2); } } #else int main() { pc.baud(115200); pc.printf("Start\n"); for(;;) { AnalogIn s1Sensor(P0_1); s1 = s1Sensor.read(); AnalogIn s2Sensor(P0_3); s2 = s2Sensor.read(); pc.printf("%f - %f\n", s1,s2); } } #endif
9 years, 11 months ago.
I had similar problem with PIC
my solution
read ADC 1, bin result read ADC 1, use result read ADC 2 bin result short delay.. read ADC 2 use result.
... my code read 10 ADC
...
read ADC 1 ignore..
..
main CODE (100 - 500mS)
last line, is to select ADC 1 ready for next time.
Ceri
I had tried binning values and large delays, and still it seems the sensors readings are not independent:
#include "mbed.h" // Wiring // temt6000 breakout: VCC(to VCC=3.3V), GND(to GND), SIG(to P0_1) // temt6000 breakout: VCC(to VCC=3.3V), GND(to GND), SIG(to P0_2) Serial pc(USBTX, USBRX); AnalogIn s1Sensor(P0_1); AnalogIn s2Sensor(P0_3); volatile float s1; volatile float s2; int main() { pc.printf("Start\n"); for(;;) { wait(1.0f); s1 = s1Sensor.read(); wait(0.5f); s1 = s1Sensor.read(); wait(0.5f); s1 = s1Sensor.read(); wait(0.5f); wait(1.0f); s2 = s2Sensor.read(); wait(0.5f); s2 = s2Sensor.read(); wait(0.5f); s2 = s2Sensor.read(); wait(0.5f); pc.printf("%f - %f\n", s1,s2); } }
Output (whilst I was covering and/or disconnecting one or the other sensor, hence the 'patches' of variations before the values settle to be the similar values):
0.006843 - 0.006843 0.006843 - 0.006843 0.008798 - 0.008798 0.010753 - 0.010753 0.010753 - 0.001955 0.003910 - 0.002933 0.003910 - 0.003910 0.004888 - 0.004888 0.006843 - 0.005865 0.007820 - 0.004888 0.011730 - 0.010753 0.010753 - 0.011730 0.011730 - 0.011730 0.011730 - 0.011730 0.010753 - 0.010753 0.010753 - 0.010753 0.010753 - 0.010753 0.010753 - 0.009775 0.009775 - 0.009775 0.009775 - 0.009775 0.009775 - 0.009775 0.010753 - 0.010753 0.009775 - 0.010753 0.019550 - 0.025415 0.010753 - 0.009775 0.177908 - 0.179863 0.178886 - 0.179863 0.177908 - 0.176931 0.176931 - 0.010753 0.009775 - 0.009775 0.012708 - 0.011730 0.010753 - 0.010753 0.010753 - 0.010753 0.010753 - 0.010753