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:

The nRF51822-mKIT is a low cost ARM mbed enabled development board for Bluetooth® Smart designs with the nRF51822 SoC. The kit gives access to all GPIO pins via pin headers …

2 Answers

9 years, 11 months ago.

Hi Wayne

The source for the Nordic AnalogIn functionality is here

http://mbed.org/users/mbed_official/code/mbed-src/file/cb4253f91ada/targets/hal/TARGET_NORDIC/TARGET_NRF51822/analogin_api.c

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

Accepted Answer

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 Martin Kojtal 26 May 2014

Hello,

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 Martin Kojtal 27 May 2014

Thanks 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
posted by Wayne Keenan 27 May 2014
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
posted by Wayne Keenan 23 May 2014