Introduction: AC Current Monitoring Data Logger

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


sspence (author)2016-12-27

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.

smooth_jamie (author)sspence2016-12-27

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

smooth_jamie (author)sspence2016-12-27

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.

blabbersnitch (author)2016-12-15

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?


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! :-)

BrandonW86 (author)2016-12-13

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.

smooth_jamie (author)BrandonW862016-12-13

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.

Cgiff (author)2016-12-12

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.

smooth_jamie (author)Cgiff2016-12-12

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

Traacker (author)2016-12-12

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.

smooth_jamie (author)Traacker 2016-12-12

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 :-)

ChrisS41 (author)2016-12-12

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.

smooth_jamie (author)ChrisS412016-12-12

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

smooth_jamie (author)ChrisS412016-12-12

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:-)

steveastrouk (author)2016-12-11

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.


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 :-)


I don't think its an issue.


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

JohnC430 (author)steveastrouk2016-12-11

ac couple 50 Hz?

steveastrouk (author)JohnC4302016-12-11

Yes, no problem.

JohnC430 (author)2016-12-11

nice project. thanks for sharing also all the calcs and files.

Its a lot of work but a good project.

the following is just suggestions and not intended to find fault with what you did:

why did you use a gain of 150? seems very high. the current transformer spec sheet shows the linear range to be 10 Amps and a suggested load resistor of 50 Ohms. Most home appliances will use that full range. what was the load resistor you used for the CT?

Since ur amplifier uses +/- 12 Volts as the DC Buss its output linear range is restricted to approximately 10 Volts. if you used the 50 Ohms resistor then your amp gain has to be no more than 1000/50 = 20. a lower value resistor allows u to use a larger amp gain but that reduces the accuracy of the CT because the wire resistance of the CT becomes a major factor.

So what resistor did you use?

Also instead of a half wave rectification if you used full wave rectification it could help with accuracy and calibration and since you are measuring 50Hz then filtering for 50 Hz on the output would also help. also I don't see a bleeder resistor across the output cap so it becomes a peak detector. perhaps the Arduino input may load it down somewhat.

no matter what I have said, I think this is a pretty good project

JohnC430 (author)JohnC4302016-12-11

Ok I missed it. in the text you mentioned a 220 Ohm load resistor for the CT making the amp gain no more than x4.5. or max current of 0.303 Amps with your values. how does this work? what were you intending to measure with this instrument? very small currents. perhaps I am missing something? I thought also that the Arduino ADC input is limited to 5 Volts but I may be wrong, cos I don't know anything about it.

smooth_jamie (author)JohnC4302016-12-11

Hi John, I am measuring currents between 0 and 100mA maximum! At 100mA the signal voltage will be near 5V. The output of the op-amp isn't limited so will keep increasing with measured current above 100mA, up to the rail voltage. You could always use a 5v zener to limit the input to the ADC.

JohnC430 (author)smooth_jamie2016-12-11

ahhhh...:) thanks. 100 mA explains it. I usually think in terms of 20 to 1000 Amps and forgot that there is another world out there. I was thinking of 10 Amps in the CT and got wayyyy out of the ball park.

smooth_jamie (author)JohnC4302016-12-11

you can measure up to 5A with this CT if you like? you just need to change the gain to suit. If you want to measure >30A you could use the SCT-013.

PC-GUY1 (author)2016-12-11

Nice project. I remember some years ago I was sent out to solve a a building wide computer problem whose Macs all seemed to go offline at random times of the day. It turned out to be a very old building in Manhattan ( I think they still ha d DC wiring in the walls from the days of Edison vs Tesla wars. ), anyway it turned out that whenever the elevator in the building was called, it sucked all of the power out of the walls. I saw it happen and a young lady who was showing me the problem was furious with me. Why is it the te techs get blamed for all of the problems that we didn't create? I called my boss and I wanted to install the shops line monitor to give the big money boys the proof. That device only monitored one outlet but it did have a built in printer so we could get a have a time and date stamped printout. Is there any chance a printer could be hooked up so that the client could see a the results in an easy to comprehend format, hopefully in color so they could see the voltage levels plotted on a timeline? This could really help the guys in the field. Thanks again for a great project.

smooth_jamie (author)PC-GUY12016-12-11

Glad you like it :-) Interesting story! On reflection, it would of been nice to have an LCD to print the results. Perhaps I will use a display in my next iteration.

brian5003 (author)2016-12-11

I think its V=IR or R=V/I. :(

brian5003 (author)brian50032016-12-11

Very nice build!

smooth_jamie (author)brian50032016-12-11

Whoops! thanks for pointing that out. I will amend :-)

Build_it_Bob (author)2016-12-11

Great example of how to put an Arduino ADC to good use.

The explanation of the math involved is helpful as well.

Thanks for sharing!


A pleasure bob :-)

electrocoder (author)2016-12-11

thanks @smooth_jamie


I'm happy you like it :-) it seems quite well received. thank you.

ngpha (author)2016-12-10

But the time is all zero

smooth_jamie (author)ngpha2016-12-11

so when you load the basic sketch and print time in the serial monitor you get zero?

ve6cmm (author)2016-12-11

John, the input load is the 1K resistor. When used as an amplifier, the input of an OPAMP is ZERO ohms. The feedback resistor guarantees this when the amplifier is running in the linear range.

I have used CT's in a number of commercial device designs. Usually, the CT is defined by an input to output current ratio. The CT will always try to output the current ratio, so a load should always be across the CT.

In this case, as long as the OPAMP is powered up, there is no problem. However, if the system is powered down the voltage developed across the CT's leads could be large enough to kill the opamp. A better idea would be to put a 500R resistor or 2 zener diodes across the CT output to limit the voltage developed.

steveastrouk (author)ve6cmm2016-12-11

If you look at the actual IMPLEMENTATION, he has 220 ohm resistors across the CT.

JohnC430 (author)2016-12-11

perhaps u can do without the amp and use the CT output directly into the adc input of the Arduino and just multiply the gain in the Arduino by 2.25. is that possible?

ngpha (author)2016-12-10

Sometimes it bombs out , then it stop working.presss reset the it works normal

ngpha (author)2016-12-08

I get problem when working with real time ds 3231. Sometimes. It lost data then all time becomes zero

smooth_jamie (author)ngpha2016-12-08

Sorry to hear that. It could be a number of reasons. What have you done to troubleshoot the problem?

ngpha (author)smooth_jamie2016-12-08

it is problem with I2C . I have tried serveral way to deal with i2c hang problem. but it cant solve.

smooth_jamie (author)ngpha2016-12-09

also just make sure you test with just the RTC and the arduino.

smooth_jamie (author)ngpha2016-12-09

Try loading a basic sketch into the arduino. Print time and date in serial monitor every second and see when it bombs out.

ngpha (author)2016-12-08 4 channels, w ac 2 dc

smooth_jamie (author)ngpha2016-12-08

Hi there. it's difficult to understand what's happening in that video. Is it linked to you other comment?

ngpha (author)smooth_jamie2016-12-08

in the video, i measure 4 type of load at the same time, 2 dc current, 2 ac current. I test the measured value with a vom meter & ac watt meter

Swansong (author)2016-12-08

Thanks for sharing!

smooth_jamie (author)Swansong2016-12-08

Happy to give back to the community! Been reading instructables for years.

About This Instructable




Bio: 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 ...
More by smooth_jamie:How to Measure AC Power FactorSteampunk voltmeter clockAC Current monitoring data logger
Add instructable to: