Reply
Posts: 35
Registered: ‎06-28-2017

BB2: Changing ADC Gain On The Fly

Greetings good people,

 

We have an issue where the first reading in a series is higher than subsequent readings.  We're reading several sensors, then a few internal channels (including temperature and Vdd), then pausing and starting again.

 

The application currently uses the EFM8BB2, but is also targeted at the BB1 when we get the code settled in.  It's an autonomous, custom, battery powered device, but we've been using Busy-Bee kits for initial development.

 

The most critical part of the project is measuring fairly low-level signals as accurately as possible. To help with this, we've set the ADC gain to 1 (of course).

 

However, we also need to keep track of battery voltage.  Naturally, this needs an ADC gain of 0.5 (because we don't have enough I/O available to use a resistor divider, and the project is very cost-sensitive).

 

This SiLabs Knowledge Base Article says "The ADC0 gain setting must be configured prior to any other ADC initializations in order for it to be configured properly."  However, it doesn't state what "properly" means, nor what the critical steps are that it must precede: For example, can we get away with simply disabling and re-enabling the ADC around the gain change?

 

This SiLabs Knowledge Base article says nothing about when the gain can or should be set or changed.

 

What we've found is that the ADC seems to respond correctly if the gain is changed on the fly (that is, between readings).  Just in case, I've added an ADC disable/enable pair around the gain change, but it doesn't seem to have changed the behaviour.

 

I've attached the workflow code (which runs the testing we're doing), as well as my ADC driver code.  The workflow code is currently executed every 100us.  (In this case, I should say that the "BasicTimerHit()" function is redundant, because the flag it reports is set in the 100us interrupt.)  

 

Any comments people might have on why the first voltage read in a cycle is higher than subsequent values would be appreciated.

 

Regards,

 

Geoff

Posts: 35
Registered: ‎06-28-2017

Re: BB2: Changing ADC Gain On The Fly

I should add to the above that the Vdd read doesn't seem to be the critical issue here.  I'm not fully discounting it though.

 

Those who bother to examine the code will note that it does two runs: A "light" run with the LEDs lit one at a time, and a "dark" run with no LED activation.  It only reads the extra values (temperature, Vdd, etc) when the LEDs are on.

However, the first values of both parts of the cycle are still notably higher than the rest.  If we swap channels, it's still the first value read that is high: We think we've eliminated hardware variations.

Posts: 35
Registered: ‎06-28-2017

Re: BB2: Changing ADC Gain On The Fly

Here's something interesting: I added a dummy read of the GND channel before taking the first "real" reading.  Basically, I added a couple of states before the LED_ON_DELAY state to start an ADC reading and then to read it and throw it away.

        if (START_STATE == sWorkflowData.m_state)           /* Start state */
        {
            /* Kick off a dummy read of the GND channel */
            ADC_START(ADC_CHAN_GND);

            /* Next state */
            sWorkflowData.m_state = DUMMY_READ;
        }
        else if (DUMMY_READ == sWorkflowData.m_state)       /* Dummy read of ground channel before starting the real measurement */
        {
            /* If the ADC read is complete, move on to the first measurement */
            if (AdcRead() < MAX_ADC_VALUE)
            {
                sWorkflowData.m_state = LED_ON_DELAY;
            }
        }

The very first set of readings ALL changed: The first "light" reading was still high (but no longer consistently so).  Some of the other "light" readings were also different on the first cycle only.  The first "dark" reading was consistently high, but not as much as when the dummy read was not present.

 

Next step: Change the dummy read to the first channel.

Posts: 35
Registered: ‎06-28-2017

Re: BB2: Changing ADC Gain On The Fly

Changing the dummy read to use the first channel actually made things more unstable.

Commenting out the Vdd read and the associated gain changes improved the stability, but didn't fix the problem.

 

What did seem to result in better stability was waiting about 6 seconds from reset before starting the read cycles.

 

Would there be some sort of stability issues with this ADC hardware?

Posts: 35
Registered: ‎06-28-2017

Re: BB2: Changing ADC Gain On The Fly

Here's a sample set of readings:

Tested the 0.2.41 version

ReadyCDP(Abs)v0.2.41          
Light40ms  Dark40ms  VddTBG1fbTSTfbt(ms)Run
Sensor1Sensor2Sensor3Sensor4Sensor1Sensor2Sensor3Sensor4     
211120532246183696171818247413483269326914990
209120432237183196181818247213503270327025431
209220452238183295181818247213493271326934012
209020462237183396171818247313503273327041483
209020462238183396181718247113503270327049424
209020452237183296181718247013483271327056485
209020452237183296181818247213493270327063706

 The highlighted readings are a lot higher than they should be. You can also see that the first readings on sensors 2 and 3 are also a little high.

Posts: 344
Registered: ‎09-22-2009

Re: BB2: Changing ADC Gain On The Fly

Do you have proper decoupling caps on the chip? Can you share your schematic?

 

If you run the BB2 ADC software example, do you see the same thing happen? I ran it on a BB2 dev kit just now and wasn't able to see the first sample be any different than the rest.

Posts: 35
Registered: ‎06-28-2017

Re: BB2: Changing ADC Gain On The Fly

Thanks for the response Alan,

 

I've attached a snapshot from the schematic. As you can see, each of the ADC inputs feeds into a 1nF capacitor, and the chip's power supply has a 1uF and a 0.1uF cap across its Vdd/GND lines.  Our Electronics Engineer has consulted SiLabs' guidelines before laying it out, too.

 

I'll see if I can adapt the example code to our specific hardware configuration.

 

Note that we turn on an LED for 3ms with the Sense line set to Open Drain and pulled low, then allow the Sense line to go high for 40ms before starting the ADC.

 

Our observations are that, without the Vdd read, the first read matches the others if we wait for at least 3 seconds from startup.  Otherwise, we get oscillations.

 

Regards,

 

Geoff

Highlighted
Posts: 35
Registered: ‎06-28-2017

Re: BB2: Changing ADC Gain On The Fly

I've started a new topic here, because I think the gain change is just one of the issues we're having.

One of our other issues seems to possibly be related to the settling time of the ADC, particularly when reading a small signal after reading a larger signal.  However, reading the GND channel before each reading should have corrected that.  It hasn't.  Hence, the other message.