Hackster is hosting Hackster Holidays, Finale: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Tuesday!Stream Hackster Holidays, Finale on Tuesday!
Science 3D
Published © GPL3+

Sensing Current with an INA219 and Storing Data on SD Card

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

IntermediateShowcase (no instructions)8 hours6,914
Sensing Current with an INA219 and Storing Data on SD Card

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
INA219 I2C DC Current Sensor Breakout Module
×1
Micro SD Card reader
×1
Stereo Speaker Plate Terminal Strip Push Connector Block
×1
Single sided copper clad board
×1
Arduino UNO
Arduino UNO
×1

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)
CNC shapeoko

Story

Read more

Custom parts and enclosures

The Casing

The top

Code

My version of the code for that project

Arduino
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>
#include <Adafruit_INA219.h>
#include <Adafruit_SSD1306.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
Adafruit_SSD1306 display(OLED_RESET);
Adafruit_INA219 ina219;

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;
float loadvoltage = 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
const int VAR1_numVAR1_readings = 5;
float VAR1_readings[VAR1_numVAR1_readings];      // the readings from the analog input
int VAR1_readIndex = 0;              // the index of the current reading
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)
  {
    CurFile = SD.open("header.txt", FILE_WRITE);
    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(loadvoltage);
        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(loadvoltage);
  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
  power_mw = (loadvoltage * current_mA);
  if (power_mw < 0)
  {
    current_mA = 0;
    loadvoltage = 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
  // subtract the last reading:
  VAR1_total = VAR1_total - VAR1_readings[VAR1_readIndex];
  // read from the sensor:
  VAR1_readings[VAR1_readIndex] = ValueToAVG;
  // add the reading to the VAR1_total:
  VAR1_total = VAR1_total + VAR1_readings[VAR1_readIndex];
  // advance to the next position in the array:
  VAR1_readIndex = VAR1_readIndex + 1;
  // if we're at the end of the array...
  if (VAR1_readIndex >= VAR1_numVAR1_readings)
    VAR1_readIndex = 0;
  // calculate the VAR1_average:
  VAR1_average = VAR1_total / VAR1_numVAR1_readings;
  // send it to the computer as ASCII digits
  return VAR1_average;
}


void B1_StartStop_SD()
{ // DEBOUNCE B1
  int reading = digitalRead(B1_buttonPin);
  if (reading != B1_LastState)
    B1_lastDebounceTime = millis();
  if ((millis() - B1_lastDebounceTime) > B1_debounceDelay)
  {
    if (reading != B1_ActualState)
    {
      B1_ActualState = reading;
      if (B1_ActualState == HIGH)
        B1_State = !B1_State;
    }
  }
  B1_LastState = reading;
}

Credits

Science 3D
11 projects • 25 followers
I have a background in electronics, since 1984. I used to work as a programmer for a couple of years. Now, I am working as a DBA.

Comments