Problem with CT sensor on Arduino - without load already 1240 Watts

Hello everyone!

I built the little DC bias adapter with burden resistor board to interface a CT current sensor to an Arduino. When I dont connect the CT sensor at all I can see I have VCC/2 on the Arduino input pin like I expect.

But when I now run the emon library current only sketch to read the wattage values, I see some (to me) unexpected values. I read at a 10 seconds interval:
9396
2484
1315
1241
1238
1240
and so on (settling at around 1240)

Shouldnt this rather be around 0? When I connect the CT sensor, I get likewise results - always too high. Of course I could simply subtract 1240 or so from the result, but obviously there is something wrong here and maybe you have a better idea to fix this?!

I think I already found the problem:

For another sensor on that Arduino I use the analogReference(INTERNAL) - and if I use an analogReference(DEFAULT) before the emon function, then my wattage values will be near 0 with no load attached…great! :slight_smile:

You may already know this, but in case not… if you plan to switch analog references on the fly, you need to be aware that pretty much every Arduino has a 0.1uF decoupling cap on AREF as recommended by Atmel. The 1.1V bandgap source (or sink in this case) is very high impedance, so when you switch from DEFAULT back to INTERNAL to read your other sensor, it’ll take quite a while (> 5 msecs on an Uno I just tested) to drain that cap back down to 1.1V. So the first 50 or so readings you make after selecting INTERNAL will be unstable. The exact time and number of readings probably varies from part to part.

This simple program demonstrates the problem:

void setup()
{
  Serial.begin(115200);
  Serial.println("AnalogIN test alive");
}

void loop() {
  uint16_t reading[60];
  byte i;

  while (1) {
    analogReference(DEFAULT);
    analogRead(0);

    analogReference(INTERNAL);
    for (i=0; i < 60; i++)
      reading[i] = analogRead(1);
    for (i=0; i<60; i++) {
      Serial.print(i);
      Serial.print(", ");
      Serial.println(reading[i]);
    }

    delay(1000);
  }
} 

With a steady low impedance 0.464V source being fed into A1, and the internal 1.1V bandgap selected, the conversion wanted to output 435. You can see in this plot of the output that it took about 50 samples to get there:

And this scope trace of the AREF pin shows why:

You can see the selection of the 5V reference happens pretty much immediately, but then when the 1.1V reference is selected it takes quite a while to get there.

Adding a delay after calling analogReference(INTERNAL) won’t help because analogReference() doesn’t actually do anything to the ADC, it simply stores which reference is to be used and that gets loaded into the ADC register next time analogRead() is called.

Thank you for the detailed comment, dBC!

You’re right, I noticed the problem of inaccurate readings after switching as well and fortunately this has been a common problem and solutions are usually suggested…for me I do an analogread() after switching the reference and then delay() a little to then carry on with actual reads.

Happy weekend!