Monday, May 11, 2015

Reading a Current Shunt with an Arduino

Current shunts are very popular with the Ham Radio, boating, electric vehicle and solar / wind off grid folks, as they allow them to monitor solar and wind power production, power consumption of devices, and the estimated amp hours left in the battery bank, sort of like a "gas gauge" for your batteries.

See our complete Off Grid Power Monitoring System at

Previous ADS1115 Arduino / Raspberry Pi post!

Unlike the solid state hall effect types, current shunts drop a small voltage across a calibrated resistor, indicating the amps being passed through the shunt. This allows shunts to report massive amounts of current, in excess of a 1000 amps, depending on the design of the shunt.

Common shunts are rated at 50mv, 75mv, and 100mv output at maximum current (do not exceed 66% of name plate current). The Arduino has a few issues with these shunts. Since the maximum output is just 100 millivolts compared to the Arduino's range of 0-5v, it's like trying to read a 5 inch ruler from 10 miles away (worse with the 50mv and 75mv versions). The second issue is the Arduino has a 10 bit analog to digital converter (ADC), so a 100amp / 100mv shunt would have a 4.88 mv per step resolution, or about 5 amps per step (a total of 1024 steps).

We can solve this with a higher bit ADC with an onboard amplifier. We chose a 16 bit ADC that has over 64000 steps (+/- 32768), and up to 16x amplification. This matches a 100mv shunt very well.

The ADC we chose is the adafruit ADS1115. It has 4 single ended channels, or two differential channels. We chose to use differential mode, to eliminate electrical interference (the third issue) in the monitoring circuit, giving us very stable results. This means we can use two shunts per ADS1115. The ADS1115 can have 4 different user selectable I2C addresses, so with only 2 data lines (SCL & SDA), you can monitor up to 8 shunts.


Connections are very simple. Adafruit gives a very comprehensive tutorial on connecting and using this sensor for a variety of different purposes, and you can read about it (and download the library) at For our purposes, this is what we needed:

VDD - Arduino +5v
GND to Arduino GND
SCL to Arduino A5
SDA to Arduino A4
ADDR to Arduino GND (one of 4 possible address combinations, see adafruit tutorial for the the others)
A0 to Current Shunt
A1 to Current Shunt


Although we are using a 100a / 100mv shunt, if you are using a 75mv or 50mv shunt, we added two additional lines in the code you can uncomment depending on which shunt you are using.

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads;  /* Use this for the 16-bit version */

void setup(void)
  ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV

void loop(void)
  int16_t results;
  results = ads.readADC_Differential_0_1();  
  Serial.print("Amps: "); 
  float amps = ((float)results * 256.0) / 32768.0;//100mv shunt
  //amps = amps * 1.333; //uncomment for 75mv shunt
  //amps = amps * 2; //uncomment for 50mv shunt


Order a complete current sensor board with 100a / 100mv shunt for only $65


  1. Thanks for taking the time to write this... I had a problem with my project and fixed it reading your blog.

  2. In your solar system, how to you manage the grounds? Ie the shunt is presumably low side, and the battery and monitoring grounds in common, or at least the more negative side of the shunt as the common ground?

    1. The shunt can be on the low side or the high side. you are just measuring the difference across it. It can even be bidirectional.

  3. I understand the circuit and how it works. My question is about having a common ground. If you were to power your circuit from the same power source being measured(in your picture it looks like a vehicle), you would be supplying 12+ volts to the analog input pins in reference to ground. I was not sure if this would be a safe condition. Where you are asking the board to only measure difference, I wasn't sure if this would keep the board safe or if it measured A0 to ground and A1 to ground and then determined the difference.

    If this would cause a problem, how could you power the Arduino from the same source safely?

    Last question, powering the Arduino from the same source, however it would have to be, could you then safely measure the source voltage through the appropriate divider on a third analog input? A divider would require a common ground wouldn't it?

    The short question if you will, how can I safely power a circuit from the same source it is measuring current and voltage?

    1. I am not delivering 12v to the analog pins. I am measuring the voltage across the two points of measurement. Not ground. There is no problem powering thew arduino from the same source you are measuring. Yes, you can measure voltage using a voltage divider, and have 12v on the top of the divider, and common ground on the bottom.

  4. Awesome!! thanks a lot this is super helpful as I already have a shunt with my battery monitor and the dc hall sensors are very expensive.

    what happened to your website? seems to be down. is there anywhere we can see your whole monitor setup?

    thanks again!

  5. Build it! Thanks! It will be in a Sailing boat for measuring the Amp for loading the battery banks.
    Great you added the diferent shunts. Makes it a lot easyer.

    Thanks for sharing!!!

  6. Hello dear friend
    Thank you so much for sharing
    but i can't understand how you calculate the current for each amount of shunt.
    can you explain the current formula in your sketch?
    Thank you

    1. See the gain calcualtions at

  7. Will this all work fine if it is bidirectional i.e. charging/discharging = (100A 75mV) -75mV/+75mV?
    Or would it need to be modified to point 2.5V = 0A?

    1. We are using the differential mode, so we are only measuring the difference across the points, not a polarity.

  8. Thank you for your tutorial. Can you please explain me the math of this line:
    float amps = ((float)results * 256.0) / 32768.0;
    I'm trying to use this script for a 300A 75mV shunt.
    Thanks a lot.

    1. We are using a gain of 16 (the 256 value) and a 16 bit adc (the 32768 value). See

  9. I'm using ADS 1115 and module I2C and sadly I2C and ADS1115 use the same analogic door (A4 and A5), Can I change it ? if I can, how? I'm waiting for your answer. thank you.

    1. The ADS1115 is I2C. I2C can handle many devices, as each have their own address. Just connect in parallel, and make sure each device has a different address. The ADS1115 address can be changed if it conflicts with another device.


Related Posts Plugin for WordPress, Blogger...