Variable T6 in program below is declared as int T6, even though its value varies only between 0 and 150.
T6 = temp1Value;
..where temp1Value is a float.
Even though I only need the integer value.
Program memory usage: 13492 bytes when declaring int T6.
When changing int T6 to unsigned T6 prog mem = 13516 bytes
When changing to uint16_t T6 prog mem = 13516 bytes
When changing to word T6 prog mem = 13516 bytes
When changing to unsigned int T6 prog mem = 13516 bytes
When changing to byte T6 prog mem = 13518 bytes
I thought that when entering a float into an int that the effective value would be an integer?
Why does the use of int as a declaration result in lower memroy usage than any of the other declarations in this case?
#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
#define fan 9 // ventilator output pin
unsigned long now1;
unsigned long now2;
unsigned long interval;
// unsigned long periods[] = {500, 1500};
const word interval1 = 500; // delay time 1 in milliseconds, high temp alarm
const word interval2 = 750; // delay time 2 in milliseconds, overtemp alarm
const word interval3 = 1000; // delay time 3 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 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; // loop value: loop amount = x+2 because min and max are removed
boolean message1;
boolean message2;
// unsigned long now;
float voltageDisplay;
float currentDisplay;
unsigned long temp1Value; // temp1 darlington cumulated
unsigned long temp2Value; // temp2 heatsink cumulated
unsigned long voltageValue; // spanning cumulated
unsigned long currentValue; // stroom cumulated
unsigned long cumulVoltage;
unsigned long cumulCurrent;
byte cumul;
void setup()
{
//initialise libraries and ancillaries
Serial.begin(9600);
delay(100);
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(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);
}
// now = millis();
lcd.clear();
}
void printToLCD(float value, byte width, byte dp) {
char out[10];
dtostrf(value, width, dp, out);
lcd.print(out);
}
void loop()
{
//initialise variables and reset loop totals to 0
unsigned long temp1Total = 0; // temp1 darlington
unsigned long temp2Total = 0; // temp2 heatsink
unsigned long voltageTotal = 0;
unsigned long currentTotal = 0;
unsigned int signalMax0 = 0; // max value from analog 0
unsigned long signalMin0 = 150000; // min value from analog 0, temp1 Darlington
unsigned int signalMax1 = 0; // max value from analog 1
unsigned long signalMin1 = 150000; // min value from analog 1, temp2 heatsink
unsigned int signalMax2 = 0; // max value from analog 2
unsigned long signalMin2 = 450000; // min value from analog 2, output voltage
//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 / 1023); // darlington temp read m°C LM35 = 10mV/°C, 5V = 500000 m°C
delayMicroseconds(50);
// temp1Value = (analogRead(0) * 50000 / 1023);
// delayMicroseconds(1000);
temp2Value = (analogRead(1) * 50000 / 1023); // heatsink temp read m°C LM35 = 10mV/°C
delayMicroseconds(50);
// temp2Value = (analogRead(1) * 50000 / 1023);
// delayMicroseconds(1000);
// voltageValue = (analogRead(2) * 45000 / 1024); // mV
// voltageValue = (analogRead(2) * 45000 / 1024); // mV
// delayMicroseconds(1000);
// voltageValue = (analogRead(2) * 45000 / 1023); // mV
// delayMicroseconds(10);
voltageValue = (analogRead(2) * 45000 / 1023); // mV
// Serial.print(F(" Darl. temp. = "));
// Serial.print(temp1Value);
// Serial.print(F(" heatsink temp. = "));
// Serial.print(temp2Value);
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*(x+2)
temp2Total += temp2Value; // temp2 cooling fins accum m°C*(x+2)
voltageTotal += voltageValue; // spanning mV*(x+2)
currentTotal += currentValue; // stroom mA*(x+2)
//test conditions for overtemp and or overcurrent warnings
if (voltageValue / 1000 <= v1 && currentValue / 1000 >= C1) // shortcircuit
{
OC = true;
lcd.setCursor (0, 1);
lcd.print(F("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;
// Serial.print(F(" raw voltageTotal = "));
// Serial.print(voltageTotal);
voltageTotal -= signalMin2; // output voltage mV
voltageTotal -= signalMax2;
// Serial.print(F(" signalMin2 = "));
// Serial.print(signalMin2);
// Serial.print(F(" signalMax2 = "));
// Serial.print(signalMax2);
// Serial.print(F(" voltageTotal = "));
// Serial.print(voltageTotal);
// Serial.print(F(" Darl. min. = "));
// Serial.print(signalMin0);
// Serial.print(F(" Darl. max. = "));
// Serial.print(signalMax0);
// Serial.print(F(" heats. min. = "));
// Serial.print(signalMin1);
// Serial.print(F(" heats. max. = "));
// Serial.print(signalMax1);
// Serial.print(F(" Darl.Temp.Ttl = "));
// Serial.print(temp1Total);
// Serial.print(F(" Heatsink.Temp.Ttl = "));
// Serial.println(temp2Total);
//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; // x = number of actually used measurements
currentDisplay = currentTotal / 1000.0 / (x + 2); // x+2 = number of actually used measurements
// Serial.print(F(" voltageDisplay = "));
// Serial.println(voltageDisplay);
cumulVoltage += voltageTotal;
cumulCurrent += currentTotal;
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
}
}
if (millis() - now1 >= interval) // execute every interval1 milliseconds (1000)
{
//test for overtemp conditions
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
// T2b = T2a; // hysteresis set to value 2C: T2 -2°C
warning = true;
lcd.setCursor (0, 1); // go to start of 2nd line
if (message1 == true) // alarm, after second passage after interval3
{
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
{
message1 = true;
interval = interval3; // LCD regular refresh
digitalWrite(LED_BUILTIN, LOW);
lcd.print(F("I="));
printToLCD(currentDisplay, 5, 2);
lcd.write(F("A"));
lcd.print(F(" T2="));
printToLCD(temp2Value, 3, 0); // heatsink temp on line 1
lcd.print(F("C"));
}
}
if ((temp1Value >= T2 && OC == false) || (temp2Value >= T2 && OC == false)) // alarm overtemperature darlington or heatsink, no shortcircuit
{
// Serial.println(F(" overtemp conditions"));
// Serial.print(F(" darl = "));
// Serial.print(temp1Value);
// Serial.print(F(" HS = "));
// Serial.println(temp2Value);
// 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("OVERTEMP WARNING");
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(RELAIS, HIGH); // overtemperature, relay opens
digitalWrite(BEEP, HIGH); // overtemperature, beep sounds
tone(BEEP, 4000);
}
else // alarm reset, or first passage after high temp detect
{
message2 = true;
interval = interval3; // LCD regular refresh
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(BEEP, LOW);
lcd.print(F("I="));
printToLCD(currentDisplay, 5, 2);
lcd.print(F("A"));
lcd.print(F(" T2="));
printToLCD(temp2Value, 3, 0); // heatsink temp on line 2
lcd.print(F("C"));
}
}
now1 = millis();
}
if (millis() - now2 >= interval3) // execute every interval1 milliseconds (500)
{
voltageDisplay = cumulVoltage / cumul / 1000.0 / x;
currentDisplay = cumulCurrent / cumul / 1000.0 / (x + 2);
// Serial.print(F(" voltageDisplay = "));
// Serial.print(voltageDisplay);
// Serial.print(F(" cumul = "));
// Serial.println(cumul);
cumulVoltage = 0;
cumulCurrent = 0;
cumul = 0;
lcd.home ();
lcd.print(F("U="));
printToLCD(voltageDisplay, 5, 2);
lcd.print(F("V"));
lcd.print(F(" T1="));
printToLCD(temp1Value, 3, 0); // Darlington temp on line 1
lcd.print(F("C"));
lcd.setCursor (0, 1); // go to start of 2nd line
if (warning == false && OC == false)
{
digitalWrite(LED_BUILTIN, LOW);
lcd.print(F("I="));
printToLCD(currentDisplay, 5, 2);
lcd.print(F("A"));
lcd.print(" T2=");
printToLCD(temp2Value, 3, 0); // heatsink temp on line 2
lcd.print(F("C"));
//}
now2 = millis();
}
}
if (temp1Value < T1 && temp2Value < T1 && OC == false) // temperatures back to normal, no short circuit, protection relay and beep reset
{
lcd.setCursor (0, 1);
noTone(BEEP); // reset buzzer
digitalWrite(RELAIS, LOW);
digitalWrite(BEEP, LOW); // overtemperature, beep sounds
digitalWrite(LED_BUILTIN, LOW);
warning = false;
T1 = T1b; // reset T1 hysteresis to 0°C
}
}