Please help me, I still learning arduino programming. I made this code through researching.
This code works fine except for one area.... when there is something being printed to the LCD like "ERROR 03" or simply printing " " the solarAmps and solarVolts will stop updating. They can just stop like if it was 2.3 is stays like that but everything else runs well. These values are being sent by another Arduino nano through Serial. The two Nanos are running at same baud rate.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <avr/wdt.h>
// Define constants and pin mappings
const int LED_PIN = LED_BUILTIN;
const int BUZZER_PIN = 6;
const int EGS002_POWER_PIN = 8;
const int FAULT_LED_PIN = 9;
const int MPPT_LED_PIN = 10;
const int MPPT_FAN_PIN = 11;
const int STANDBY_PIN = 12;
const int OUTPUT_RELAY_PIN = 7;
const int SHUT_DOWN_PIN = 4;
const int FAN_PIN = 3;
const int FAN_SENSE_PIN = 5;
const int BUTTON_SENSE_PIN = 2;
const int MPPT_OFF_PIN = A0;
const int TEMP_PIN = A1;
const int BATT_PIN = A2;
const int AC_CURR_PIN = A3;
const int AC_VOLTS_PIN = A7;
const long MINUTE = 60000;
const long INTERVAL = 1000;
const long MPPT_INTERVAL = 1000;
const char power[] = "power";
// Define global variables
bool inverterPower = false;
bool newData = false;
bool fanError1 = false;
bool fanError2 = false;
bool lowBattWarning = false;
bool buzzerEnabled = false;
bool dischargedBelow20 = false;
bool mpptState = false;
bool error = false;
bool lowVoltsWarning = false;
bool lowBatt = false;
bool highBatt = false;
bool tempError = false;
bool fanOn = false;
bool opVoltsError = false;
bool overLoad = false;
bool overCurr = false;
bool dispError = false;
int buzzerState = LOW;
int ledState = LOW;
int mpptLedState = LOW;
int lbw = 0;
int acLowError = 0;
int acHighError = 0;
int ovLdErr = 0;
int ovLdTout = 0;
int lowBattCut = 0;
int fanError = 0;
int fanState2;
int mpptFanState = 0;
int button;
int averageCount = 0;
int acVolts = 0;
int temperature = 0;
int acCurr = 0;
float battVolts = 0.0;
float solarVolts = 0.0;
float solarAmps = 0.0;
float tempValue = 0.0;
float ampsSum = 0.0;
float voltsSum = 0.0;
float avSolarVolts = 0.0;
float avSolarAmps = 0.0;
unsigned long lastSDT = 0;
unsigned long previousMillis = 0;
unsigned long mpptPrevMillis = 0;
unsigned long onDuration = 200;
unsigned long offDuration = 200;
unsigned long rememberTime = 0;
unsigned long mpptTimer = 0;
unsigned long acVoltsTimer = 0;
unsigned long voltsErrorShut = 0;
unsigned long fanTimer = 0;
unsigned long lcdRefreshTimer = 0;
unsigned long lowBattShut = 0;
unsigned long lastFilterUpdate = 0;
unsigned long resetTimer = 0;
const unsigned filterUpdateInterval = 100;
byte batt[] = { 0b01110, 0b11011, 0b11111,
0b11111, 0b11111, 0b11111, 0b11111, 0b11111
};
byte solar[] = { 0b11111, 0b10101, 0b11111,
0b10101, 0b11111, 0b10101, 0b10101, 0b11111
};
byte acOut[] = { 0b01010, 0b01010, 0b11111, 0b11111, 0b01110, 0b00100, 0b00100, 0b00100 };
byte tempy[] = { 0b00100, 0b01010, 0b01010, 0b01110, 0b01110, 0b11111, 0b11111, 0b01110 };
byte load[] = { 0b00100, 0b00100, 0b00100, 0b11111, 0b01110, 0b00100, 0b11111, 0b11111 };
byte ampsChg[] = { 0b00010, 0b00100, 0b01000, 0b11111, 0b00010, 0b00100, 0b01000, 0b00000 };
LiquidCrystal_I2C lcd(0x27, 16, 4);
void setup() {
// Initialize pins and peripherals
analogReference(EXTERNAL);
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(EGS002_POWER_PIN, OUTPUT);
pinMode(FAULT_LED_PIN, OUTPUT);
pinMode(MPPT_LED_PIN, OUTPUT);
pinMode(STANDBY_PIN, OUTPUT);
pinMode(OUTPUT_RELAY_PIN, OUTPUT);
pinMode(SHUT_DOWN_PIN, OUTPUT);
pinMode(FAN_PIN, OUTPUT);
pinMode(FAN_SENSE_PIN, INPUT);
pinMode(BUTTON_SENSE_PIN, INPUT);
pinMode(MPPT_OFF_PIN, OUTPUT);
pinMode(TEMP_PIN, INPUT);
pinMode(BATT_PIN, INPUT);
pinMode(AC_CURR_PIN, INPUT);
pinMode(AC_VOLTS_PIN, INPUT);
pinMode(MPPT_FAN_PIN, INPUT);
digitalWrite(MPPT_OFF_PIN, HIGH);
lcd.init();
lcd.backlight();
Serial.begin(9600);
setupDisplay();
fanLocked();
//wdt_enable(WDTO_4S);
}
void loop() {
if (!mpptState) {
solarVolts = 0.0;
solarAmps = 0.0;
lcd.setCursor(11, 0);
lcd.print(solarVolts, 1);
lcd.setCursor(7, 2);
lcd.print(solarAmps, 1);
}
static unsigned long opvTimer;
static unsigned long resetOffSerial;
if (millis() - resetOffSerial > 5000) {
digitalWrite(MPPT_OFF_PIN, LOW);
}
if (battVolts < 29 && !lowBatt && !tempError && !opVoltsError && !overCurr && !overLoad && !fanError1) {
error = false;
lcd.backlight();
}
loopDisplay();
readings();
if (button == 0) {
outputVoltageMonitor();
outputLoadMonitor();
}
temperatureMornitor();
mpptCharger();
buttonPowerOff();
if (inverterPower == 0) {
acVoltsTimer = millis();
}
if (!opVoltsError) {
voltsErrorShut = millis();
}
fanState2 = digitalRead(FAN_SENSE_PIN);
mpptFanState = digitalRead(MPPT_FAN_PIN);
//Serial.print("voltsErrorShut = ");
//Serial.println(mpptState);
//Serial.print("opVoltsError = ");
//Serial.println(opVoltsError);
//Serial.print("mill-fantimer = ");
//Serial.println(millis()-fanTimer);
if (button == 0 && (millis() > 10000)) {
if (!error) {
InverterOn();
batteryMonitor();
// errorDisplay();
}
}
if (buzzerEnabled) {
buzzer();
digitalWrite(FAULT_LED_PIN, digitalRead(BUZZER_PIN));
}
if (!buzzerEnabled && button == 0) {
noBuzzer();
}
if (millis() - lcdRefreshTimer > 10 * MINUTE) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(0);
lcd.setCursor(9, 0);
lcd.write(1);
lcd.setCursor(0, 1);
lcd.write(2);
lcd.setCursor(9, 1);
lcd.write(3);
lcd.setCursor(-4, 2);
lcd.write(4);
lcd.setCursor(5, 2);
lcd.write(5);
lcdRefreshTimer = millis();
}
}
// Custom functions
void readings() {
unsigned long currentTime = millis();
if (currentTime - lastFilterUpdate >= filterUpdateInterval) {
lastFilterUpdate = currentTime;
float battValue = (analogRead(BATT_PIN) * 3.3 / 1024) * 15.44;
battVolts = (battVolts * 0.9) + (battValue * 0.1);
float acValue = (analogRead(AC_VOLTS_PIN) * 3.3 / 1024) * 174.4967;
acVolts = (acVolts * 0.9) + (acValue * 0.1);
int acCurrValue = (analogRead(AC_CURR_PIN));
//acCurrValue = acCurrValue;
acCurrValue = map(acCurrValue, 0, 1023, 0, 2400);
acCurrValue = map(acCurrValue, 0, 2400, 0, 100);
acCurr = (acCurr * 0.9) + (acCurrValue * 0.1);
tempValue = (analogRead(TEMP_PIN) * 3.3 / 1024);
tempValue = (tempValue * 0.9) + (tempValue * 0.1);
float resistance = 14000 * (1 / (tempValue / 3.3) - 1);
temperature = 1 / (0.001129833 + (0.000234848 * log(resistance)) + (0.000000085663 * pow(log(resistance), 3)));
temperature = temperature - 273.15;
temperature = temperature + 8;
}
}
void batteryMonitor() {
// low voltage warning
if (battVolts < 22 && !dischargedBelow20) {
lowVoltsWarning = true;
} else if (battVolts >= 23) {
lowVoltsWarning = false;
}
if (lowVoltsWarning) {
onDuration = 2000;
offDuration = 200;
buzzerEnabled = true;
} else {
buzzerEnabled = false;
}
if (battVolts < 20) {
buzzerEnabled = false;
lowVoltsWarning = false;
dischargedBelow20 = true;
} else if (battVolts >= 23) {
dischargedBelow20 = false;
//lowVoltsWarning = true;
}
// high voltage cut off
if (battVolts >= 30) {
highBatt = true;
}
else if (battVolts <= 28.4) {
highBatt = false;
}
if (highBatt) {
InverterOff();
onDuration = 200;
offDuration = 200;
buzzerEnabled = true;
digitalWrite(FAULT_LED_PIN, HIGH);
}
//low voltage cut off
if (!lowBatt)lowBattShut = millis();
if (battVolts < 20) {
lowBatt = true;
} else if (battVolts > 23) {
lowBatt = false;
}
if (lowBatt) {
InverterOff();
if (millis() - lowBattShut > 5000) {
lcd.noBacklight();
digitalWrite(FAULT_LED_PIN, HIGH);
}
}
}
//temperature monitor
void temperatureMornitor() {
if (temperature > 60) {
tempError = true;
} else if (temperature < 55) {
tempError = false;
}
if (tempError) {
InverterOff();
onDuration = 200;
offDuration = 200;
buzzerEnabled = true;
digitalWrite(FAULT_LED_PIN, HIGH);
}
if (temperature >= 55 && acCurr < 50) {
analogWrite(FAN_PIN, 5);
fanOn = 1;
} else if (temperature <= 50 && temperature > 45 && acCurr < 50) {
analogWrite(FAN_PIN, 50);
fanOn = 1;
} else if ((temperature <= 45 && temperature > 40)) {
analogWrite(FAN_PIN, 100);
fanOn = 1;
} else if (temperature < 45 && mpptFanState == 1) {
analogWrite(FAN_PIN, 100);
fanOn = 1;
} else if (temperature <= 35 && mpptFanState == 0) {
fanOn = 0;
digitalWrite(FAN_PIN, 1);
}
if (acCurr >= 50 && temperature > 37) {
analogWrite(FAN_PIN, 30);
fanOn = 1;
}
if (fanOn == 0) {
fanTimer = millis();
}
if (millis() - fanTimer > 10000) {
if (fanState2 == 1 && fanOn == 1) {
fanError2 = true;
if (fanError2) {
digitalWrite(FAULT_LED_PIN, 1);
error = true;
onDuration = 200;
offDuration = 200;
buzzerEnabled = true;
}
}
}
}
//output voltage mornitor
void outputVoltageMonitor() {
if (millis() - acVoltsTimer > 10000) {
if ((acVolts <= 165) || (acVolts >= 260)) {
opVoltsError = true;
}
if (opVoltsError) {
//dispError = true;
onDuration = 500;
offDuration = 500;
buzzerEnabled = true;
digitalWrite(FAULT_LED_PIN, HIGH);
//error = true;
}
if (!opVoltsError) {
voltsErrorShut = millis();
}
if (millis() - voltsErrorShut > 15000) {
InverterOff();
digitalWrite(SHUT_DOWN_PIN, HIGH);
}
}
}
//output Load Monitor
unsigned long overLoadTimer = 0;
unsigned long shortCircuitTimer = 0;
void outputLoadMonitor() {
if (!overLoad) {
overLoadTimer = millis();
}
if (acCurr >= 75 && acCurr <= 85) {
overLoad = true;
error = true;
} else if (acCurr < 75 || acCurr > 85) {
overLoad = false;
//buzzerEnabled = false;
}
if (overLoad) {
onDuration = 1000;
offDuration = 1000;
buzzerEnabled = true;
if (millis() - overLoadTimer > 10000) {
InverterOff();
delay(2000);
digitalWrite(SHUT_DOWN_PIN, HIGH);
}
}
if (!overCurr) {
shortCircuitTimer = millis();
}
if (acCurr >= 90) {
overCurr = true;
error = true;
} else if (acCurr < 90) {
if (millis() - shortCircuitTimer > 10000) {
overCurr = false;
}
}
if (overCurr) {
InverterOff();
onDuration = 50;
offDuration = 50;
buzzerEnabled = true;
}
}
void loopDisplay() {
if (acVolts <= 10)acVolts = 0;
if (solarAmps < 0)solarAmps = 0.0;
if (averageCount >= 16) {
avSolarVolts = voltsSum / averageCount;
voltsSum = 0.0;
avSolarAmps = ampsSum / averageCount;
ampsSum = 0.0;
averageCount = 0;
}
voltsSum += solarVolts;
ampsSum += solarAmps;
averageCount++;
lcd.setCursor(2, 0);
lcd.print(battVolts, 1);
lcd.setCursor(2, 1);
lcd.print(acVolts);
lcd.setCursor(-2, 2);
lcd.print(acCurr);
lcd.setCursor(11, 1);
lcd.print(temperature);
if (acCurr < 100) {
lcd.setCursor (0, 2);
lcd.print(" ");
}
if (acCurr < 10) {
lcd.setCursor (-1, 2);
lcd.print(" ");
}
if (acVolts < 100) {
lcd.setCursor (4, 1);
lcd.print(" ");
}
if (acVolts < 10) {
lcd.setCursor (3, 1);
lcd.print(" ");
}
if (avSolarAmps < 10) {
lcd.setCursor(10, 2);
lcd.print(" ");
}
if (avSolarVolts < 10) {
lcd.setCursor(14, 0);
lcd.print(" ");
}
if (newData) {
lcd.setCursor(11, 0);
lcd.print(avSolarVolts, 1);
lcd.setCursor(7, 2);
lcd.print(avSolarAmps, 1);
}
}
void mpptCharger() {
static unsigned long mpptTimer;
if (Serial.available() >= sizeof(solarAmps) + sizeof(solarVolts) + 2) {
char bytes[sizeof(solarAmps) + sizeof(solarVolts) + 2];
Serial.readBytes(bytes, sizeof(solarAmps) + sizeof(solarVolts) + 2);
newData = true;
mpptState = true;
if (bytes[0] == 0x01 && bytes[sizeof(solarAmps) + sizeof(solarVolts) + 1] == 0x04) {
memcpy(&solarAmps, bytes + 1, sizeof(solarAmps));
memcpy(&solarVolts, bytes + 1 + sizeof(solarAmps), sizeof(solarVolts));
}
lastSDT = millis();
mpptTimer = millis();
if (solarAmps > 0.01) {
mpptIndicator();
} else {
digitalWrite(MPPT_LED_PIN, 0);
}
}
else if (millis() - lastSDT > 2000) {
solarAmps = 0.0;
solarVolts = 0.0;
newData = false;
mpptState = false;
}
int button = digitalRead(BUTTON_SENSE_PIN);
if (button == 1 & millis() > 20000) {
if (millis() - mpptTimer > 10000) {
if (!inverterPower) {
digitalWrite(SHUT_DOWN_PIN, HIGH);//(MPPT_OFF_PIN, 1);
}
}
}
}
void buttonPowerOff() {
static unsigned long buttonState;
button = digitalRead(BUTTON_SENSE_PIN);
if (button == 0) buttonState = millis();
if (button == 1 && millis() - buttonState < 3000) {
lowVoltsWarning = false;
digitalWrite(BUZZER_PIN, 1);
}
if (millis() - buttonState > 5000) {
digitalWrite(BUZZER_PIN, 0);
InverterOff();
}
if (millis() - buttonState > 20000) {
if (!mpptState) {
digitalWrite(SHUT_DOWN_PIN, HIGH);
}
}
}
void InverterOn() {
//lcd.backlight();
digitalWrite(STANDBY_PIN, 1);
digitalWrite(EGS002_POWER_PIN, 1);
digitalWrite(FAULT_LED_PIN, LOW);
inverterPower = true;
if (acVolts > 170) {
inverterIndicator();
digitalWrite(OUTPUT_RELAY_PIN, 1);
}
}
void InverterOff() {
inverterPower = false;
digitalWrite(STANDBY_PIN, 0);
digitalWrite(EGS002_POWER_PIN, 0);
digitalWrite(LED_PIN, 0);
digitalWrite(OUTPUT_RELAY_PIN, 0);
}
void inverterIndicator() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= INTERVAL) {
previousMillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(LED_PIN, ledState);
}
}
void mpptIndicator() {
unsigned long mpptMillis = millis();
if (mpptMillis - mpptPrevMillis >= MPPT_INTERVAL) {
mpptPrevMillis = mpptMillis;
if (mpptLedState == LOW) {
mpptLedState = HIGH;
} else {
mpptLedState = LOW;
}
digitalWrite(MPPT_LED_PIN, mpptLedState);
}
}
void fanLocked() {
int fanState = digitalRead(FAN_SENSE_PIN);
if (fanState == 1) {
fanError1 = true;
onDuration = 200;
offDuration = 200;
buzzerEnabled = true;
if (buzzerEnabled) {
buzzer();
digitalWrite(FAULT_LED_PIN, digitalRead(BUZZER_PIN));
}
// while (true);
}
}
void setupDisplay() {
lcd.setCursor(0, 0);
lcd.print("****************");
lcd.setCursor(0, 1);
lcd.print("****************");
lcd.setCursor(-4, 2);
lcd.print("****************");
lcd.setCursor(-4, 3);
lcd.print("****************");
digitalWrite(LED_PIN, 1);
delay(200);
digitalWrite(LED_PIN, 0);
digitalWrite(MPPT_LED_PIN, 1);
delay(200);
digitalWrite(MPPT_LED_PIN, 0);
digitalWrite(FAULT_LED_PIN, 1);
delay(200);
digitalWrite(FAULT_LED_PIN, 0);
delay(200);
digitalWrite(LED_PIN, 1);
delay(200);
digitalWrite(LED_PIN, 0);
digitalWrite(MPPT_LED_PIN, 1);
delay(200);
digitalWrite(MPPT_LED_PIN, 0);
digitalWrite(FAULT_LED_PIN, 1);
delay(200);
digitalWrite(FAULT_LED_PIN, 0);
delay(200);
digitalWrite(LED_PIN, 1);
delay(200);
digitalWrite(LED_PIN, 0);
digitalWrite(MPPT_LED_PIN, 1);
delay(200);
digitalWrite(MPPT_LED_PIN, 0);
digitalWrite(FAULT_LED_PIN, 1);
delay(200);
digitalWrite(FAULT_LED_PIN, 0);
analogWrite(FAN_PIN, 100);
digitalWrite(BUZZER_PIN, 1);
digitalWrite(LED_PIN, 1);
digitalWrite(MPPT_LED_PIN, 1);
digitalWrite(FAULT_LED_PIN, 1);
lcd.clear();
delay(500);
lcd.createChar(0, batt);
lcd.createChar(1, solar);
lcd.createChar(2, acOut);
lcd.createChar(3, tempy);
lcd.createChar(4, load);
lcd.createChar(5, ampsChg);
lcd.setCursor(0, 0);
lcd.write(0);
lcd.setCursor(9, 0);
lcd.write(1);
lcd.setCursor(0, 1);
lcd.write(2);
lcd.setCursor(9, 1);
lcd.write(3);
lcd.setCursor(-4, 2);
lcd.write(4);
lcd.setCursor(5, 2);
lcd.write(5);
delay(2000);
digitalWrite(BUZZER_PIN, 0);
digitalWrite(LED_PIN, 0);
digitalWrite(MPPT_LED_PIN, 0);
digitalWrite(FAULT_LED_PIN, 0);
}
void buzzer() {
if (buzzerState == LOW) {
if ((millis() - rememberTime) >= onDuration) {
buzzerState = HIGH;
rememberTime = millis();
}
} else {
if ((millis() - rememberTime) >= offDuration) {
buzzerState = LOW;
rememberTime = millis();
}
}
digitalWrite(BUZZER_PIN, buzzerState);
}
void noBuzzer() {
digitalWrite(BUZZER_PIN, LOW);
}
void errorDisplay() {
if (lowVoltsWarning || highBatt || lowBatt || tempError || fanError1 || fanError2 || opVoltsError || overLoad || overCurr) {
error = true;
} else if (!lowVoltsWarning && !highBatt && !lowBatt && !tempError && !fanError1 && !fanError2 && !opVoltsError && !overLoad && !overCurr) {
error = false;
}
if (error) {
if (lowVoltsWarning) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [64]");
}
else if (highBatt) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [03]");
}
else if (lowBatt) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [04]");
}
else if (tempError) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [27]");
}
else if (fanError2) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [61]");
}
else if ((acVolts < 165) && (millis() - acVoltsTimer > 10000)) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [58]");
}
else if (acVolts > 260) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [06]");
}
else if (overLoad) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [67]");
}
else if (millis() - overLoadTimer > 10000) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [07]");
}
else if (overCurr) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [05]");
}
else if (fanError1) {
lcd.setCursor(-1, 3);
lcd.print("ERROR [01]");
}
}
else if (!error) {
lcd.setCursor(-1, 3);
lcd.print(" ");
}
}
Thank you in advance.