A program that compiles ok and runs well needs an additional (third) delay with millis.
There already are two delays with millis running flawless; adding a third seems impossible: the program just quits running, even the LCD message during setup is not being displayed.
The questionable lines:
A. in declarations:
unsigned long previousMillis3 = 0; // display timer 3
const int displaydelay = 500; // display update delay in milliseconds
B. ..the added (questionable) llines in loop(); currently commented out in the main code, lower:
unsigned long currentMillis = millis();
if (currentMillis - previousMillis3 >= displaydelay)
{
// current code here
previousMillis3 = currentMillis;
}
The 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
// int RELAIS = 10;
const int T1 = 70; // max normal operating temperature darlington & heatsink
const int T2 = 85; // overtemperature darlington or heatsink
const int T2a = T2 - 2; // hysteresis set variable overtemperature at -2C
int T2b = T2; // hysteresis set variable overtemperature
const int T3 = 65; // kick-in temp for fan, fanspeed = 25%
const int T4 = 85; // temp for max fan speed
const int T5 = 5; // hysteresis value, used to substract from kick-in temperature
int fanValue; // output value to cooling fan
int T6; // intermediate temp value for fan speed usage
const int fanMin = 125; // minimum fan speed
const int fanMax = 255; // maximum fanspeed
const int fan = 9; // ventilator output pin
const int V1 = 2; // max voltage when short circuit occurs
const int C1 = 2; // min current when short circuit occurs
const int displaydelay = 500; // display update delay in millis
boolean OC; // overcurrent status
boolean warning; // warning status (temperature and/or current)
const int x = 8; // loop value: loop amount = x+2 because min and max are removed
const long interval1 = 500; // display time 1 in milliseconds
const long interval2 = 1000; // display time 2 in milliseconds
int long interval;
unsigned long previousMillis1 = 0; // display timer 1
unsigned long previousMillis2 = 0; // display timer 2
unsigned long previousMillis3 = 0; // display timer 3
boolean message1;
boolean message2;
unsigned long periods[] = {500, 1500};
unsigned int signalMax0 = 0; // max value from analog 0
unsigned long int signalMin0 = 150000; // min value from analog 0, temp1 Darlington
unsigned int signalMax1 = 0; // max value from analog 1
unsigned long int signalMin1 = 150000; // min value from analog 1, temp2 heatsink
unsigned int signalMax2 = 0; // max value from analog 2
unsigned long int signalMin2 = 450000; // min value from analog 2, output voltage
unsigned long now;
float cumulVoltage = 0;
float cumulCurrent = 0;
unsigned long int cumul = 0;
void setup()
{
//initialise libraries and ancillaries
Serial.begin(9600);
delay(250);
Serial.println(__FILE__);
analogReference(EXTERNAL); // externe referntiespanning: 5,000V
ina219.begin();
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);
digitalWrite(BEEP, LOW);
// LCD Backlight ON
lcd.backlight();
lcd.setBacklight(HIGH);
//initialise display on startup
lcd.home (); // go home on LCD
lcd.print(" Labo PSU");
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
lcd.setCursor (0, 1);
lcd.print(" Erik /V9 ");
digitalWrite(LED_BUILTIN, LOW);
delay(100);
for (int i = 0; i < 3; i++)
{
lcd.noBacklight();
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
lcd.backlight();
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
}
void loop()
{
//initialise variables and reset loop totals to 0
unsigned long int temp1Total = 0; // temp1 darlington
unsigned long int temp2Total = 0; // temp2 heatsink
unsigned long int voltageTotal = 0;
unsigned long int currentTotal = 0;
unsigned long currentMillis = millis();
float voltageDisplay;
float currentDisplay;
unsigned long int temp1Value; // temp1 darlington
unsigned long int temp2Value; // temp2 heatsink
unsigned int voltageValue; // spanning
unsigned int currentValue; // stroom
static char outvolt[7];
static char outcurr[7];
static char outtemp1[8];
static char outtemp2[8];
unsigned int signalMax0 = 0; // max value from analog 0
unsigned long int signalMin0 = 150000; // min value from analog 0, temp1 Darlington
unsigned int signalMax1 = 0; // max value from analog 1
unsigned long int signalMin1 = 150000; // min value from analog 1, temp2 heatsink
unsigned int signalMax2 = 0; // max value from analog 2
unsigned long int signalMin2 = 450000; // min value from analog 2, output voltage
int fanValue; // output value to cooling fan
int T6; // intermediate temp value for fan speed usage
//start loop x + 2 times
// x + 2 measurements of each analog input and accumulation;
// test conditions for emergency action where and when necessary
for (int j1 = 0; j1 < (x + 2); j1++)
{
//read values from analog inputs and accumulate
temp1Value = (analogRead(0) * 50000 / 1024); // darlington temp read m°C
temp2Value = (analogRead(1) * 50000 / 1024); // heatsink temp read m°C
// voltageValue = (analogRead(2) * 45000 / 1024); // mV
// voltageValue = (analogRead(2) * 45000 / 1024); // mV
// delayMicroseconds(1000);
voltageValue = (analogRead(2) * 45000 / 1024); // mV
currentValue = ina219.getCurrent_mA(); //mA
if (temp1Value < signalMin0)signalMin0 = temp1Value;
if (temp1Value > signalMax0)signalMax0 = temp1Value;
if (temp2Value < signalMin1)signalMin1 = temp2Value;
if (temp2Value > signalMax1)signalMax1 = temp2Value;
if (voltageValue < signalMin2)signalMin2 = voltageValue;
if (voltageValue > signalMax2)signalMax2 = voltageValue;
temp1Total += temp1Value; // temp1 darlington accum m°C*10
temp2Total += temp2Value; // temp2 cooling fins accum m°C*10
voltageTotal += voltageValue; // spanning mV*10
currentTotal += currentValue; // stroom mA
//test conditions for overtemp and or overcurrent warnings
if (voltageValue / 1000 < V1 && currentValue / 1000 > C1) // shortcircuit
{
OC = true;
lcd.setCursor (0, 1);
lcd.print("kortsluiting ");
digitalWrite(LED_BUILTIN, HIGH);
}
else // no shortcircuit;
{
OC = false;
if (warning == false)
{
}
}
}
//remove minimum and maximum outliers
temp1Total -= signalMin0; // darlington temp m°C
temp1Total -= signalMax0;
temp2Total -= signalMin1; // heatsink temp m°C
temp2Total -= signalMax1;
voltageTotal -= signalMin2; // output voltage mV
voltageTotal -= signalMax2;
//calculate average temperatures, voltage and current
temp1Value = temp1Total / x / 100; // temp darlington °C
temp2Value = temp2Total / x / 100; // temp heatsink °C
voltageDisplay = voltageTotal / 1000.0 / x;
currentDisplay = currentTotal / 1000.0 / (x + 2);
cumulVoltage += voltageDisplay;
cumulCurrent += currentDisplay;
cumul = cumul + 1;
//fan cooling ventilator control section, output on pin 9
bool fanOn = false;
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
}
}
//prepare values for display
// if (currentMillis - previousMillis3 >= displaydelay) // only update display every displaydelay delay to limit flicker
// {
dtostrf(voltageDisplay, 5, 2, outvolt); // display output voltage: 5 digits where 2 after comma
dtostrf(currentDisplay, 5, 2, outcurr); //add 2 to x because no removal minimum and maximum values from current
dtostrf(temp1Value, 3, 0, outtemp1); //display darlington temp
dtostrf(temp2Value, 3, 0, outtemp2); //display heatsink temp
lcd.home ();
lcd.print("U=");
lcd.print(outvolt);
lcd.print("V");
lcd.print(" T1=");
lcd.print(outtemp2); // heatsink temp on line 1
lcd.print("C");
lcd.setCursor (0, 1); // go to start of 2nd line
if (warning == false && OC == false)
{
digitalWrite(LED_BUILTIN, LOW);
lcd.print("I=");
lcd.print(outcurr);
lcd.print("A");
lcd.print(" T2=");
lcd.print(outtemp1);
lcd.print("C");
}
// previousMillis3 = currentMillis;
// }
//test for overtemp conditions
if ((temp1Value >= T1 && temp1Value < T2b && OC == false) || (temp2Value >= T1 && temp2Value < T2b && OC == false)) // warning high temp darlington or heatsink
{
T2b = T2; // hysteresis set back to value 0C = T2
warning = true;
// lcd.setCursor (0, 1); // go to start of 2nd line
if ((currentMillis - previousMillis1) >= interval)
{
previousMillis1 = currentMillis;
if (message1 == true)
{
message1 = false;
interval = interval1;
lcd.print("HIGH TEMP WARN!!");
digitalWrite(LED_BUILTIN, HIGH);
}
else
{
message1 = true;
digitalWrite(LED_BUILTIN, LOW);
interval = interval2;
lcd.print("I=");
lcd.print(outcurr);
lcd.print("A");
lcd.print(" T2=");
lcd.print(outtemp1);
lcd.print("C");
}
}
}
if ((temp1Value >= T2b && OC == false) || (temp2Value >= T2b && OC == false)) // warning overtemp darlington or heatsink
{
T2b = T2a; // hysteresis st -2C
// lcd.setCursor (0, 1); // go to start of 2nd line
warning = true;
digitalWrite(RELAIS, HIGH); // overtemperature, relay opens
if ((currentMillis - previousMillis2) >= interval)
{
previousMillis2 = currentMillis;
if (message2 == true)
{
message2 = false;
interval = interval1;
lcd.print("OVERTEMP WARNING");
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(RELAIS, HIGH); // overtemperature, relay opens
digitalWrite(BEEP, HIGH); // overtemperature, beep sounds
tone(BEEP, 4000);
}
else
{
message2 = true;
interval = interval2;
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(BEEP, LOW);
noTone(BEEP);
lcd.print("I=");
lcd.print(outcurr);
lcd.print("A");
lcd.print(" T2=");
lcd.print(outtemp1);
lcd.print("C");
}
}
}
if (temp1Value < T1 && temp2Value < T1 && OC == false) // temperatures back to normal, protection relay and beep reset
{
lcd.setCursor (0, 1);
digitalWrite(RELAIS, LOW);
digitalWrite(LED_BUILTIN, LOW);
warning = false;
}
}