With a correctly working ina219 module and using the example program by Adafruit (getcurrent.ino) I get correct current values returned (in my case: 0mA).
When using my own program, using the same module, and with correct I2C connections, the returned current value = 65535.
This is when both programs are using the same hardware setup (I2C connections SDA & SCL, working ina219 module, same power supply connections, ..).
Ultimately I cannot see the forrest through the trees anymore, so I turn to this forum.
In my program I use currentValue to store the current value (mA) retrieved from the ina219.
Any help, suggestions, comments, .. will be greatly appreciated.
The output of
Serial.print(F("currentValue = "));
Serial.print(currentValue);
Serial.print(F(" cumul = "));
Serial.print(cumul);
Serial.print(F(" cum.volt. = "));
Serial.print(cumulVoltage);
Serial.print(F(" cum.amp. = "));
Serial.print(cumulCurrent);
Serial.print(F(" volt.Disp. = "));
Serial.print(voltageDisplay);
Serial.print(F(" amp.Disp. = "));
Serial.println(currentDisplay);
is
currentValue = 65535 cumul = 20 cum.volt. = 0 cum.amp. = 13041465 volt.Disp. = 0.00 amp.Disp. = 65.21
Current through the ina219 = 0mA.
My program:
#include <Wire.h>
#include <LCD.h> // will force using NewLiquidCrystal library
#include <LiquidCrystal_I2C.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219; //declare an instance of INA219
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// const int RELAIS = 10;
#define RELAIS 10 // PB2 set relais/LED output on pin 10 overtemp detection
#define BEEP 11 // PB3 set piezo beep output on pin 11 (PWM pin)
#define fan 9 // PB1 ventilator output pin
unsigned long now1 = millis(); // temperature measurement interval time
unsigned long now2 = millis(); // voltage and current measurement interval time
unsigned long interval;
const word interval1 = 1000; // delay time in milliseconds, temperature measuerements
const word interval2 = 500; // delay time in milliseconds, voltage and current measurements
const word interval3 = 750; // delay time in milliseconds, LCD refresh
byte T1 = 70; // max normal operating temperature darlington & heatsink
const byte T1a = T1 - 2; // hysteresis set variable high temperature low end at -2C
const byte T1b = T1; // hysteresis reset
const byte T2 = 85; // overtemperature darlington or heatsink
const byte T3 = 65; // kick-in temp for fan, fanspeed = 25%
const byte T4 = 85; // temp for max fan speed
const byte T5 = 5; // hysteresis value, used to substract from kick-in temperature
byte fanValue; // output value to cooling fan
int T6; // intermediate temp value for fan speed usage
const byte fanMin = 125; // minimum fan speed
const byte fanMax = 254; // maximum fanspeed
const byte v1 = 2; // max voltage when short circuit occurs
const byte C1 = 2; // min current (A) when short circuit occurs
const int displaydelay = 500; // display update delay in millis
boolean OC = false; // overcurrent status
boolean warning; // warning status (temperature and/or current)
const byte x = 8; // number of loops to remove a pos and a neg maximum = x+2
const byte cumul = 20; // number of repeats for x+2 loops
boolean message1;
boolean message2;
float voltageDisplay;
float currentDisplay;
unsigned int temp1Value; // temp1 darlington
unsigned int temp2Value; // temp2 heatsink
unsigned int voltageValue; // spanning
unsigned int currentValue; // stroom
unsigned long cumulVoltage;
unsigned long cumulCurrent;
void setup()
{
Serial.begin(9600);
delay(5);
Serial.println(__FILE__);
Serial.println("Arduino_LCD_voltage_current_ina219_v11.ino");
analogReference(EXTERNAL); // externe referntiespanning: 5,000 V
if (! ina219.begin()) {
Serial.println("Failed to find INA219 chip");
while (1) {
delay(10);
}
} lcd.begin(16, 2);
pinMode (RELAIS, OUTPUT);
pinMode (BEEP, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(fan, OUTPUT); //set fan as ventilator output
digitalWrite(RELAIS, LOW);
lcd.backlight();
lcd.setBacklight(HIGH);
//initialise display on startup
lcd.home (); // go home on LCD
lcd.print(F(" Labo PSU"));
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
lcd.setCursor (0, 1);
lcd.print(F(" Erik /V10a "));
digitalWrite(LED_BUILTIN, LOW);
delay(10);
for (int i = 0; i < 4; i++)
{
lcd.noBacklight();
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
lcd.backlight();
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
lcd.clear();
}
void printToLCD(float value1, byte width, byte dp) // print to LCD: value, number of digits, number of digits after comma
{
char out[10];
dtostrf(value1, width, dp, out);
lcd.print(out);
}
void printToLcdLine2Reset(float value2, unsigned int value3)
{
// digitalWrite(BEEP, LOW);
digitalWrite(LED_BUILTIN, LOW);
lcd.print(F("I="));
printToLCD(value2, 5, 2);
lcd.print(F("A T2="));
printToLCD(value3, 3, 0); // heatsink temp on line 2
lcd.print(F("C"));
}
void loop()
{
//initialise variables and reset loop totals to 0
unsigned long temp1Total = 0; // temp1 darlington cumulated
unsigned long temp2Total = 0; // temp2 heatsink cumulated
unsigned long voltageTotal = 0; // voltage values cumulated
unsigned long currentTotal = 0; // current values cumulated
unsigned int signalMax0 = 0; // max value from analog 0 (temp1Value)
unsigned int signalMin0 = 65000; // min value from analog 0, temp1 Darlington
unsigned int signalMax1 = 0; // max value from analog 1 (temp2Value)
unsigned int signalMin1 = 65000; // min value from analog 1, temp2 heatsink
unsigned int signalMax2 = 0; // max value from analog 2 (voltageValue)
unsigned int signalMin2 = 65000; // min value from analog 2, output voltage
unsigned int signalMax3 = 0; // max value from INA219 (currentValue)
unsigned int signalMin3 = 100000; // min value from INA219, output current
bool fanOn = false;
/**********************************************************************/
// test for overtemperatures, elke 1 seconde
/**********************************************************************/
if (millis() - now1 >= interval1) // execute every interval1 milliseconds (1000)
{
for (int j1 = 0; j1 < (x + 2); j1++) // read values x+2 times, and deduct min. and max, the divide by x
{
//read values from analog inputs and accumulate
temp1Value = (analogRead(0) * 50000 / 1023); // darlington temp read m°C LM35 = 10mV/°C, 5V = 500000 m°C, temp1Value = integer = actual temperature * 100 = unsigned int
delayMicroseconds(10);
temp1Value = (analogRead(0) * 50000 / 1023); // repeat
delayMicroseconds(10);
temp2Value = (analogRead(1) * 50000 / 1023); // heatsink temp read m°C LM35 = 10mV/°C, 5V = 500000 m°C, temp1Value = integer = actual temperature * 100 = unsigned int
delayMicroseconds(10);
temp2Value = (analogRead(1) * 50000 / 1023); // repeat
delayMicroseconds(10);
if (temp1Value < signalMin0)signalMin0 = temp1Value;
if (temp1Value > signalMax0)signalMax0 = temp1Value;
if (temp2Value < signalMin1)signalMin1 = temp2Value;
if (temp2Value > signalMax1)signalMax1 = temp2Value;
temp1Total += temp1Value; // temp1 darlington accum m°C*(x+2)
temp2Total += temp2Value; // temp2 cooling fins accum m°C*(x+2)
}
// remove minimum and maximum outliers
temp1Total -= signalMin0; // Darlington temp m°C
temp1Total -= signalMax0;
temp2Total -= signalMin1; // heatsink temp m°C
temp2Total -= signalMax1;
// calculate average temperatures, voltage and current
temp1Value = temp1Total / x / 100; // temp darlington °C
temp2Value = temp2Total / x / 100; // temp heatsink °C
/**********************************************************************/
// fan cooling ventilator control section, output on pin 9
/**********************************************************************/
if (temp1Value > T4) //then it's already at max speed...
{
T6 = 100;
}
if (temp1Value > T3) // min temp1Value for fan kick-in
{
fanOn = true;
T6 = temp1Value;
}
else if (temp1Value < (T3 - T5)) // min temp1Value - hysteresis for fan kick-out
{
fanOn = false;
analogWrite(fan, 0);
}
if (fanOn)
{ // calculate fanspeed if temp1Value > T3
if (temp1Value > T3)
{
T6 = temp1Value;
fanValue = map(T6, T3, T4, fanMin, fanMax);
analogWrite(fan, fanValue);
}
else {
analogWrite(fan, fanMin); // fanspeed if T3 - T5 < temp1Value < T3
}
}
/**********************************************************************/
// test for overtemp conditions without overcurrent
/**********************************************************************/
if ((temp1Value >= T1 && temp1Value < T2 && OC == false) || (temp2Value >= T1 && temp2Value < T2 && OC == false)) // warning high temp darlington or heatsink, no shortcircuit
{
Serial.println(F(" high temp conditions"));
Serial.print(F(" darl = "));
Serial.print(temp1Value);
Serial.print(F(" HS. = "));
Serial.println(temp2Value);
T1 = T1a; // hysteresis set to value 0°C: T2
warning = true;
lcd.setCursor (0, 1); // go to start of 2nd line
if (message1 == true) // alarm, after second passage after interval3, print to LCD second line
{
message1 = false;
interval = interval1; // faster interval
lcd.print(F("HIGH TEMP WARN!!"));
digitalWrite(LED_BUILTIN, HIGH);
}
else // alarm reset, or first passage after high temp detect, print to LCD second line
{
message1 = true;
interval = interval3; // LCD regular refresh
printToLcdLine2Reset(currentDisplay, temp2Value);
}
}
// alarm overtemperature darlington or heatsink, no shortcircuit
if ((temp1Value >= T2 && OC == false) || (temp2Value >= T2 && OC == false))
{
// T2b = T2a; // hysteresis st -2°C
lcd.setCursor (0, 1); // go to start of 2nd line
warning = true;
digitalWrite(RELAIS, HIGH); // overtemperature, relay opens
lcd.setCursor (0, 1); // go to start of 2nd line
if (message2 == true) // alarm, after second passage after interval3
{
message2 = false;
interval = interval2; // faster interval
lcd.print(F("OVERTEMP WARNING"));
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(RELAIS, HIGH); // overtemperature, relay opens
tone(BEEP, 4000); // overtemperature, beep sounds
}
else // alarm reset, or first passage after high temp detect
{
message2 = true;
interval = interval3; // LCD regular refresh
noTone(BEEP); // turn off buzzer
printToLcdLine2Reset(currentDisplay, temp2Value);
Serial.println(F(" alarm reset"));
Serial.print(F(" currentDisplay = "));
Serial.println(currentDisplay);
}
}
now1 = millis();
}
/**********************************************************************/
// voltage and current measurements every 500ms
/**********************************************************************/
if (millis() - now2 >= interval2)
{
// repeat 'cumul' times current and voltage minus outliers and accumulate voltage and current values
for (int j2 = 0; j2 < cumul; j2++)
{
// read x+2 times values from analog inputs and accumulate
for (int j1 = 0; j1 < (x + 2); j1++) // read values x+2 times, and deduct min. and max, the divide by x
{
currentValue = ina219.getCurrent_mA(); //mA, unsigned int
voltageValue = (analogRead(2) * 45000 / 1023); // mV // actual voltage * 1000, unsigned int
delayMicroseconds(10);
voltageValue = (analogRead(2) * 45000 / 1023); // repeat
delayMicroseconds(10);
if (voltageValue < signalMin2)signalMin2 = voltageValue; // voltage in mV
if (voltageValue > signalMax2)signalMax2 = voltageValue;
// if (currentValue < signalMin3)signalMin3 = currentValue;
// if (currentValue > signalMax3)signalMax3 = currentValue;
voltageTotal += voltageValue; // spanning mV*(x+2), unsigned long
currentTotal += currentValue; // stroom mA*(x+2)
}
// Subtract minimum and maximum outliers from totalled voltage values
voltageTotal -= signalMin2; // output voltage in mV
voltageTotal -= signalMax2;
// currentTotal -= signalMin3; // measured mA current
// currentTotal -= signalMax3;
cumulVoltage += voltageTotal; // cumulated voltage ('cumul' times) over x measurements, in mV
cumulCurrent += currentTotal; // cumulated current ('cumul' times) over x+2 measurements, in mA
voltageTotal = 0; // reset
currentTotal = 0; // reset
}
float voltageDisplay = cumulVoltage / cumul / 1000.0 / x; // average voltage measurement over 'cumul' times measurement during (x+2 times minus mi and max outliers)
float currentDisplay = cumulCurrent / cumul / 1000.0 / (x+2); // average current measurement
Serial.print(F("currentValue = "));
Serial.print(currentValue);
Serial.print(F(" cumul = "));
Serial.print(cumul);
Serial.print(F(" cum.volt. = "));
Serial.print(cumulVoltage);
Serial.print(F(" cum.amp. = "));
Serial.print(cumulCurrent);
Serial.print(F(" volt.Disp. = "));
Serial.print(voltageDisplay);
Serial.print(F(" amp.Disp. = "));
Serial.println(currentDisplay);
cumulVoltage = 0;
cumulCurrent = 0;
/**********************************************************************/
// test conditions for overcurrent warnings
/**********************************************************************/
// shortcircuit where v1 = c1 = 2
if (voltageValue <= v1 && currentDisplay >= C1) // shortcircuit where v1 = c1 = 2
{
OC = true;
lcd.setCursor (0, 1);
lcd.print(F("kortsluiting "));
digitalWrite(LED_BUILTIN, HIGH);
}
else // no shortcircuit, warning reset
{
OC = false;
if (warning == false)
{
}
}
/**********************************************************************/
// LCD print line 0: voltage and temp1 (Darlington) value
/**********************************************************************/
lcd.home ();
lcd.print(F("U="));
printToLCD(voltageDisplay, 5, 2);
lcd.print(F("V T1="));
printToLCD(temp1Value, 3, 0); // Darlington temp on line 0
lcd.print(F("C"));
lcd.setCursor (0, 1); // go to start of 2nd line
if (warning == false && OC == false) // when alarm is reset, re-display regular values on line 1 (second line)
{
printToLcdLine2Reset(currentDisplay, temp2Value); // current value and heatsink temperature
Serial.println(F(" regular current display"));
Serial.print(F(" currentDisplay = "));
Serial.println(currentDisplay);
}
now2 = millis();
}
/**********************************************************************/
// temperatures back to normal, no short circuit, protection relay and beep reset
/**********************************************************************/
if (temp1Value < T1 && temp2Value < T1 && OC == false)
{
lcd.setCursor (0, 1);
noTone(BEEP); // reset buzzer, turn off buzzer
digitalWrite(RELAIS, LOW);
digitalWrite(LED_BUILTIN, LOW);
warning = false;
T1 = T1b; // reset T1 hysteresis to 0°C
}
}