Something seems to be locking up my hot tub control code one Leonardo with an ATmega32. I think that interference may be causing it since it doesn't happen on every board, just two at this point. I have a theory that the screen updating new info is somehow hanging up the firmware but I don't know how to fix it. Here is the code.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Defining pins------------------------
// Inputs ********************
#define Button1 5
#define Button2 10
#define Button3 9
#define TempSensor A5
#define Flow_SW A4
// Outputs *******************
#define HeatRealy_1 12
#define HeatRealy_2 8
#define OzoneRealy 11
#define ValveRealy 1
#define JetPump_Low 4
#define JetPump_High 0
#define PowerLed 13
// Different States:
int jets_State = 0; // 0 = OFF, 1 = LOW, 2 = HIGH
String jetsState = "OFF";
String prevJetsState = "OFF";
bool jets_Low = false;
String heatState = "OFF";
String prevHeatState = "OFF";
int ozoneState = HIGH; // Starting default state of Ozone
// Variables to store last update times:
unsigned long prevTempUpdate = 0;
unsigned long lastOzoneUpdate = 0;
unsigned long lastButtonPress1 = 0;
unsigned long lastButtonPress2 = 0;
unsigned long lastButtonPress3 = 0;
unsigned long jetsStartMillis = 0;
unsigned long prevLcdUpdate = 0;
// Time variables (changeable):
unsigned long airPurgeTime = 30000; // Turn ON Jets Low for this amount of time at startup
unsigned long tempInterval = 20000; // How long to wait before taking a new temperature reading
unsigned long ozoneInterval = 10800000; // 3 hrs * 3600 seconds on/off cycle
unsigned long jetsTimeout = 1800000; // 30 min, How long it takes jets to turn OFF after starting
unsigned long lcdUpdateInt = 30000; // 20 min, The whole display updates after this time
// Other variables Set (changeable):
int set_Temp = 100; // Deg F
int current_Temp = 105;
int minTemp = 52; // Min temp that can be set
int maxTemp = 104; // Max temp that can be set
int maxTempReadings = 20; // How many temp readings to take at a time to average
float Vout = 0.0, Sens_Res = 0.0, avg_Res = 0.0;
void setup() {
//Serial.begin(9600);
// INPUTS
pinMode(Button1, INPUT_PULLUP);
pinMode(Button2, INPUT_PULLUP);
pinMode(Button3, INPUT_PULLUP);
pinMode(Flow_SW, INPUT_PULLUP);
// OUTPUTS
pinMode(HeatRealy_1, OUTPUT);
pinMode(HeatRealy_2, OUTPUT);
pinMode(OzoneRealy, OUTPUT);
pinMode(ValveRealy, OUTPUT);
pinMode(JetPump_Low, OUTPUT);
pinMode(JetPump_High, OUTPUT);
pinMode(PowerLed, OUTPUT);
// Setting Outputs initially
digitalWrite(HeatRealy_1, LOW);
digitalWrite(HeatRealy_2, LOW);
digitalWrite(OzoneRealy, LOW);
digitalWrite(ValveRealy, LOW);
digitalWrite(JetPump_Low, LOW);
digitalWrite(JetPump_High, LOW);
digitalWrite(PowerLed, HIGH); // Turn ON at startup
// Initialize LCD Display
Wire.setWireTimeout();
lcd.init();
lcd.backlight();
lcd.clear();
// Line 0
lcd.setCursor(0, 0);
lcd.print("SYSTEM STARTING");
// Line 1
lcd.setCursor(0, 1);
lcd.print("Set Temp: ");
lcd.setCursor(10, 1);
lcd.print(set_Temp);
// Line 2
lcd.setCursor(0, 2);
lcd.print("Jets: ");
lcd.setCursor(6, 2);
lcd.print("START");
// Line 3
lcd.setCursor(0, 3);
lcd.print("Heat: ");
lcd.setCursor(6, 3);
lcd.print(heatState);
Serial.println("Electric w/ Jets Code Running");
delay(2000);
// Turn ON jets on LOW at startup for a set time
digitalWrite(JetPump_Low, HIGH);
delay(airPurgeTime);
digitalWrite(JetPump_Low, LOW);
jetsState = "OFF";
// Line 0
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Current Temp: ");
// Line 2
lcd.setCursor(6, 2);
lcd.print(" ");
lcd.setCursor(6, 2);
lcd.print(jetsState);
digitalWrite(OzoneRealy, ozoneState); // Turn ON Ozone after startup
lastOzoneUpdate = millis(); // Save the time ozone relay was turned ON
}
void loop() {
/*
Temperature Sensor Function-----------------------------------------------
*/
takeTempReading(); // Take a new temperature reading from the sensor
/*
Ozone Function------------------------------------------------------------
*/
// Check if its time to change the state of the Ozone Relay:
if (millis() - lastOzoneUpdate >= ozoneInterval) {
lastOzoneUpdate = millis();
ozoneState = !ozoneState; // Toggle the state, ON if OFF and vice versa
digitalWrite(OzoneRealy, ozoneState); // Turn ON Ozone after startup
}
if (digitalRead(JetPump_High) == HIGH) { // If jets are high, turn Ozone OFF
digitalWrite(OzoneRealy, LOW); // Turn OFF
}
/*
Button 1 Function-----------------------------------------------------------
*/
if (digitalRead(Button1) == LOW) { // If button 1 pressed, decrease set temp
if (millis() - lastButtonPress1 > 50) {
Serial.println("Button 1 pressed!");
set_Temp--;
if (set_Temp < minTemp) {
set_Temp = minTemp;
}
displayLcd(1); // Update line 1 on LCD display
}
lastButtonPress1 = millis();
}
/*
Button 2 Function------------------------------------------------------------
*/
if (digitalRead(Button2) == LOW) { // If button 2 pressed, Increase set temp
if (millis() - lastButtonPress2 > 50) {
Serial.println("Button 2 pressed!");
set_Temp++;
if (set_Temp > maxTemp) {
set_Temp = maxTemp;
}
displayLcd(1);// Update line 1 on LCD display
}
lastButtonPress2 = millis();
}
/*
Button 3 Function------------------------------------------------------------
*/
if (digitalRead(Button3) == LOW) { // If button 3 pressed
if (millis() - lastButtonPress3 > 50) {
Serial.println("Button 3 pressed!");
if (digitalRead(HeatRealy_1) == LOW) { // If heating is turned OFF
jets_State++;
if (jets_State == 1) {
jetsState = "LOW";
jetsStartMillis = millis(); // Save the Start time when jets were set to LOW
}
else if (jets_State == 2) {
jetsState = "HIGH";
jetsStartMillis = millis(); // Save the Start time when jets were set to HIGH
}
else if (jets_State > 2) {
jets_State = 0; // Reset and go back to OFF
jetsState = "OFF";
}
}
else { // If heating is turned ON, toggle between LOW and HIGH
if (jets_State == 1) {
jets_State = 2;
jetsState = "HIGH";
jetsStartMillis = millis(); // Save the Start time when jets were set to HIGH
}
else {
jets_State = 1;
jetsState = "LOW";
jetsStartMillis = millis(); // Save the Start time when jets were set to LOW
}
}
displayLcd(2);
delay(50);// Update line 2 on LCD display
}
lastButtonPress3 = millis();
}
/*
Heater Function---------------------------------------------------------------
*/
if (current_Temp < set_Temp) { // If temperaure is less than the set temp, turn ON Heaters
digitalWrite(HeatRealy_1, HIGH);
digitalWrite(HeatRealy_2, HIGH);
heatState = "ON";
if (jets_State == 0) {
jets_Low = true; // Turn ON Jets at low speed
}
}
else if (current_Temp >= set_Temp + 1) { // If current temperaure is 1 deg greater than the set temp, turn OFF Heaters
digitalWrite(HeatRealy_1, LOW);
digitalWrite(HeatRealy_2, LOW);
heatState = "OFF";
jets_Low = false;
}
else{
// do nothing
}
if (digitalRead(JetPump_Low) == HIGH || digitalRead(JetPump_High) == HIGH) { // Check only if jets are ON
if (digitalRead(Flow_SW) == HIGH) { // If Flow sensor reads HIGH = 1, Turn OFF heater
digitalWrite(HeatRealy_1, LOW);
digitalWrite(HeatRealy_2, LOW);
heatState = "LOW FLOW";
jets_Low = true;
}
}
if (prevHeatState != heatState) { // Update on display if state changed
prevHeatState = heatState;
displayLcd(3);
delay(50);// Update line 3 on LCD display
}
/*
Jets Function----------------------------------------------------------------------
*/
if (jets_Low == true && jets_State == 0) { // Turn jets ON if heater is ON and jets were OFF
digitalWrite(JetPump_Low, HIGH);
digitalWrite(JetPump_High, LOW);
jetsState = "LOW";
}
else if (jets_State == 1) { // Turn jets LOW if set to 1
digitalWrite(JetPump_Low, HIGH);
digitalWrite(JetPump_High, LOW);
jetsState = "LOW";
}
else if (jets_State == 2) { // Turn jets HIGH if set to 2
digitalWrite(JetPump_Low, LOW);
digitalWrite(JetPump_High, HIGH);
jetsState = "HIGH";
}
else { // Turn jets OFF if set to 0
digitalWrite(JetPump_Low, LOW);
digitalWrite(JetPump_High, LOW);
jetsState = "OFF";
}
if (digitalRead(HeatRealy_1) == LOW) { // Check only if Heating is OFF
if (digitalRead(JetPump_Low) == HIGH || digitalRead(JetPump_High) == HIGH) { // If Jets are HIGH or LOW
if (millis() - jetsStartMillis >= jetsTimeout) { // Check for timeout
jets_State = 0; // Turn OFF jets after timeout
}
}
}
if (prevJetsState != jetsState) { // Update on display if jets state changed
prevJetsState = jetsState;
displayLcd(2);
delay(50);// Update line 2 on LCD display
}
/*
LCD display Function-------------------------------------------------------------
*/
if (millis() - prevLcdUpdate >= lcdUpdateInt) { // Update the LCD display every 5 sec
prevLcdUpdate = millis();
lcd.clear();
delay(50);
displayLcd(0);
delay(50);
displayLcd(1);
delay(50);
displayLcd(2);
delay(50);
displayLcd(3);// Update all 4 lines
}
}
void displayLcd(int lineNo) {
String currTemp = "";
if (current_Temp < 53) {
currTemp = "COLD";
}
else if (current_Temp > 111) {
currTemp = "HOT";
}
else {
currTemp = String(current_Temp);
}
String line0 = "Current Temp: " + currTemp;
String line1 = "Set Temp: " + String(set_Temp);
String line2 = "Jets: " + jetsState;
String line3 = "Heat: " + heatState;
if (lineNo == 0) {
lcd.setCursor(14, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print(line0);
}
else if (lineNo == 1) {
lcd.setCursor(10, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(line1);
}
else if (lineNo == 2) {
lcd.setCursor(6, 2);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print(line2);
}
else if (lineNo == 3) {
lcd.setCursor(6, 3);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(line3);
}
else {
lcd.setCursor(0, 0);
lcd.print(line0);
lcd.setCursor(0, 1);
lcd.print(line1);
lcd.setCursor(0, 2);
lcd.print(line2);
lcd.setCursor(0, 3);
lcd.print(line3);
}
}
void takeTempReading() {
if (millis() - prevTempUpdate >= tempInterval) {
avg_Res = 0;
for (int i = 0; i < maxTempReadings; i++) {
Vout = analogRead(TempSensor);
Vout = Vout * 0.004883;
Sens_Res = (Vout * 10000) / (5 - Vout);
avg_Res = avg_Res + Sens_Res;
delay(10);
}
Sens_Res = (avg_Res / 20);
Serial.print(Sens_Res);
Serial.print(" ");
Res_Temp_Chart();
Serial.println(current_Temp);
lcd.setCursor(14, 0);
lcd.print(" ");
lcd.setCursor(14, 0);
lcd.print(current_Temp);
prevTempUpdate = millis();
displayLcd(0); // Update line 0 on LCD display
}
}
void Res_Temp_Chart() {
if (Sens_Res > 55880)
current_Temp = 50; // Temperature LOW
else if (Sens_Res < 55880 && Sens_Res > 53071)
current_Temp = 53;
else if (Sens_Res < 54455 && Sens_Res > 51726)
current_Temp = 54;
else if (Sens_Res < 53071 && Sens_Res > 50419)
current_Temp = 55;
else if (Sens_Res < 51726 && Sens_Res > 49149)
current_Temp = 56;
else if (Sens_Res < 50419 && Sens_Res > 47915)
current_Temp = 57;
else if (Sens_Res < 49149 && Sens_Res > 46716)
current_Temp = 58;
else if (Sens_Res < 47915 && Sens_Res > 45550)
current_Temp = 59;
else if (Sens_Res < 46716 && Sens_Res > 44418)
current_Temp = 60;
else if (Sens_Res < 45550 && Sens_Res > 43316)
current_Temp = 61;
else if (Sens_Res < 44418 && Sens_Res > 42245)
current_Temp = 62;
else if (Sens_Res < 43316 && Sens_Res > 41204)
current_Temp = 63;
else if (Sens_Res < 42245 && Sens_Res > 40192)
current_Temp = 64;
else if (Sens_Res < 41204 && Sens_Res > 39208)
current_Temp = 65;
else if (Sens_Res < 40192 && Sens_Res > 38251)
current_Temp = 66;
else if (Sens_Res < 39208 && Sens_Res > 37320)
current_Temp = 67;
else if (Sens_Res < 38251 && Sens_Res > 36414)
current_Temp = 68;
else if (Sens_Res < 37320 && Sens_Res > 35533)
current_Temp = 69;
else if (Sens_Res < 36414 && Sens_Res > 34676)
current_Temp = 70;
else if (Sens_Res < 35533 && Sens_Res > 33843)
current_Temp = 71;
else if (Sens_Res < 34676 && Sens_Res > 33032)
current_Temp = 72;
else if (Sens_Res < 33843 && Sens_Res > 32242)
current_Temp = 73;
else if (Sens_Res < 33032 && Sens_Res > 31474)
current_Temp = 74;
else if (Sens_Res < 32242 && Sens_Res > 30727)
current_Temp = 75;
else if (Sens_Res < 31474 && Sens_Res > 30000)
current_Temp = 76;
else if (Sens_Res < 30727 && Sens_Res > 29291)
current_Temp = 77;
else if (Sens_Res < 30000 && Sens_Res > 28602)
current_Temp = 78;
else if (Sens_Res < 29291 && Sens_Res > 27931)
current_Temp = 79;
else if (Sens_Res < 28602 && Sens_Res > 27278)
current_Temp = 80;
else if (Sens_Res < 27931 && Sens_Res > 26642)
current_Temp = 81;
else if (Sens_Res < 27278 && Sens_Res > 26023)
current_Temp = 82;
else if (Sens_Res < 26642 && Sens_Res > 25420)
current_Temp = 83;
else if (Sens_Res < 26023 && Sens_Res > 24832)
current_Temp = 84;
else if (Sens_Res < 25420 && Sens_Res > 24260)
current_Temp = 85;
else if (Sens_Res < 24832 && Sens_Res > 23703)
current_Temp = 86;
else if (Sens_Res < 24260 && Sens_Res > 23160)
current_Temp = 87;
else if (Sens_Res < 23703 && Sens_Res > 22632)
current_Temp = 88;
else if (Sens_Res < 23160 && Sens_Res > 22117)
current_Temp = 89;
else if (Sens_Res < 22632 && Sens_Res > 21615)
current_Temp = 90;
else if (Sens_Res < 22117 && Sens_Res > 21126)
current_Temp = 91;
else if (Sens_Res < 21615 && Sens_Res > 20649)
current_Temp = 92;
else if (Sens_Res < 21126 && Sens_Res > 20185)
current_Temp = 93;
else if (Sens_Res < 20649 && Sens_Res > 19733)
current_Temp = 94;
else if (Sens_Res < 20185 && Sens_Res > 19292)
current_Temp = 95;
else if (Sens_Res < 19733 && Sens_Res > 18862)
current_Temp = 96;
else if (Sens_Res < 19292 && Sens_Res > 18443)
current_Temp = 97;
else if (Sens_Res < 18862 && Sens_Res > 18034)
current_Temp = 98;
else if (Sens_Res < 18443 && Sens_Res > 19733)
current_Temp = 99;
else if (Sens_Res < 18034 && Sens_Res > 17247)
current_Temp = 100;
else if (Sens_Res < 19733 && Sens_Res > 16869)
current_Temp = 101;
else if (Sens_Res < 17247 && Sens_Res > 18443)
current_Temp = 102;
else if (Sens_Res < 16869 && Sens_Res > 16139)
current_Temp = 103;
else if (Sens_Res < 18443 && Sens_Res > 15788)
current_Temp = 104;
else if (Sens_Res < 16139 && Sens_Res > 15446)
current_Temp = 105;
else if (Sens_Res < 15788 && Sens_Res > 15112)
current_Temp = 106;
else if (Sens_Res < 15446 && Sens_Res > 14786)
current_Temp = 107;
else if (Sens_Res < 15112 && Sens_Res > 14468)
current_Temp = 108;
else if (Sens_Res < 14786 && Sens_Res > 14158)
current_Temp = 109;
else if (Sens_Res < 14468 && Sens_Res > 13855)
current_Temp = 110;
else if (Sens_Res < 14158 && Sens_Res > 13589)
current_Temp = 111;
else if (Sens_Res < 13589)
current_Temp = 112;
else
current_Temp = 120; // Temperature HIGH
}