#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#define AddressArray 2 // Total number of addresses to scan
#define ScanPreRegCheckDelta 5000 // Delay in milliseconds between scan attempts
#define ONE_WIRE_BUS1 2//coolant temp rad supply
#define ONE_WIRE_BUS2 3//coolant temp rad return
//coolant radiator temps
OneWire TempCoolant_1(ONE_WIRE_BUS1);
OneWire TempCoolant_2(ONE_WIRE_BUS2);
DallasTemperature sensors1(&TempCoolant_1);
DallasTemperature sensors2(&TempCoolant_2);
LiquidCrystal_I2C lcd_1(0x27, 20, 4); //Address and LengthxWidth LCD_1
LiquidCrystal_I2C lcd_2(0x26, 20, 4); //Address and LengthxWidth LCD_2
byte SpecifiedAddresses[AddressArray] = {0x27, 0x26};
int addressCheck = 0;
int addressCheck_FAIL = 0;
int addressFailRetry = 3;
int SystemRun = 0;
int CoolantAHH = 0;
int CoolantReturnTemp = 60;
int CoolantSupplyTemp = 90;
const int buttonReset = 4;
const int ledFault = 13;
//main init
void setup() {
Wire.begin();
Serial.begin(9600);
while (!Serial);
Serial.println("\nI2C Scanner & Address Checker");
sensors1.begin();
sensors2.begin();
LCD_1_Boot();
LCD_2_Boot();
pinMode(buttonReset, INPUT);
pinMode(ledFault, OUTPUT);
}
//main loop body
void loop() {
if (addressCheck == 0 && addressFailRetry != 0 ) {
scanAddresses();
if (addressFailRetry <= 0) {
LCD_BootBypass();
}
}
//main runtime if statement
if (SystemRun >= 1) {
sensors1.requestTemperatures();
sensors2.requestTemperatures();
LCD_SystemRunLCD_1();
delay(800);
}
if (CoolantAHH >= 1){
lcd_1.setCursor(4, 3);
lcd_1.print("Temp Alarm HH");
digitalWrite(ledFault, HIGH);
pinMode(LED_BUILTIN, OUTPUT);
delay(350);
}
if (digitalRead(buttonReset) == HIGH) { //Alarm Anunciator RESET
Serial.println ("Reset");
CoolantAHH = 0;
lcd_1.setCursor(2, 3);
lcd_1.print(" ");
digitalWrite(ledFault, LOW);//Acked Warning Flasher
}
}
void scanAddresses() {
delay(ScanPreRegCheckDelta);
bool allAddressesFound = true;
for (int i = 0; i < AddressArray; i++) {
byte address = SpecifiedAddresses[i];
Wire.beginTransmission(address);
byte error = Wire.endTransmission();
if (error == 0) {
Serial.print("Device found at address 0x");
if (address < 16) {
Serial.print("0");
}
Serial.println(address, HEX);
} else {
allAddressesFound = false;
}
}
if (allAddressesFound) {
Serial.println("All addresses found. Completed.");
LCDTestInit_PASS();
} else {
Serial.println("Some addresses not found.");
LCDTestInit_FAIL();
addressFailRetry --;
}
}
//Addressing check PASS
void LCDTestInit_PASS() {
addressCheck++;
digitalWrite(ledFault, HIGH);//LED Test ON
pinMode(LED_BUILTIN, OUTPUT);
lcd_1.noBacklight();
lcd_2.noBacklight();
lcd_1.clear();
lcd_2.clear();
delay(200);
lcd_1.backlight();
lcd_2.backlight();
lcd_1.setCursor(4, 1);
lcd_2.setCursor(4, 1);
lcd_1.print("System Pass");
lcd_2.print("System Pass");
delay(3000);//after all screens run Boot Seq then move on to next phase.
digitalWrite(ledFault, LOW);//LED Test OFF
SystemRun++;
}
//Addressing check FAIL
void LCDTestInit_FAIL() {
addressCheck_FAIL++;
lcd_1.noBacklight();
lcd_2.noBacklight();
lcd_1.clear();
lcd_2.clear();
lcd_1.backlight();
lcd_2.backlight();
lcd_1.setCursor(3, 0);
lcd_2.setCursor(3, 0);
lcd_1.print("System Fail");
lcd_2.print("System Fail");
lcd_1.setCursor(3, 1);
lcd_2.setCursor(3, 1);
lcd_1.print("Retry in 5s");
lcd_2.print("Retry in 5s");
lcd_1.setCursor(3, 2);
lcd_2.setCursor(3, 2);
lcd_1.print("AttemptsLeft/");
lcd_1.print(addressFailRetry);
lcd_2.print("AttemptsLeft/");
lcd_2.print(addressFailRetry);
lcd_1.setCursor(1, 3);
lcd_2.setCursor(1, 3);
lcd_1.print("LCD Fault Detected");
lcd_2.print("LCD Fault Detected");
if (addressFailRetry == 0) {
LCD_BootBypass;
}
}
void LCD_1_Boot() { //boot sequence and test for LCD 1
lcd_1.begin(20, 4);
lcd_1.backlight();
delay(200);
lcd_1.setCursor(3, 0); //phase_1 load lcd_1
delay(300);
lcd_1.print("LCD Display 1");
lcd_1.setCursor(3, 1); //phase_2 load lcd_1
delay(300);
lcd_1.print("LCD Initialise");
lcd_1.setCursor(3, 2); //phase_3 load lcd_1
delay(300);
lcd_1.print("LCD Light Test");
}
void LCD_2_Boot() { //boot sequence and test for LCD 2
lcd_2.begin(20, 4);
lcd_2.backlight();
delay(200);
lcd_2.setCursor(3, 0); //phase_1 load lcd_2
delay(300);
lcd_2.print("LCD Display 2");
lcd_2.setCursor(3, 1); //phase_2 load lcd_2
delay(300);
lcd_2.print("LCD Initialise");
lcd_2.setCursor(3, 2); //phase_3 load lcd_2
delay(300);
lcd_2.print("LCD Light Text");
}
void LCD_BootBypass() { //continue boot sequence even with bad LCD detected
delay(3000);
digitalWrite(ledFault, HIGH);//LED Test ON
pinMode(LED_BUILTIN, OUTPUT);
lcd_1.clear();
lcd_2.clear();
lcd_1.setCursor(3, 0);
lcd_2.setCursor(3, 0);
lcd_1.print("Continue Boot");
lcd_2.print("Continue Boot");
lcd_1.setCursor(3, 1);
lcd_2.setCursor(3, 1);
lcd_1.print("With Bad LCD");
lcd_2.print("With Bad LCD");
lcd_1.setCursor(3, 2);
lcd_2.setCursor(3, 2);
lcd_1.print("Detected!");
lcd_2.print("Detected!");
lcd_1.setCursor(3, 3);
lcd_2.setCursor(3, 3);
lcd_1.print("Warning: Error");
lcd_2.print("Warning: Error");
delay(4000);
digitalWrite(ledFault, LOW);//LED Test OFF
lcd_1.clear();
lcd_2.clear();
SystemRun++;
}
void LCD_SystemRunLCD_1() {
if ( sensors1.getTempCByIndex(0) >= CoolantSupplyTemp || sensors2.getTempCByIndex(0) >= CoolantReturnTemp) {
CoolantAHH = 1;
lcd_1.setCursor(2, 3);
lcd_1.print(" ");
digitalWrite(ledFault, LOW);
}
lcd_1.setCursor(2, 0);
lcd_1.print("Rad Coolant Temp");
lcd_1.setCursor(0, 1);
lcd_1.print("Rad Inlet-");
lcd_1.print(" ");
lcd_1.print(" ");
lcd_1.setCursor(0, 1);
lcd_1.print("Rad Inlet-");
lcd_1.print(sensors1.getTempCByIndex(0));
lcd_1.print(":C");
lcd_1.setCursor(0, 2);
lcd_1.print("Rad Outlet-");
lcd_1.print(" ");
lcd_1.print(" ");
lcd_1.setCursor(0, 2);
lcd_1.print("Rad Outlet-");
lcd_1.print(sensors2.getTempCByIndex(0));
lcd_1.print(":C");
}