AC Current Monitoring Data Logger





Introduction: AC Current Monitoring Data Logger

About: By day I am an electronic engineer for a certification and approvals company, by night I am an avid technology hobbyist and DIY'er. I enjoy learning how things work, and sharing my learning experiences with ...

Hi Everyone, welcome to my first instructable! By day I am a test engineer for a company that supplies industrial heating equipment, by night I am an avid technology hobbyist and DIY'er. Part of my work involves testing the performance of heaters, on this occasion I wanted to be able to monitor the RMS current draw of 8 devices over 1000hrs and log the data to graph the results later. I have access to a data logger but it was already committed to another project and I needed something low cost, so I decided to cobble together this basic datalogger.

The project uses an Arduino Uno to read analogue sensors via analogue to digital converter (ADC) and records the data with a time stamp on an SD card. There is alot of theory and calculation involved in designing the circuits, so instead of explaining absolutely everything, I will just show you how to make it. If your interested in seeing the FULL hit then let me know in the comments and I will explain further.

Step 1: Current Transformers

This project uses HMCT103C 5A/5MA current transformer. It has a 1:1000 turns ratio meaning for every 5A of current flowing through the conductor, 5mA will flow through the CT. A resistor needs to be connected across the two terminals of the CT to allow a voltage to be measured across it. On this occasion I used a 220 Ohm resistor, therefore using Ohm's law V=IR, the output of the CT will be 1.1 Volts AC, for every 5mA of CT current (or every 5A of measured current). The CT's were soldered to strip board with the resistor and some instrument wire to make flying leads. I terminated the leads with 3.5mm male audio jack plugs.

Here is the datasheet for the current transformer


Step 2: Signal Conditioning

The signal from the CT will be weak so needs to be amplified. For this I soldered together a simple amplifier circuit using a uA741 dual rail op amp. In this case the gain is therefore set to 150 using the formula Rf / Rin (150k / 1k). However the output signal from the amplifier is still AC, the diode on the output of the op-amp cuts off the negative half cycle of the AC and passes the positive voltage to a 0.1uF capacitor to smooth the wave into a rippled DC signal. Below are the parts that make up the circuit:

  • V1 - This is arbitrary in this diagram, it simply represents the signal voltage which is fed into the non-inverting input of the op-amp.
  • R1 - This is known as the feedback resistor (Rf) and is set to 150k
  • R2 - This is known as the input resistor (Rin) and is set to 1k
  • 741 - This is the uA741 intergrated circuit
  • VCC - Positive supply rail +12V
  • VEE - Negative supply rail -12V
  • D1 - Is the haf wave rectifiying signal diode 1N4001
  • C3 - This capactor holds the DC signal for a set time

In picture 2 you can see it was assembled using Veroboard and tinned copper wire. 4 hole were drilled for PCB stand off's so they could be stacked (because there are eight channels there needs to be eight amplifier circuits altogether.

Step 3: Power Supply

If you don't fancy making it from scratch then you can buy the board pre-assembled from China like the one pictured above, but you will still need the 3VA transformer (step down 240V to 12V). The one pictured cost me around £2.50

To power the project I decided to make my own dual rail 12VDC power supply. This was convenient as the op-amps require +12V, 0V, -12V, and the Arduino Uno can accept any supply up to 14 VDC. Below are the parts that make up the circuit:

  • V1 - This represents the supply from the mains socket 240V 50Hz
  • T1 - This is a small 3VA transformer I had lying about. It's important that the transformer has a central tap on the secondary which will be connected to 0V i.e. ground
  • D1 to D4 - This is a full wave bridge rectifier using 1N4007 diodes
  • C1 & C2 - 35V electrolytic capacitors 2200uF (has to be 35V as the potential between positive and negative will reach 30V)
  • U2 - LM7812, is a 12V positive voltage regulator
  • U3 - LM7912, is a 12V negative voltage regulator (be careful to note the pin differences between the 78xx and 79xx IC!)
  • C3 & C4 - 100nF Smoothing capacitors 25V electrolytic
  • C5 & C6 - 10uF ceramic disc capacitors

I soldered the components onto stripboard, and joined the vertical tracks with bare single core tinned copper wire. Picture 3 above shows my DIY power supply, sorry there's alot of jumpers in the photo!

Step 4: Analogue to Digital Converters

The Arduino Uno already has a built in 10-bit ADC, however there are only 6 Analogue inputs. Therefore I opted to use two ADC breakouts with the ADS1115 16-bit. This allows 2^15 = 32767 bits to represent voltage levels from 0-4.096V (4.096V is the breakout's operating voltage), this means every bit represents 0.000125V ! Also, because it uses the I2C bus it means that up to 4 ADC's can be addressed, allowing up to 16 channels to be monitored if desired.

I have tried to illustrate the connections using Fritzing, however due to the limitations there is no custom parts to illustrate a Signal Generator. The purple wire is connected to the output of the amplifier circuit, the black wire next to it illustrates that all amplifier circuits must share common ground. So I have used a breadboard to illustrate how I've made the tie points. However my actual project has the breakouts sitting in female headers, soldered to Veroboard, and all the tie points are soldered onto the veroboard.

Step 5: Microcontroller

As mentioned above the controller I chose was an Arduino Uno, this was a good choice as it has alot of on board and built in functionality that otherwise would of needed to be built seperaturely. Plus it is compatible with alot of specially built 'shields'. On this occasion I required a real time clock to timestamp all the results and an SD card writer to record the results to a .csv or .txt file. Luckily, the Arduino data-logging shield has both in a shield that push fit's onto the original Arduino board without additional soldering. The shield is compatible with the RTClib and SD card libraries so no need for any specialist code.

Step 6: Assembly

I used 5mm ridgid medium/low density PVC (sometimes known as foamboard) to screw down most of my components and cut it to a convenient size with a craft knife. All the components were built in a modular fashion for the prototype as it allows for removal of individual parts if things go wrong, however it isn't as efficient or tidy as an etched PCB (further work) this also means alot of jumper wires between the components.

Step 7: Uploading Code

Upload the code to the Arduino, or get the code from my Github repo

Step 8: Calibration

Theoretically the measured current will be a result of several things combined:

Measured amps = ((( a *0.45)/150)/(1.1/5000))/1000 where 'a' is the signal voltage from the amplifier

0.45 is the rms value of the Vout of the amplifier circuit, 150 is the op-amp gain (Rf/Rin = 150k / 1k), 1.1 is full scale voltage output of the CT when measured amps is 5A, 5000 is simply 5A in mA, and 1000 is the amount of turns in the transformer. This can be simplified to:

Measured amps = ( b * 9.216) / 5406555 where b is ADC reported value

This formula was tested using the Arduino 10-bit ADC and a difference between multimeter values and Arduino generated values was observed by 11% which is an unacceptable deviation. My preferred method for calibration is to record ADC value vs Current on a multimeter in a spreadsheet and plot a third order polynomial. From this the cubic formula can be used to give better results when calcuating measured current:

(ax^3) + (bx^2) + (cx^1) + d

The coefficients a,b,c, and d are calculated in excel from a simple data table, x is your ADC value.

To get the data I used a ceramic 1k variable resistor (rheostat), and 12v transformer to step down the mains AC voltage from 240V, which will gave me generate a variable current source from 13mA to 100mA. The more data points collected the better, however I'd suggest collecting 10 data points to gain an accurate trend. The attached Excel template will calculate the coefficients for you, it's then just a matter of entering them into the arduino code

On line 69 of the code you will see where to enter the coefficients

float chn0 = ((7.30315 * pow(10,-13)) * pow(adc0,3) + (-3.72889 * pow(10,-8) * pow(adc0,2) + (0.003985811 * adc0) + (0.663064521)));

which is the same as the formula in sheet1 of the excel file:

y = 7E-13x3 - 4E-08x2 + 0.004x + 0.663

Where x = adc0 of whatever channel you are calibrating

Step 9: Finish

Put it in a project enclosure. I finished off the power supply with a toggle switch to turn the whole thing on/off at the supply, and an IEC "figure 8" connector for the mains input. Screw it all together and your ready to test it out.

Further work

The whole project was mocked up rather quickly so there is alot of room for improvement, etched circuit, better components. Ideally the whole thing would be etched or soldered onto FR4 rather than loads of jumpers. Like I said earlier there's loads of stuff I haven't mentioned but if there is something specific you would like to know let me know in the comments and I will update the instrucable!

Update 18/12/2016

I have now added a 16x2 LCD using the I2C "backpack" to monitor the first four channels, will be adding another to monitor the last four when it arrives through the post.


This project was made possible by all the authors of the Libraries used in my Arduino sketch including the DS3231 library, Adafruit ADS1015 library and the Arduino SD library



    • Water Contest

      Water Contest
    • Clocks Contest

      Clocks Contest
    • Oil Contest

      Oil Contest

    51 Discussions

    Awesome project. I have been thinking about a system to monitor my homes energy usage. Where is power being wasted, phantom loads and such. There are some on the market, but i haven't been really excited about any of them. Seems like your project could be adapted to such a use. What do you think?

    I use a voltage divider to create a 2.5v centerline for measurement. Those 12bit ADC's also are amplifiers, so your amplifier seems redundant. I'd love to see how you would keep a running ah/wh measurement.

    2 replies

    It's a 16 bit ADC I've used not 12 bit as pictured.

    Hi there. Yes, the ADS1115 has a built in PGA but the max gain is only x16, I needed x150 to get fine resolution over the full 0-5v so not redundant at all. The problem with biasing the AC signal is the swing is half the 5v so half resolution, then you have to write the code to find peak maxima and minima every 20ms. It's easier just to DC couple in and calc RMS for a half wave rectifier.

    I hate to be a critic after the great effort you have made and the trouble you have gone to post your Instructable, but hopefully these criticisms will be constructive.

    The 1k input resistor to the opamp is effectively in parallel with the 220ohm resistor across the CT (as the 1k resistor goes to a virtual ground). It means your effective burden is about 180ohm, not the 220ohm you might think it is. This isn’t a big deal really, but will effect calculations if not considered. Canging your inverting opamp configuration to a non-inverting opamp configuration would get rid of this issue.

    And as someone mentioned, a bleed resistor across the output cap would be a good idea.

    And also as mentioned, you are really only measuring peak. The relationship between peak and rms will vary from equipment to equipment. Even with the mathematical approach you have taken to accurately measure a test current, as soon as you try to measure a non-linear load, your results will be out. You also have a non-linearity introduced by the rectifying diode (its effect on the result varies with input current, but at low levels, you won’t be generating enough voltage to even force it to conduct).

    If you take the AC voltage straight to the Arduino (suitably offset), maybe you could do a true RMS calculation?

    1 reply

    Some very constructive comments thank you. Yes I'm aware of the limitations, for my appplication it's perfect, but for other people it needs refinement including a proper RMS calculation in the Arduino code. I will certainly implement your suggestions in revision 2! :-)

    Fantastic! This will do well for when I need to rewire portions of the house to accommodate new outlets and network infrastructure (among other things).

    I would imagine that with the ethernet interface capabilities of the Arduino, one could create a real-time monitor of sorts using this same apparatus and a rudimentary data-logging API.

    1 reply

    Hi there, thanks for the comment. I tried using a shield which includes a micro SD card and the Wiznet ethernet chip. Unfortunately I found the Wiz a bit of a power hog and there was a number of failed writes to the SD card. Hopefully you'll do better than me and get one to work. Let me know how you get on I'd like to try out an IOT build sometime.


    1 year ago

    Nice real world project smooth_jamie. It's nice to see someone build a multi channel logger measuring AC current to boot. I was a test engineer in part of my working career ( retired now) . AC (line operated appliances) and DC ( battery) measurements were a big part of my job function . wish the arduino and associated family of software and hardware modules were available. My solution was pc board level products that plugged into expansion ports. This project brought back memories, I like the SD card write.BTW. I2C LCD's are super simple to implement and use on the Arduino, I discovered this board on Banggood which might be of interest to you moving forward

    Adafruit sell it as well

    post your reports once you get some data.

    1 reply

    That's a handy breakout, I'll have a play with one. Thank you :-)

    Nicely done! I have decades of time with chalk at the board making crude ( but hands on folks think of as savvy )diagrams, schematics, bad art of the Rube Goldberg theory of education, hoping to inspire my young folk audience ( read that brilliant doers, often seen as the duhhhh kids traditional secondary schools short change and dump anywhere but in "their" class rooms).

    Your efforts for presentation ought to be "trophied", me thinks. My hope was always to try and achieve what I think you have accomplished in this tutorial, inspired thought of seeing the possible from basic intuition and fundamental building blocks from fLoss type thinking over centuries. We all have seen apples fall from trees, not once have I seen them go up. Yet, until someone stated it so clearly as a law, the forest for the trees dilemma dominates.

    I could go on with greater obfiscation and confusing sentences, but let me end by saying thank you, nicely done and I hope that your efforts are seen as what I think they are: humble, generous, appreciative of those before you and a strong desire to be part of creating a more perfect...

    Thank you.

    1 reply

    Thanks for the support, and kind words. I hope you've enjoyed reading the instructable. I intend to write a few more in the future :-)

    One question I have is what are you doing to account for power factor? Reading current on AC systems can give you a very inaccurate image of the usage if the power factor is not perfect.

    2 replies

    Also, on the note of accuracy, calibration is critical. I calibrated the readings against a calibrated multimeter. The project will be accurate to less than 1mA

    thanks for your question. I'm not overly concerned with PF considering I am only measuring current (not power) in a single phase system. Domestic supplies in the UK are tightly regulated. I would expect the PF to be very close to unity or between 0.95 and 1.0. Finally my project is to monitor resistive loads so no PF correction needed:-)

    There's not a lot of point making dc coupled amps for the front end, you could ac couple the signal in, or bias it, so you don't need dual supplies.

    4 replies

    yes but if you have pure sine wave into the analog in you would need to alter the code to measure the peak at 5ms after the zero crossing point, and then calc RMS from that (Assuming the measured current is 50Hz i think emonlib does it that way). if you don't want to use dual supplies you could use a single rail op-amp instead. The 741 is a bit dated now :-)

    Correct, it's not an issue at all. It's just a my way of doing things :-)