Project showcase # Sensing Current with an INA219 and Storing Data on SD Card © GPL3+

This is my version of a data logger using a INA219.

• 4,422 views
• 10 respects

## Components and supplies Arduino Nano R3
×1
 INA219 I2C DC Current Sensor Breakout Module
×1
×1
 Stereo Speaker Plate Terminal Strip Push Connector Block
×1
×1 Arduino UNO
×1

## Necessary tools and machines 3D Printer (generic) Soldering iron (generic)
 CNC shapeoko

### The Goal

The majority of my electronic projects are connected on an external power source but, I intend to make some of them work on battery or solar panel.

To achieve that goal, I need to estimate the power consumption, in mAh, over a certain period of time.

Let's take some exemples:

• Let's say that my circuit consume 50mA for 1 hour, then I can say that a 50mAh battery will support the circuit for 1 hour.
• Now, let's presume that my circuit triggers certain external devices and that the current consumption varies over time. For example: In the first half of the hour, my device consumes 50mA but for the second half, it consumes 100mA, then, after one hour, I could calculate that the circuit will need a 75mAh battery to support the load for one hour.
• But what if my circuit consumes 50mA for 15 minutes then 55mA for 6 minutes then 150 for 12 minutes and so on... the only way to correctly estimate the mAh needed for a 1 hour period is by capturing the power consumption every second or more precisely, many times per second!

This is exactly the goal of that project: Continuously estimating the current consumption, overtime, and store all the data on an micro SD card so I can loadthe data into Excel and, not only will I be able to see the final power consumption but also a graph showing the variation of the power over the hole period of time.

### Video explanation

I posted a video on YouTube so if you want to see the complete build, please visit the video.

### Technical details

My version of a data logger based on the one made by "GreatScott"; This guy is hot and the video explanations that he makes are very detailed so, I decided to let you visit his video for the technical part and for the base code and use my video for the build and the modification that I made on the base code.

At the heart of this project resides the INA219

It is a I2C breakout board that is really easy to use but it has a small problem: the current returned, when there are no load, is in the negative range. So to hide this problem, I decided to add a condition to return 0 when this condition occurs

``power_mw = (loadvoltage * current_mA);if (power_mw < 0){current_mA = 0;loadvoltage = 0;power_mw = 0;}``

I also added a push button to start & stop the recording so I control what to monitor. For that purpose, I added a function tu Debounce the pushbutton

I tried to make an "Easy to use" module and to make it more friendly so I prepared 2 ways to "Input the voltage".

One of the method is via a DC Power Supply Jack Socket Female Connector

The other method is via a Stereo Speaker Plate Terminal Strip Push Connector Block

Here are some 3D Rendered images of the inside

As shown in the next image, I split the front section in 2 sections: the left side are the inputs and the right side are the outputs section with the ground clip.

Once the data are imported into Excel, a deeper analysis can be made as you can see in the next image

My goal is reached now: I can monitor any electronic project and analyze the captured data to better understand the current consumption overtime and, using this data, I can start thinking about creating outdoors IoT devices powered by solar panels like this IoT Weather Station that I made: I will certainly revisit this project to estimate the current and, eventually, convert it to use solar panels.

Thanks

## Code

##### My version of the code for that projectArduino
The main part of that code comes from GreatScott but I modified it to suit my needs.
```//ref: https://www.youtube.com/watch?v=lrugreN2K4w
#include <Wire.h>
// inclure aussi la librarie Adafruit_BusIO-master meme si il n'y a pas d'include ici.
#include <SPI.h>
#include "SdFat.h"
SdFat SD;

#define OLED_RESET 4

unsigned long previousMillis = 0;
unsigned long dataAquisitionInterval_ms = 250;
const int chipSelect = 10;
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float power_mw = 0;
float current_mAh = 0;
float power_mWh = 0;
File DataLogFile;
File CurFile;

int boot = 1;

int days;     //number of days
int hours;   //the remainder from days division (in milliseconds) divided by hours, this gives the full hours
int minutes; //and so on...
int seconds;

// Moving Average VAR1
float VAR1_total = 0;                  // the running total

// DEBOUNCE B1
const int B1_buttonPin = 3;    // the number of the pushbutton pin
int B1_State = LOW;         // the current state of the output pin
int B1_ActualState;             // the current reading from the input pin
int B1_LastState = LOW;   // the previous reading from the input pin
unsigned long B1_lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long B1_debounceDelay = 50;    // the debounce time; increase if the output flickers
const int ledPin = 4;      // the number of the LED pin

void setup()
{
SD.begin(chipSelect);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
ina219.begin();

// DEBOUNCE B1
pinMode(B1_buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);

}

void loop()
{

if (boot == 1)
{
if (CurFile)
{
CurFile.println("day,hrs,voltage,current_mA,power_mWh,current_mAh");
CurFile.close();
boot = 0;
}
//    B1_State = LOW;
digitalWrite(ledPin, LOW);
}

// DEBOUNCE B1
B1_StartStop_SD();
// set the LED:
digitalWrite(ledPin, B1_State);

unsigned long currentMillis = millis();

//Calculation for the Up Time
long day = 86400000; // 86400000 milliseconds in a day
long hour = 3600000; // 3600000 milliseconds in an hour
long minute = 60000; // 60000 milliseconds in a minute
long second =  1000; // 1000 milliseconds in a second

days = currentMillis / day ;                                //number of days
hours = (currentMillis % day) / hour;                       //the remainder from days division (in milliseconds) divided by hours, this gives the full hours
minutes = ((currentMillis % day) % hour) / minute ;         //and so on...
seconds = (((currentMillis % day) % hour) % minute) / second;
//Calculation for the Up Time

if (currentMillis - previousMillis >= dataAquisitionInterval_ms)
{
previousMillis = currentMillis;
ina219values();

//>>> writing to the card
if (B1_State == HIGH)
{
DataLogFile = SD.open("DataLog.txt", FILE_WRITE);
if (DataLogFile)
{
DataLogFile.print(days);
DataLogFile.print(",");

if (hours < 10) DataLogFile.print('0');
DataLogFile.print(hours);
DataLogFile.print(":");
if (minutes < 10) DataLogFile.print('0');
DataLogFile.print(minutes);
DataLogFile.print(":");
if (seconds < 10) DataLogFile.print('0');
DataLogFile.print(seconds);
DataLogFile.print(",");

DataLogFile.print(",");
DataLogFile.print(current_mA);
DataLogFile.print(",");
DataLogFile.print(power_mWh);
DataLogFile.print(",");
DataLogFile.println(current_mAh);
DataLogFile.close();
}  //>>> writing to the card
}

displaydata();
}

}

void displaydata()
{
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);

//first line
display.setCursor(0, 0);

display.print(days);
display.print("d ");

if (hours < 10) display.print('0');
display.print(hours);
display.print(":");
if (minutes < 10) display.print('0');
display.print(minutes);
display.print(":");
if (seconds < 10) display.print('0');
display.print(seconds);
display.print(" -> ");

display.print("v ");

//second ling
display.setCursor(0, 10);
display.print(power_mw);
display.print("mW ");
display.print(abs(current_mA));
display.print("mA");

//third ling
display.setCursor(0, 20);
display.print(power_mWh);
display.print("mWh ");
display.print(current_mAh);
display.print("mAh");
display.display();
}

void ina219values()
{
shuntvoltage = (ina219.getShuntVoltage_mV());
busvoltage = (ina219.getBusVoltage_V());
current_mA = MovingAVG_VAR1(ina219.getCurrent_mA());
loadvoltage = (busvoltage + (shuntvoltage / 1000));

// to avoid inconsistant readings, set to zero when values are below zero
if (power_mw < 0)
{
current_mA = 0;
power_mw = 0;
}

power_mWh = power_mWh + (power_mw       / (60 * 60) / (1000 / dataAquisitionInterval_ms));
current_mAh = current_mAh + (current_mA / (60 * 60) / (1000 / dataAquisitionInterval_ms));

}

float MovingAVG_VAR1(float ValueToAVG)
{
float VAR1_average = 0;                // the average
// advance to the next position in the array:
// if we're at the end of the array...
// calculate the VAR1_average:
// send it to the computer as ASCII digits
return VAR1_average;
}

void B1_StartStop_SD()
{ // DEBOUNCE B1
B1_lastDebounceTime = millis();
if ((millis() - B1_lastDebounceTime) > B1_debounceDelay)
{
{
if (B1_ActualState == HIGH)
B1_State = !B1_State;
}
}
}
```

## Custom parts and enclosures

#### SD Card Temperature Data Logger

Project tutorial by 3 developers

• 15,501 views
• 11 respects

#### SD Card Module with Arduino: How to Read/Write Data

• 151,959 views
• 35 respects

#### Sorting Resistors the Lazy Way

Project tutorial by Federico Vivaldi

• 18,938 views
• 99 respects

#### Motion Sensing Under Bed Lights

Project tutorial by T3ch Flicks

• 12,592 views
• 39 respects

#### Reading Text Files From an SD Card (Arduino)

Project tutorial by millerman4487

• 6,889 views