# Reading a varying voltage into Arduino

Using an Arduino Nano and a current transformer (CT), I'm trying to sense the current flowing through a 120 V 60 Hz line.

Circuit

CT outputs `0-1&nbsp;V` according to its specifications. This output is biased `AREF/2` = 2.5 V. `analogRead` Values

The x-axis represents the index number of the ADC sample, while the y-axis represent the ADC value (0-1024). Sampling rate is about 9 kHz. Peak-to-peak difference is about 1026 samples. Is this waveform what you would expect from the CT? Why are there regions where the values are flat, rather than varying continuously?

Furthermore, if we look at the curve part of the plot, why is Arduino reading values both above `512` and below `512` alternately? It reads a value above `512`, then a value below `512`, then a value above `512` and so on.

Time taken for an `analogRead` was measured to be 110 microseconds for my setup and there are 1026 samples between the waveform peaks. That means there will be about 9 peaks in 1 second, although I would expect 60 peaks since we are sensing a 60 Hz line. What do you make out of this? There's a capacitor, `C1`, in the circuit, would it have anything to do with this?

Are these analogRead values suitable to be used to calculate the RMS voltage, and hence the RMS current passing through the wire being sensed? The final goal of this is to calculate the power usage after determining the RMS current flowing through the wire.

Sketch used to get values for plot

``````void setup() {
Serial.begin(9600);
}

void loop() {
Serial.println(sensorValue)
}
``````

Actual `analogRead` data points in the bump regions

``````487
534
487
535
488
537
484
536
487
538
486
536
484
540
484
539
485
540
483
540
484
541
481
539
481
540
484
540
480
543
484
539
481
540
484
541
486
542
485
538
485
538
488
535
489
534
491
530
491
529
493
531
492
526
498
526
499
524
499
520
503
518
502
518
507
``````

The analogRead values are now stored in a buffer before being transmitted over Serial. There are now 55 ADC datapoints making up 1 period. Considering the analogRead time is 110 µs, each cycle takes 6.05 ms, giving us a frequency of 165 Hz! What may have gone wrong? ``````void loop() {
char buf;

dtostrf(sensorValue, 8, 2, buf);
value = buf;

if (stop == 0) {
if (i < 10000) {
message += ',';
message += value;
i++;
}
else {
stop = 1;
Serial.println(message);
}
}
}
``````
• Can you post your code? This doesn't look right at all. When you say "Assuming that 100ms passes", why do we assume that? Mar 22, 2014 at 21:12
• @Cybergibbons Posted the code used to generate values for the plot. Sorry, I've just measured the time taken for an `analogRead()` and found it to be 110 microseconds. Updated the question. Mar 22, 2014 at 21:23
• What is the load you are using for the mains. Ideally you want something fairly stable like an incandescent bulb. If you have something complex like a laptop switchmode power supply which may have a varying load you might expect a complex result. Mar 22, 2014 at 21:40
• The bulk of the time in the loop will be spent sending serial at 9600bps. You will only shift 960 char/s i.e. each reading takes 4ms. Mar 22, 2014 at 21:41
• @Salixalba The load is a desktop computer with a switching power supply. I will try measuring a different load, such as a heater. Mar 22, 2014 at 21:42

Regarding your measurements, I would completely disregard the first set with Serial.println() in the loop. I would exepect the timing of this to be unreliable.

Your second set of data that you captured in a buffer looks correct, but your Frequency Estimation / timing may be wrong. I would invert a Digital Output at each loop iteration. You can measure the frequency of that with a Multimeter and your ADC sample rate would be twice that value.

For a PC or laptop power supply that's quite a common current waveform.

Without effective Power Factor Correction the current signal shown below would be quite typical (source: http://www.nlvocables.com/blog/?p=300) You will need to calculate RMS values and it would be wise to filter the signal.

Here's an instructable I wrote on how to build and code an Arduino Yun based Electricity Monitor with Cloud Support / Temboo and Google Drive. It should be of some help to you.

• Thank you! The CT you've used outputs -1V to 1V. To make use of the 10 bit ADC, will you amplify the SCT output by 2.5 using an opamp? Or set your AREF to 2V and bias your CT signal by 1V Mar 23, 2014 at 17:33
• No I did not amplify it or change the Aref. Mar 23, 2014 at 23:55
• How could you get this graph plot? With what software? Apr 15, 2014 at 5:59

if you are measuring a resistive load I would say that the burden resistor you have chosen is wrong, there are some cheap CT's on ebay (SCT-013-xxx) that have versions with and without the burden resistors, these work well for their price but you must read the datasheet. the SCT-013-000 requires a 20R resistor to get 1V out with a 100A load, if this resistor is wrong you can get a severely distorted waveform when measuring higher currents (similar to those you have provided), you would expect the signal to distort more the lower the burden resistor value but this is not the case with CT's.