From 550141b4da00cf10f100bb7840f5fb3a285c6918 Mon Sep 17 00:00:00 2001 From: TechBuilder <89338379+AngeloCasi@users.noreply.github.com> Date: Sun, 22 Aug 2021 17:46:48 +0800 Subject: [PATCH] Add files via upload --- 2_Read_Sensors.ino | 86 +++++++ 3_Device_Protection.ino | 24 ++ 4_Charging_Algorithm.ino | 74 ++++++ 5_System_Processes.ino | 91 +++++++ 6_Onboard_Telemetry.ino | 82 +++++++ 7_Wireless_Telemetry.ino | 43 ++++ 8_LCD_Menu.ino | 436 +++++++++++++++++++++++++++++++++ ARDUINO_MPPT_FIRMWARE_V1.0.ino | 296 ++++++++++++++++++++++ 8 files changed, 1132 insertions(+) create mode 100644 2_Read_Sensors.ino create mode 100644 3_Device_Protection.ino create mode 100644 4_Charging_Algorithm.ino create mode 100644 5_System_Processes.ino create mode 100644 6_Onboard_Telemetry.ino create mode 100644 7_Wireless_Telemetry.ino create mode 100644 8_LCD_Menu.ino create mode 100644 ARDUINO_MPPT_FIRMWARE_V1.0.ino diff --git a/2_Read_Sensors.ino b/2_Read_Sensors.ino new file mode 100644 index 0000000..90c8a39 --- /dev/null +++ b/2_Read_Sensors.ino @@ -0,0 +1,86 @@ +void ADC_SetGain(){ + if(ADS1015_Mode==true){ //FOR ADS1015 12-BIT ADC MODEL + if(ADC_GainSelect==0){ads.setGain(GAIN_TWOTHIRDS);ADC_BitReso=3.0000;} // Gain: 2/3x Range: +/- 6.144V + else if(ADC_GainSelect==1){ads.setGain(GAIN_ONE);ADC_BitReso=2.0000;} // Gain: 1x Range: +/- 4.096V + else if(ADC_GainSelect==2){ads.setGain(GAIN_TWO);ADC_BitReso=1.0000;} // Gain: 2x Range: +/- 2.048V + } + else{ //FOR ADS1115 16-BIT ADC MODEL + if(ADC_GainSelect==0){ads.setGain(GAIN_TWOTHIRDS);ADC_BitReso= 0.1875;} // Gain: 2/3x Range: +/- 6.144V + else if(ADC_GainSelect==1){ads.setGain(GAIN_ONE);ADC_BitReso= 0.125;} // Gain: 1x Range: +/- 4.096V + else if(ADC_GainSelect==2){ads.setGain(GAIN_TWO);ADC_BitReso= 0.0625;} // Gain: 2x Range: +/- 2.048V + } +} +void resetVariables(){ + secondsElapsed = 0; + energySavings = 0; + daysRunning = 0; + timeOn = 0; +} +void Read_Sensors(){ + + /////////// TEMPERATURE SENSOR ///////////// + if(sampleStoreTS<=avgCountTS){ //TEMPERATURE SENSOR - Lite Averaging + TS = TS + analogRead(TempSensor); + sampleStoreTS++; + } + else{ + TS = TS/sampleStoreTS; + TSlog = log(9000.00*(4095.00/TS-1.00)); + temperature = (1.0/(1.009249522e-03+2.378405444e-04*TSlog+2.019202697e-07*TSlog*TSlog*TSlog))-273.15; + sampleStoreTS = 0; + TS = 0; + } + /////////// VOLTAGE & CURRENT SENSORS ///////////// + VSI = 0.0000; //Clear Previous Input Voltage + VSO = 0.0000; //Clear Previous Output Voltage + CSI = 0.0000; //Clear Previous Current + + //VOLTAGE SENSOR - Instantenous Averaging + for(int i = 0; i100){batteryPercent=100;} + + //TIME DEPENDENT SENSOR DATA COMPUTATION + currentRoutineMillis = millis(); + if(currentRoutineMillis-prevRoutineMillis>=millisRoutineInterval){ //Run routine every millisRoutineInterval (ms) + prevRoutineMillis = currentRoutineMillis; //Store previous time + Wh = Wh+(powerInput/(3600.000*(1000.000/millisRoutineInterval))); //Accumulate and compute energy harvested (3600s*(1000/interval)) + kWh = Wh/1000.000; + MWh = Wh/1000000.000; + daysRunning = timeOn/(86400.000*(1000.000/millisRoutineInterval)); //Compute for days running (86400s*(1000/interval)) + timeOn++; //Increment time counter + } + + //OTHER DATA + secondsElapsed = millis()/1000; //Gets the time in seconds since the was turned on and active + energySavings = electricalPrice*(Wh/1000.0000); //Computes the solar energy saving in terms of money (electricity flag rate) +} diff --git a/3_Device_Protection.ino b/3_Device_Protection.ino new file mode 100644 index 0000000..5e52480 --- /dev/null +++ b/3_Device_Protection.ino @@ -0,0 +1,24 @@ +void Device_Protection(){ + //ERROR COUNTER RESET + currentRoutineMillis = millis(); + if(currentErrorMillis-prevErrorMillis>=errorTimeLimit){ //Run routine every millisErrorInterval (ms) + prevErrorMillis = currentErrorMillis; //Store previous time + if(errorCountvoltageOutput+voltageDropout||MPPT_Mode==0){bypassEnable=1;} //Normal Condition - Turn on Backflow MOSFET (on by default when not in MPPT charger mode) + else{bypassEnable=0;} //Input Undervoltage - Turn off bypass MOSFET and prevent PV Backflow (SS) + digitalWrite(backflow_MOSFET,bypassEnable); //Signal backflow MOSFET GPIO pin + + //FAULT DETECTION + ERR=0; //Reset local error counter + if(temperature>temperatureMax) {OTE=1;ERR++;errorCount++;}else{OTE=0;} //OTE - OVERTEMPERATURE: System overheat detected + if(voltageOutputcurrentInAbsolute) {IOC=1;ERR++;errorCount++;}else{IOC=0;} //IOC - INPUT OVERCURRENT: Input current has reached absolute limit + if(currentOutput>currentOutAbsolute) {OOC=1;ERR++;errorCount++;}else{OOC=0;} //OOC - OUTPUT OVERCURRENT: Output current has reached absolute limit + if(voltageInputvoltageBatteryMax+voltageBatteryThresh) {OOV=1;ERR++;errorCount++;}else{OOV=0;} //OOV - OUTPUT OVERVOLTAGE: Output voltage has reached absolute limit + if(voltageInputpwmMaxLimited){PPWM=pwmMaxLimited;} //PPWM Exceeded allowable PWM ceiling; Limit PPWM to maximum allowable PWM value + else if(PPWM<0){PPWM=0;} //PPWM Exceeded allowable PWM floor value; Limit PPWM to 0 + } + + else{ //PPWM Enabled (MPPT Mode) - PPWM is set to 0 (maximum PWM floor will be set to 0) + if(voltageInput<=0){PPWM=0;} //Prevents Indefinite Answer when voltageInput is zero + else{PPWM=(PPWM_margin*pwmMax*voltageOutput)/(100.00*voltageInput);} //Compute for predictive PWM Floor and store in variable + if(PPWM>pwmMaxLimited){PPWM=pwmMaxLimited;} //PPWM Exceeded allowable PWM ceiling; Limit PPWM to maximum allowable PWM value + else if(PPWM<0){PPWM=0;} //PPWM Exceeded allowable PWM floor value; Limit PPWM to 0 + } +} + +void Charging_Algorithm(){ + if(ERR>0||chargingPause==1){buck_Disable();} //ERROR PRESENT - Turn off MPPT buck when error is present or when chargingPause is used for a pause override + else{ //NO ERROR FOUND - Resume to normal operation + if(REC==1&&MPPT_Mode==1){ //IUV RECOVERY - (Only active for MPPT mode) + REC=0; //Reset IUV recovery boolean identifier + buck_Disable(); //Disable buck before PPWM initialization + Serial.println("> Solar Panel Detected"); //Display serial message + Serial.print("> Computing For Predictive PWM "); //Display serial message + for(int i = 0; i<20; i++){Serial.print(".");delay(20);} //For loop "loading... effect + Serial.println(""); //Display a line break on serial for next lines + Read_Sensors(); + predictivePWM(); + PWM = PPWM; + } + //NORMAL OPERATION + else{ + buck_Enable(); + /////////////////////// MPPT & CC-CV CHARGING ALGORITHM /////////////////////// + if(currentOutput>currentCharging){PWM--;} //Current Is Above → Decrease Duty Cycle + else if(voltageOutput>voltageBatteryMax){PWM--;} //Voltage Is Above → Decrease Duty Cycle + else if(voltageOutputpowerInputPrev && voltageInput>voltageInputPrev) {PWM--;} // ↑P ↑V ; →MPP //D-- + else if(powerInput>powerInputPrev && voltageInputvoltageInputPrev){PWM++;} // ↓P ↑V ; MPP→ //D++ + else if(powerInputpwmMaxLimited){PWM=pwmMaxLimited;} //PWM Ceiling Limiter - Limits maximum PWM value + else if(PWM=temperatureFan){fanStatus=1;} //Turn on fan when set fan temp reached + else if(temperature1) {resetVariables();} //Daily Reset + else if(telemCounterReset==2 && daysRunning>7) {resetVariables();} //Weekly Reset + else if(telemCounterReset==3 && daysRunning>30) {resetVariables();} //Monthly Reset + else if(telemCounterReset==4 && daysRunning>365){resetVariables();} //Yearly Reset + + ///////////// LOW POWER MODE ///////////// + if(lowPowerMode==1){} + else{} +} + +void loadSettings(){ + MPPT_Mode = EEPROM.read(0); // Load saved charging mode setting + voltageBatteryMax = EEPROM.read(1)+(EEPROM.read(2)*.01); // Load saved maximum battery voltage setting + voltageBatteryMin = EEPROM.read(3)+(EEPROM.read(4)*.01); // Load saved minimum battery voltage setting + currentCharging = EEPROM.read(5)+(EEPROM.read(6)*.01); // Load saved charging current setting + enableFan = EEPROM.read(7); // Load saved fan enable settings + temperatureFan = EEPROM.read(8); // Load saved fan temperature settings + temperatureMax = EEPROM.read(9); // Load saved shutdown temperature settings + enableWiFi = EEPROM.read(10); // Load saved WiFi enable settings + flashMemLoad = EEPROM.read(11); // Load saved flash memory autoload feature +} + +void saveSettings(){ + int conv1, conv2; //Temporary float to integer converters + EEPROM.write(0,MPPT_Mode); //STORE: Charge Mode + conv1 = voltageBatteryMax*100; //STORE: Maximum Battery Voltage (gets whole number) + conv2 = conv1%100; //STORE: Maximum Battery Voltage (gets decimal number and converts to a whole number) + EEPROM.write(1,voltageBatteryMax); + EEPROM.write(2,conv2); + conv1 = voltageBatteryMin*100; //STORE: Minimum Battery Voltage (gets whole number) + conv2 = conv1%100; //STORE: Minimum Battery Voltage (gets decimal number and converts to a whole number) + EEPROM.write(3,voltageBatteryMin); + EEPROM.write(4,conv2); + conv1 = currentCharging*100; //STORE: Charging Current + conv2 = conv1%100; + EEPROM.write(5,currentCharging); + EEPROM.write(6,conv2); + EEPROM.write(7,enableFan); //STORE: Fan Enable + EEPROM.write(8,temperatureFan); //STORE: Fan Temp + EEPROM.write(9,temperatureMax); //STORE: Shutdown Temp + EEPROM.write(10,enableWiFi); //STORE: Enable WiFi +//EEPROM.write(11,flashMemLoad); //STORE: Enable autoload (must be excluded from bulk save, uncomment under discretion) + EEPROM.commit(); //Saves setting changes to flash memory +} +void saveAutoloadSettings(){ + EEPROM.write(11,flashMemLoad); //STORE: Enable autoload + EEPROM.commit(); //Saves setting changes to flash memory +} + +void factoryReset(){ + EEPROM.write(0,1); //STORE: MPPT Mode (bool) + EEPROM.write(1,12); //STORE: Max Battery Voltage (float whole) + EEPROM.write(2,0); //STORE: Max Battery Voltage (float decimal) + EEPROM.write(3,10); //STORE: Min Battery Voltage (float whole) + EEPROM.write(4,0); //STORE: Min Battery Voltage (float decimal) + EEPROM.write(5,30); //STORE: Charging Current (float whole) + EEPROM.write(6,0); //STORE: Charging Current (float decimal) + EEPROM.write(7,1); //STORE: Fan Enable (Bool) + EEPROM.write(8,60); //STORE: Fan Temp (Integer) + EEPROM.write(9,90); //STORE: Shutdown Temp (Integer) + EEPROM.write(10,1); //STORE: Enable WiFi (Boolean) + EEPROM.write(11,1); //STORE: Enable autoload (on by default) + EEPROM.commit(); + loadSettings(); +} +void initializeFlashAutoload(){ + if(disableFlashAutoLoad==0){ + flashMemLoad = EEPROM.read(11); //Load saved WiFi enable settings + if(flashMemLoad==1){loadSettings();} //Load stored settings from flash memory + } +} diff --git a/6_Onboard_Telemetry.ino b/6_Onboard_Telemetry.ino new file mode 100644 index 0000000..11c29f8 --- /dev/null +++ b/6_Onboard_Telemetry.ino @@ -0,0 +1,82 @@ +void Onboard_Telemetry(){ + + /////////////////////// USB SERIAL DATA TELEMETRY //////////////////////// + // 0 - Disable Serial + // 1 - Display All + // 2 - Display Essential Data + // 3 - Display Numbers Only + + currentSerialMillis = millis(); + if(currentSerialMillis-prevSerialMillis>=millisSerialInterval){ //Run routine every millisRoutineInterval (ms) + prevSerialMillis = currentSerialMillis; //Store previous time + + if(serialTelemMode==0){} +// else if(chargingPause==1){Serial.println("CHARGING PAUSED");} // Charging paused message + else if(serialTelemMode==1){ // 1 - Display All + Serial.print(" ERR:"); Serial.print(ERR,0); + Serial.print(" FLV:"); Serial.print(FLV,0); + Serial.print(" BNC:"); Serial.print(BNC,0); + Serial.print(" IUV:"); Serial.print(IUV,0); + Serial.print(" IOC:"); Serial.print(IOC,0); + Serial.print(" OOV:"); Serial.print(OOV,0); + Serial.print(" OOC:"); Serial.print(OOC,0); + Serial.print(" OTE:"); Serial.print(OTE,0); + Serial.print(" "); + Serial.print(" BYP:"); Serial.print(bypassEnable); + Serial.print(" EN:"); Serial.print(buckEnable); + Serial.print(" FAN:"); Serial.print(fanStatus); + Serial.print(" WiFi:"); Serial.print(WIFI); + Serial.print(" "); + Serial.print(" PI:"); Serial.print(powerInput,0); + Serial.print(" PWM:"); Serial.print(PWM); + Serial.print(" PPWM:"); Serial.print(PPWM); + Serial.print(" VI:"); Serial.print(voltageInput,1); + Serial.print(" VO:"); Serial.print(voltageOutput,1); + Serial.print(" CI:"); Serial.print(currentInput,2); + Serial.print(" CO:"); Serial.print(currentOutput,2); + Serial.print(" Wh:"); Serial.print(Wh,2); + Serial.print(" Temp:"); Serial.print(temperature,1); + Serial.print(" "); + Serial.print(" CSMPV:"); Serial.print(currentMidPoint,3); + Serial.print(" CSV:"); Serial.print(CSI_converted,3); + Serial.print(" VO%Dev:"); Serial.print(outputDeviation,1); + Serial.print(" SOC:"); Serial.print(batteryPercent);Serial.print("%"); + Serial.print(" T:"); Serial.print(secondsElapsed); + Serial.print(" LoopT:"); Serial.print(loopTime,3);Serial.print("ms"); + Serial.println(""); + } + else if(serialTelemMode==2){ // 2 - Display Essential Data + Serial.print(" PI:"); Serial.print(powerInput,0); + Serial.print(" PWM:"); Serial.print(PWM); + Serial.print(" PPWM:"); Serial.print(PPWM); + Serial.print(" VI:"); Serial.print(voltageInput,1); + Serial.print(" VO:"); Serial.print(voltageOutput,1); + Serial.print(" CI:"); Serial.print(currentInput,2); + Serial.print(" CO:"); Serial.print(currentOutput,2); + Serial.print(" Wh:"); Serial.print(Wh,2); + Serial.print(" Temp:"); Serial.print(temperature,1); + Serial.print(" EN:"); Serial.print(buckEnable); + Serial.print(" FAN:"); Serial.print(fanStatus); + Serial.print(" SOC:"); Serial.print(batteryPercent);Serial.print("%"); + Serial.print(" T:"); Serial.print(secondsElapsed); + Serial.print(" LoopT:"); Serial.print(loopTime,3);Serial.print("ms"); + Serial.println(""); + } + else if(serialTelemMode==3){ // 3 - Display Numbers Only + Serial.print(" "); Serial.print(powerInput,0); + Serial.print(" "); Serial.print(voltageInput,1); + Serial.print(" "); Serial.print(voltageOutput,1); + Serial.print(" "); Serial.print(currentInput,2); + Serial.print(" "); Serial.print(currentOutput,2); + Serial.print(" "); Serial.print(Wh,2); + Serial.print(" "); Serial.print(temperature,1); + Serial.print(" "); Serial.print(buckEnable); + Serial.print(" "); Serial.print(fanStatus); + Serial.print(" "); Serial.print(batteryPercent); + Serial.print(" "); Serial.print(secondsElapsed); + Serial.print(" "); Serial.print(loopTime,3); + Serial.print(" "); Serial.println(""); + } + + } +} diff --git a/7_Wireless_Telemetry.ino b/7_Wireless_Telemetry.ino new file mode 100644 index 0000000..2e455c2 --- /dev/null +++ b/7_Wireless_Telemetry.ino @@ -0,0 +1,43 @@ +void setupWiFi(){ + if(enableWiFi==1){ + Blynk.begin(auth,ssid,pass); + WIFI = 1; + } +} + +void Wireless_Telemetry(){ + + ////////// WIFI TELEMETRY ////////// + if(enableWiFi==1){ + int LED1, LED2, LED3, LED4; //Declare LED brightness variable + if(buckEnable==1) {LED1=200;}else{LED1=0;} //BATTERY CHARGING STATUS + if(batteryPercent>=99 ){LED2=200;}else{LED2=0;} //FULL CHARGE STATUS + if(batteryPercent<=10) {LED3=200;}else{LED3=0;} //LOW BATTERY STATUS + if(IUV==0) {LED4=200;}else{LED4=0;} //PV INPUT PRESENCE STATUS + + Blynk.run(); + Blynk.virtualWrite(1,powerInput); + Blynk.virtualWrite(2,batteryPercent); + Blynk.virtualWrite(3,voltageInput); + Blynk.virtualWrite(4,currentInput); + Blynk.virtualWrite(5,voltageOutput); + Blynk.virtualWrite(6,currentOutput); + Blynk.virtualWrite(7,temperature); + Blynk.virtualWrite(8,Wh/1000); + Blynk.virtualWrite(9,energySavings); + Blynk.virtualWrite(10,LED1); //LED - Battery Charging Status + Blynk.virtualWrite(11,LED2); //LED - Full Battery Charge Status + Blynk.virtualWrite(12,LED3); //LED - Low Battery Charge Status + Blynk.virtualWrite(13,LED4); //LED - PV Harvesting + + Blynk.virtualWrite(14,voltageBatteryMin); //Minimum Battery Voltage (Read & Write) + Blynk.virtualWrite(15,voltageBatteryMax); //Maximum Battery Voltage (Read & Write) + Blynk.virtualWrite(16,currentCharging); //Charging Current (Read & Write) + Blynk.virtualWrite(17,electricalPrice); //Electrical Price (Write) + } + ////////// WIFI TELEMETRY ////////// + if(enableBluetooth==1){ + //ADD BLUETOOTH CODE + } + +} diff --git a/8_LCD_Menu.ino b/8_LCD_Menu.ino new file mode 100644 index 0000000..3f17c5b --- /dev/null +++ b/8_LCD_Menu.ino @@ -0,0 +1,436 @@ +void padding100(int padVar){ + if(padVar<10){lcd.print(" ");} + else if(padVar<100){lcd.print(" ");} +} +void padding10(int padVar){ + if(padVar<10){lcd.print(" ");} +} + +void displayConfig1(){ + lcd.setCursor(0,0);lcd.print(powerInput,0);lcd.print("W");padding100(powerInput); + lcd.setCursor(5,0); + if(Wh<10){lcd.print(Wh,3);lcd.print("Wh");} //9.999Wh + else if(Wh<100){lcd.print(Wh,2);lcd.print("Wh");} //99.99Wh + else if(Wh<1000){lcd.print(Wh,1);lcd.print("Wh");} //999.9Wh + else if(Wh<10000){lcd.print(kWh,2);lcd.print("kWh");} //9.99kWh + else if(Wh<100000){lcd.print(kWh,1);lcd.print("kWh");} //99.9kWh + else if(Wh<1000000){lcd.print(kWh,0);lcd.print("kWh ");} //999kWh_ + else if(Wh<10000000){lcd.print(MWh,2);lcd.print("MWh");} //9.99MWh + else if(Wh<100000000){lcd.print(MWh,1);lcd.print("MWh");} //99.9MWh + else if(Wh<1000000000){lcd.print(MWh,0);lcd.print("MWh ");} //999MWh_ + lcd.setCursor(13,0);lcd.print(daysRunning,3); + lcd.setCursor(0,1);lcd.print(batteryPercent); lcd.print("%");padding100(batteryPercent); + if(BNC==0){lcd.setCursor(5,1); lcd.print(voltageOutput,1);lcd.print("V");padding10(voltageOutput);} + else{lcd.setCursor(5,1);lcd.print("NOBAT");} + lcd.setCursor(11,1);lcd.print(currentOutput,1);lcd.print("A");padding10(currentOutput); +} +void displayConfig2(){ + lcd.setCursor(0,0); lcd.print(powerInput,0); lcd.print("W");padding100(powerInput); + lcd.setCursor(5,0); lcd.print(voltageInput,1);lcd.print("V");padding10(voltageInput); + lcd.setCursor(11,0);lcd.print(currentInput,1);lcd.print("A");padding10(currentInput); + lcd.setCursor(0,1); lcd.print(batteryPercent);lcd.print("%");padding100(batteryPercent); + if(BNC==0){lcd.setCursor(5,1); lcd.print(voltageOutput,1);lcd.print("V");padding10(voltageOutput);} + else{lcd.setCursor(5,1);lcd.print("NOBAT");} + lcd.setCursor(11,1);lcd.print(currentOutput,1);lcd.print("A");padding10(currentOutput); +} +void displayConfig3(){ + lcd.setCursor(0,0); lcd.print(powerInput,0);lcd.print("W");padding100(powerInput); + lcd.setCursor(5,0); + if(Wh<10){lcd.print(Wh,2);lcd.print("Wh");} //9.99Wh + else if(Wh<100){lcd.print(Wh,1);lcd.print("Wh");} //99.9Wh + else if(Wh<1000){lcd.print(Wh,0);lcd.print("Wh ");} //999Wh_ + else if(Wh<10000){lcd.print(kWh,1);lcd.print("kWh");} //9.9kWh + else if(Wh<100000){lcd.print(kWh,0);lcd.print("kWh ");} //99kWh_ + else if(Wh<1000000){lcd.print(kWh,0);lcd.print("kWh");} //999kWh + else if(Wh<10000000){lcd.print(MWh,1);lcd.print("MWh");} //9.9MWh + else if(Wh<100000000){lcd.print(MWh,0);lcd.print("MWh ");} //99MWh_ + else if(Wh<1000000000){lcd.print(MWh,0);lcd.print("MWh");} //999Mwh + lcd.setCursor(12,0);lcd.print(batteryPercent);lcd.print("%");padding100(batteryPercent); + int batteryPercentBars; + batteryPercentBars = batteryPercent/6.18; //6.25 proper value + lcd.setCursor(0,1); + for(int i=0;isubMenuPages){subMenuPage=0;} + else if(subMenuPage<0){subMenuPage=subMenuPages;} + //--------------------------- SETTINGS MENU PAGES: ---------------------------// + ///// SETTINGS MENU ITEM: CHARGING MODE ///// + if(subMenuPage==0){ + lcd.setCursor(0,0);lcd.print("CHARGING MODE "); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + if(MPPT_Mode==1){lcd.print("MPPT CHARGER ");} + else{lcd.print("CC-CV BUCK PSU");} + + //SET MENU - BOOLTYPE + if(setMenuPage==0){boolTemp = MPPT_Mode;} + else{ + if(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){ + while(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){} + if(MPPT_Mode==1){MPPT_Mode=0;}else{MPPT_Mode=1;} + } + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}MPPT_Mode = boolTemp;cancelledMessageLCD();setMenuPage=0;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveSettings();setMenuPage=0;savedMessageLCD();} + } + } + ///// SETTINGS MENU ITEM: MAX BATTERY V ///// + else if(subMenuPage==1){ + lcd.setCursor(0,0);lcd.print("MAX BATTERY V "); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + lcd.setCursor(2,1);lcd.print(voltageBatteryMax,2);lcd.print("V"); + lcd.print(" "); + + //SET MENU - FLOATTYPE + if(setMenuPage==0){floatTemp = voltageBatteryMax;} + else{ + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}voltageBatteryMax = floatTemp;cancelledMessageLCD();setMenuPage=0;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveSettings();setMenuPage=0;savedMessageLCD();} + currentMenuSetMillis = millis(); + if(digitalRead(buttonRight)==1){ //Right button press (increments setting values) + while(digitalRead(buttonRight)==1){ + if(millis()-currentMenuSetMillis>longPressTime){ //Long Press + voltageBatteryMax += 1.00; //Increment by 1 + voltageBatteryMax = constrain(voltageBatteryMax,vOutSystemMin,vOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(voltageBatteryMax,2);delay(longPressInterval); //Display settings data + } + else{ //Short Press + voltageBatteryMax += 0.01; //Increment by 0.01 + voltageBatteryMax = constrain(voltageBatteryMax,vOutSystemMin,vOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(voltageBatteryMax,2);delay(shortPressInterval); //Display settings data + } + lcd.print("V "); //Display unit + } + } + else if(digitalRead(buttonLeft)==1){ //Left button press (decrements setting values) + while(digitalRead(buttonLeft)==1){ + if(millis()-currentMenuSetMillis>longPressTime){ //Long Press + voltageBatteryMax -= 1.00; //Increment by 1 + voltageBatteryMax = constrain(voltageBatteryMax,vOutSystemMin,vOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(voltageBatteryMax,2);delay(longPressInterval); //Display settings data + } + else{ //Short Press + voltageBatteryMax -= 0.01; //Increment by 0.01 + voltageBatteryMax = constrain(voltageBatteryMax,vOutSystemMin,vOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(voltageBatteryMax,2);delay(shortPressInterval); //Display settings data + } + lcd.print("V "); //Display unit + } + } + } + } + ///// SETTINGS MENU ITEM: MIN BATTERY V ///// + else if(subMenuPage==2){ + lcd.setCursor(0,0);lcd.print("MIN BATTERY V "); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + lcd.setCursor(2,1);lcd.print(voltageBatteryMin,2);lcd.print("V"); + lcd.print(" "); + + //SET MENU - FLOATTYPE + if(setMenuPage==0){floatTemp = voltageBatteryMin;} + else{ + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}voltageBatteryMin = floatTemp;cancelledMessageLCD();setMenuPage=0;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveSettings();setMenuPage=0;savedMessageLCD();} + currentMenuSetMillis = millis(); + if(digitalRead(buttonRight)==1){ //Right button press (increments setting values) + while(digitalRead(buttonRight)==1){ + if(millis()-currentMenuSetMillis>longPressTime){ //Long Press + voltageBatteryMin += 1.00; //Increment by 1 + voltageBatteryMin = constrain(voltageBatteryMin,vOutSystemMin,vOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(voltageBatteryMin,2);delay(longPressInterval); //Display settings data + } + else{ //Short Press + voltageBatteryMin += 0.01; //Increment by 0.01 + voltageBatteryMin = constrain(voltageBatteryMin,vOutSystemMin,vOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(voltageBatteryMin,2);delay(shortPressInterval); //Display settings data + } + lcd.print("V "); //Display unit + } + } + else if(digitalRead(buttonLeft)==1){ //Left button press (decrements setting values) + while(digitalRead(buttonLeft)==1){ + if(millis()-currentMenuSetMillis>longPressTime){ //Long Press + voltageBatteryMin -= 1.00; //Increment by 1 + voltageBatteryMin = constrain(voltageBatteryMin,vOutSystemMin,vOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(voltageBatteryMin,2);delay(longPressInterval); //Display settings data + } + else{ //Short Press + voltageBatteryMin -= 0.01; //Increment by 0.01 + voltageBatteryMin = constrain(voltageBatteryMin,vOutSystemMin,vOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(voltageBatteryMin,2);delay(shortPressInterval); //Display settings data + } + lcd.print("V "); //Display unit + } + } + } + } + ///// SETTINGS MENU ITEM: CHARGING CURRENT ///// + else if(subMenuPage==3){ + lcd.setCursor(0,0);lcd.print("CHARGING CURRENT"); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + lcd.setCursor(2,1);lcd.print(currentCharging,2);lcd.print("A"); + lcd.print(" "); + + //SET MENU - FLOATTYPE + if(setMenuPage==0){floatTemp = currentCharging;} + else{ + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}currentCharging = floatTemp;cancelledMessageLCD();setMenuPage=0;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveSettings();setMenuPage=0;savedMessageLCD();} + currentMenuSetMillis = millis(); + if(digitalRead(buttonRight)==1){ //Right button press (increments setting values) + while(digitalRead(buttonRight)==1){ + if(millis()-currentMenuSetMillis>longPressTime){ //Long Press + currentCharging += 1.00; //Increment by 1 + currentCharging = constrain(currentCharging,0.0,cOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(currentCharging,2);delay(longPressInterval); //Display settings data + } + else{ //Short Press + currentCharging += 0.01; //Increment by 0.01 + currentCharging = constrain(currentCharging,0.0,cOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(currentCharging,2);delay(shortPressInterval); //Display settings data + } + lcd.print("A "); //Display unit + } + } + else if(digitalRead(buttonLeft)==1){ //Left button press (decrements setting values) + while(digitalRead(buttonLeft)==1){ + if(millis()-currentMenuSetMillis>longPressTime){ //Long Press + currentCharging -= 1.00; //Increment by 1 + currentCharging = constrain(currentCharging,0.0,cOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(currentCharging,2);delay(longPressInterval); //Display settings data + } + else{ //Short Press + currentCharging -= 0.01; //Increment by 0.01 + currentCharging = constrain(currentCharging,0.0,cOutSystemMax); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(currentCharging,2);delay(shortPressInterval); //Display settings data + } + lcd.print("A "); //Display unit + } + } + } + } + ///// SETTINGS MENU ITEM: COOLING FAN ///// + else if(subMenuPage==4){ + lcd.setCursor(0,0);lcd.print("COOLING FAN "); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + if(enableFan==1){lcd.print("ENABLED ");} + else{lcd.print("DISABLE ");} + + //SET MENU - BOOLTYPE + if(setMenuPage==0){boolTemp = enableFan;} + else{ + if(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){ + while(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){} + if(enableFan==1){enableFan=0;}else{enableFan=1;} + } + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}enableFan = boolTemp;cancelledMessageLCD();setMenuPage=0;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveSettings();setMenuPage=0;savedMessageLCD();} + } + } + ///// SETTINGS MENU ITEM: FAN TRIG TEMP ///// + else if(subMenuPage==5){ + lcd.setCursor(0,0);lcd.print("FAN TRIG TEMP "); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + lcd.setCursor(2,1);lcd.print(temperatureFan); + lcd.print((char)223);lcd.print("C");lcd.print(" "); + + //SET MENU - INTTYPE + if(setMenuPage==0){intTemp = temperatureFan;} + else{ + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}temperatureFan = intTemp;cancelledMessageLCD();setMenuPage=0;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveSettings();setMenuPage=0;savedMessageLCD();} + if(digitalRead(buttonRight)==1){ //Right button press (increments setting values) + while(digitalRead(buttonRight)==1){ + temperatureFan++; //Increment by 1 + temperatureFan = constrain(temperatureFan,0,100); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(temperatureFan);delay(shortPressInterval); //Display settings data + lcd.print((char)223);lcd.print("C "); //Display unit + } + } + else if(digitalRead(buttonLeft)==1){ //Left button press (decrements setting values) + while(digitalRead(buttonLeft)==1){ + temperatureFan--; //Increment by 1 + temperatureFan = constrain(temperatureFan,0,100); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(temperatureFan);delay(shortPressInterval); //Display settings data + lcd.print((char)223);lcd.print("C "); //Display unit + } + } + } + } + ///// SETTINGS MENU ITEM: SHUTDOWN TEMP ///// + else if(subMenuPage==6){ + lcd.setCursor(0,0);lcd.print("SHUTDOWN TEMP "); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + lcd.setCursor(2,1);lcd.print(temperatureMax); + lcd.print((char)223);lcd.print("C");lcd.print(" "); + + //SET MENU - INTTYPE + if(setMenuPage==0){intTemp = temperatureMax;} + else{ + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}temperatureMax = intTemp;cancelledMessageLCD();setMenuPage=0;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveSettings();setMenuPage=0;savedMessageLCD();} + if(digitalRead(buttonRight)==1){ //Right button press (increments setting values) + while(digitalRead(buttonRight)==1){ + temperatureMax++; //Increment by 1 + temperatureMax = constrain(temperatureMax,0,100); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(temperatureMax);delay(shortPressInterval); //Display settings data + lcd.print((char)223);lcd.print("C "); //Display unit + } + } + else if(digitalRead(buttonLeft)==1){ //Left button press (decrements setting values) + while(digitalRead(buttonLeft)==1){ + temperatureMax--; //Increment by 1 + temperatureMax = constrain(temperatureMax,0,100); //Limit settings values to a range + lcd.setCursor(2,1);lcd.print(temperatureMax);delay(shortPressInterval); //Display settings data + lcd.print((char)223);lcd.print("C "); //Display unit + } + } + } + } + ///// SETTINGS MENU ITEM: WIFI FEATURE ///// + else if(subMenuPage==7){ + lcd.setCursor(0,0);lcd.print("WIFI FEATURE "); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + if(enableWiFi==1){lcd.print("ENABLED ");} + else{lcd.print("DISABLED ");} + + //SET MENU - BOOLTYPE + if(setMenuPage==0){boolTemp = enableWiFi;} + else{ + if(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){ + while(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){} + if(enableWiFi==1){enableWiFi=0;}else{enableWiFi=1;} + } + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}enableWiFi = boolTemp;cancelledMessageLCD();setMenuPage=0;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveSettings();setMenuPage=0;savedMessageLCD();} + } + } + + ///// SETTINGS MENU ITEM: AUTOLOAD ///// + else if(subMenuPage==8){ + lcd.setCursor(0,0);lcd.print("AUTOLOAD FEATURE"); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + if(flashMemLoad==1){lcd.print("ENABLED ");} + else{lcd.print("DISABLED ");} + + //SET MENU - BOOLTYPE + if(setMenuPage==0){boolTemp = flashMemLoad;} + else{ + if(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){ + while(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){} + if(flashMemLoad==1){flashMemLoad=0;}else{flashMemLoad=1;} + } + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}flashMemLoad = boolTemp;cancelledMessageLCD();setMenuPage=0;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveAutoloadSettings();setMenuPage=0;savedMessageLCD();} + } + } + + ///// SETTINGS MENU ITEM: FACTORY RESET ///// + else if(subMenuPage==9){ + if(setMenuPage==0){ + lcd.setCursor(0,0);lcd.print("FACTORY RESET "); + lcd.setCursor(0,1);lcd.print("> PRESS SELECT "); + } + else{ + if(confirmationMenu==0){lcd.setCursor(0,0);lcd.print(" ARE YOU SURE? ");lcd.setCursor(0,1);lcd.print(" >NO YES ");} // Display ">No" + else{lcd.setCursor(0,0);lcd.print(" ARE YOU SURE? ");lcd.setCursor(0,1);lcd.print(" NO >YES ");} // Display ">YES" + if(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){while(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){}if(confirmationMenu==0){confirmationMenu=1;}else{confirmationMenu=0;}} //Cycle Yes NO + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}cancelledMessageLCD();setMenuPage=0;confirmationMenu=0;} //Cancel + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}if(confirmationMenu==1){factoryReset();savedMessageLCD();}setMenuPage=0;confirmationMenu=0;} + } + } + ///// SETTINGS MENU ITEM: FIRMWARE VERSION ///// + else if(subMenuPage==10){ + if(setMenuPage==0){ + lcd.setCursor(0,0);lcd.print("FIRMWARE VERSION"); + lcd.setCursor(0,1);lcd.print(firmwareInfo); + } + else{ + lcd.setCursor(0,0);lcd.print(firmwareContactR1); + lcd.setCursor(0,1);lcd.print(firmwareContactR1); + if(digitalRead(buttonBack)==1||digitalRead(buttonSelect)==1){while(digitalRead(buttonBack)==1||digitalRead(buttonSelect)==1){}setMenuPage=0;} //Cancel + } + } + } + //MAIN MENU + else if(settingMode==0){ + chargingPause = 0; + + //BUTTON KEYPRESS + if(digitalRead(buttonRight)==1) {buttonRightCommand=1;} + if(digitalRead(buttonLeft)==1) {buttonLeftCommand=1;} + if(digitalRead(buttonBack)==1) {buttonBackCommand=1;} + if(digitalRead(buttonSelect)==1){buttonSelectCommand=1;} + + currentLCDMillis = millis(); + if(currentLCDMillis-prevLCDMillis>=millisLCDInterval&&enableLCD==1){ //Run routine every millisLCDInterval (ms) + prevLCDMillis = currentLCDMillis; + + //MENU PAGE BUTTON ACTION + if(buttonRightCommand==1) {buttonRightCommand=0; lcd.clear();menuPage++;} + else if(buttonLeftCommand==1) {buttonLeftCommand=0; lcd.clear();menuPage--;} + else if(buttonBackCommand==1) {buttonBackCommand=0; lcd.clear();menuPage=0;} + else if(buttonSelectCommand==1&&menuPage==4){buttonSelectCommand=0;lcd.clear();settingMode=1;} + if(menuPage>menuPages){menuPage=0;} + else if(menuPage<0){menuPage=menuPages;} + + if(menuPage==0) {displayConfig1();} + else if(menuPage==1){displayConfig2();} + else if(menuPage==2){displayConfig3();} + else if(menuPage==3){displayConfig4();} + else if(menuPage==4){displayConfig5();} + } + } +} diff --git a/ARDUINO_MPPT_FIRMWARE_V1.0.ino b/ARDUINO_MPPT_FIRMWARE_V1.0.ino new file mode 100644 index 0000000..24bbd8f --- /dev/null +++ b/ARDUINO_MPPT_FIRMWARE_V1.0.ino @@ -0,0 +1,296 @@ +/* 1kW MPPT (ESP32, ADS1115, HLSR50P - V3.0) + * By: Angelo Casimiro + * CREATED: May 20, 2021 + * + * Expri: + * - Check MPPT mode + * - Check eepromread + * - Wipe WiFi data + * + * NOTES: + * - Add blink items for settings + * - Charging will only charge battery when input voltage is 1V above 'Maximum Battery Charging Voltage (voltageBatteryMax)' + * - Add telem save + * + * - Add debounce capacitor to buttons + * - Fix fatally low system voltage action (Source: Vin or Vo?) + * - Add diode in PCB + * - Fix error counter, Implement error counter infinite loop protection + * - Add buttons millis debounce + * - Add LCD Menu Savings + * - Fix LCD Flicker + * - Hysterisis for IUV recovery + * - Voltage divider ints + * - Night time low power mode (add millis to all except menu - add option to disconnect to wifi) + * - ADS1115 Compatibility + * - LCD backlight + * + * ENCLOSURE: + * - ADD MORE HOLES + * - Add LED hole + * - reduce 4mm - retain cover + * - Fix screws + * + * FEATURES: + * - Equipped With Diodeless PV Backflow Prevention + * - Equipped With Synchronous Buck Charger Backflow Current Detection + * - Uses Predictive PWM (PPWM) to accelerate floor regulation speed + * - Automatic Sensor Calibration + * +*/ +//========== FIRMWARE LCD MENU INFO ================================================================= +String +firmwareInfo = "V1.00 (22/08/21)", +firmwareContactR1 = "www.youtube.com/", +firmwareContactR2 = "TechBuilder "; +//========== ARDUINO LIBRARIES ====================================================================== +#include //SYSTEM PARAMETER - EEPROM Library (By: Arduino) +#include //SYSTEM PARAMETER - WIRE Library (By: Arduino) +#include //SYSTEM PARAMETER - SPI Library (By: Arduino) +#include //SYSTEM PARAMETER - WiFi Library (By: Arduino) +#include //SYSTEM PARAMETER - WiFi Library (By: Arduino) +#include //SYSTEM PARAMETER - Blynk WiFi Library For Phone App +#include //SYSTEM PARAMETER - ESP32 LCD Compatible Library (By: Robojax) +#include //SYSTEM PARAMETER - ADS1115/ADS1015 ADC Library (By: Adafruit) +LiquidCrystal_I2C lcd(0x27,16,2); //SYSTEM PARAMETER - Configure LCD RowCol Size and I2C Address +Adafruit_ADS1015 ads; //SYSTEM PARAMETER - ADS1115/ADS1015 ADC Library (By: Adafruit) +TaskHandle_t Core2; //SYSTEM PARAMETER - Used for the ESP32 dual core operation +//========== PIN CONFIG ============================================================================= +#define backflow_MOSFET 27 //SYSTEM PARAMETER - Backflow MOSFET +#define buck_IN 33 //SYSTEM PARAMETER - Buck MOSFET Driver PWM Pin +#define buck_EN 32 //SYSTEM PARAMETER - Buck MOSFET Driver Enable Pin +#define LED 2 //SYSTEM PARAMETER - LED Indicator GPIO Pin +#define FAN 16 //SYSTEM PARAMETER - Fan GPIO Pin +#define ADC_ALERT 34 //SYSTEM PARAMETER - Fan GPIO Pin +#define TempSensor 35 //SYSTEM PARAMETER - Temperature Sensor GPIO Pin +#define buttonLeft 18 //SYSTEM PARAMETER - +#define buttonRight 17 //SYSTEM PARAMETER - +#define buttonBack 19 //SYSTEM PARAMETER - +#define buttonSelect 23 //SYSTEM PARAMETER - +//========== WiFi SSID ============================================================================= +char +auth[] = "nW4qPYZTfwGk6SjhOOZuwKFSScLSmYXO", // USER PARAMETER - Input Blynk Authentication Token (From email after registration) +ssid[] = "Husavik", // USER PARAMETER - Enter Your WiFi SSID +pass[] = "Joey+Lena=2293"; // USER PARAMETER - Enter Your WiFi Password +//========== MPPT VARIABLE PARAMETERS ============================================================== +bool //========== BOOLEAN (1 = Enable, 0 - Disable) ========== +MPPT_Mode = 1, // USER PARAMETER - Enable MPPT algorithm, when disabled charger uses CC-CV mode +disableFlashAutoLoad = 0, // USER PARAMETER - Forces the MPPT to not use flash saved settings, enabling this "1" defaults to programmed firmware settings. +enablePPWM = 1, // USER PARAMETER - Enables Predictive PWM, this accelerates regulation speed (only applicable for battery charging application) +enableWiFi = 1, // USER PARAMETER - Enable WiFi Connection +enableFan = 1, // USER PARAMETER - Enable Cooling Fan +enableBluetooth = 1, // USER PARAMETER - Enable Bluetooth Connection +enableLCD = 1, // USER PARAMETER - Enable LCD display +enableLCDBacklight = 1, // USER PARAMETER - Enable LCD display's backlight +overrideFan = 0, // USER PARAMETER - Fan always on +enableDynamicCooling = 0, // USER PARAMETER - Enable for PWM cooling control +ADS1015_Mode = 1, // CALIB PARAMETER - Use 1 for ADS1015 ADC model use 0 for ADS1115 ADC model +buckEnable = 0, // SYSTEM PARAMETER - Buck Enable Status +fanStatus = 0, // SYSTEM PARAMETER - Fan activity status (1 = On, 0 = Off) +bypassEnable = 0, // SYSTEM PARAMETER - +chargingPause = 0, // SYSTEM PARAMETER - +lowPowerMode = 0, // SYSTEM PARAMETER - +buttonRightStatus = 0, +buttonLeftStatus = 0, +buttonBackStatus = 0, +buttonSelectStatus = 0, +buttonRightCommand = 0, +buttonLeftCommand = 0, +buttonBackCommand = 0, +buttonSelectCommand = 0, +settingMode = 0, +setMenuPage = 0, // SYSTEM PARAMETER - +boolTemp = 0, // SYSTEM PARAMETER - +flashMemLoad = 0, // SYSTEM PARAMETER - +confirmationMenu = 0, + + +WIFI = 0, // SYSTEM PARAMETER - +BNC = 0, // SYSTEM PARAMETER - +REC = 0, // SYSTEM PARAMETER - +FLV = 0, // SYSTEM PARAMETER - +IUV = 0, // SYSTEM PARAMETER - +IOV = 0, // SYSTEM PARAMETER - +IOC = 0, // SYSTEM PARAMETER - +OUV = 0, // SYSTEM PARAMETER - +OOV = 0, // SYSTEM PARAMETER - +OOC = 0, // SYSTEM PARAMETER - +OTE = 0; // SYSTEM PARAMETER - + +int +serialTelemMode = 2, // USER PARAMETER - Selects serial telemetry data feed (0 - Disable Serial, 1 - Display All Data, 2 - Display Essential, 3 - Number only) +pwmResolution = 11, // USER PARAMETER - PWM Bit Resolution +pwmFrequency = 39000, // USER PARAMETER - PWM Switching Frequency (For Buck) +temperatureFan = 60, // USER PARAMETER - Temperature threshold for fan to turn on +temperatureMax = 90, // USER PARAMETER - Overtemperature, System Shudown When Exceeded (deg C) +telemCounterReset = 0, // USER PARAMETER - Reset Telem Data Every (0 = Never, 1 = Day, 2 = Week, 3 = Month, 4 = Year) +errorTimeLimit = 1000, // USER PARAMETER - Time interval for reseting error counter (milliseconds) +errorCountLimit = 5, // USER PARAMETER - Maximum number of errors +millisRoutineInterval = 250, // USER PARAMETER - Time Interval Refresh Rate For Routine Functions (ms) +millisSerialInterval = 1, // USER PARAMETER - Time Interval Refresh Rate For USB Serial Datafeed (ms) +millisLCDInterval = 1000, // USER PARAMETER - Time Interval Refresh Rate For LCD Display (ms) +millisWiFiInterval = 2000, // USER PARAMETER - Time Interval Refresh Rate For WiFi Telemetry (ms) + +baudRate = 500000, // USER PARAMETER - USB Serial Baud Rate (bps) + +ADC_GainSelect = 2, // CALIB PARAMETER - ADC Gain Selection (0→±6.144V 3mV/bit, 1→±4.096V 2mV/bit, 2→±2.048V 1mV/bit) +avgCountVS = 3, // CALIB PARAMETER - Voltage Sensor Average Sampling Count +avgCountCS = 4, // CALIB PARAMETER - Current Sensor Average Sampling Count +avgCountTS = 500, // CALIB PARAMETER - Temperature Sensor Average Sampling Count +avgStoreTS = 0, // SYSTEM PARAMETER - Temperature Sensor uses non invasive averaging, this is used an accumulator for mean averaging +temperature = 0, // SYSTEM PARAMETER - +sampleStoreTS = 0, // SYSTEM PARAMETER - TS AVG nth Sample +pwmMax = 0, // SYSTEM PARAMETER - +pwmMaxLimited = 0, // SYSTEM PARAMETER - +PWM = 0, // SYSTEM PARAMETER - +PPWM = 0, // SYSTEM PARAMETER - +pwmChannel = 0, // SYSTEM PARAMETER - +batteryPercent = 0, // SYSTEM PARAMETER - +errorCount = 0, // SYSTEM PARAMETER - +menuPage = 0, // SYSTEM PARAMETER - +subMenuPage = 0, // SYSTEM PARAMETER - +ERR = 0, // SYSTEM PARAMETER - +intTemp = 0; + +float +voltageBatteryMax = 27.3000, // USER PARAMETER - Maximum Battery Charging Voltage (Output V) +voltageBatteryMin = 22.4000, // USER PARAMETER - Minimum Battery Charging Voltage (Output V) +currentCharging = 30.0000, // USER PARAMETER - Maximum Charging Current (A - Output) +electricalPrice = 9.5000, // USER PARAMETER - Input electrical price per kWh (Dollar/kWh,Euro/kWh,Peso/kWh) + +voltageDropout = 1.0000, // CALIB PARAMETER - Buck regulator's dropout voltage (DOV is present due to Max Duty Cycle Limit) +voltageBatteryThresh = 1.5000, // CALIB PARAMETER - Power cuts-off when this voltage is reached (Output V) +currentInAbsolute = 31.0000, // CALIB PARAMETER - Maximum Input Current The System Can Handle (A - Input) +currentOutAbsolute = 50.0000, // CALIB PARAMETER - Maximum Output Current The System Can Handle (A - Input) +PPWM_margin = 99.5000, // CALIB PARAMETER - Minimum Operating Duty Cycle for Predictive PWM (%) +PWM_MaxDC = 97.0000, // CALIB PARAMETER - Maximum Operating Duty Cycle (%) 90%-97% is good +efficiencyRate = 1.0000, // CALIB PARAMETER - Theroretical Buck Efficiency (% decimal) +currentMidPoint = 2.5250, // CALIB PARAMETER - Current Sensor Midpoint (V) +currentSens = 0.0000, // CALIB PARAMETER - Current Sensor Sensitivity (V/A) +currentSensV = 0.0660, // CALIB PARAMETER - Current Sensor Sensitivity (mV/A) +vInSystemMin = 10.0000, // CALIB PARAMETER - Minimum system input voltage (V) + +vOutSystemMin = 0.0000, // CALIB PARAMETER - Minimum system output voltage (V) +vOutSystemMax = 0.5000, // CALIB PARAMETER - Maximum system output voltage (V) +cOutSystemMax = 30.000, // CALIB PARAMETER - Maximum system output voltage (V) + + +VSI = 0.0000, // SYSTEM PARAMETER - Raw input voltage sensor ADC voltage +VSO = 0.0000, // SYSTEM PARAMETER - Raw output voltage sensor ADC voltage +CSI = 0.0000, // SYSTEM PARAMETER - Raw current sensor ADC voltage +CSI_converted = 0.0000, // SYSTEM PARAMETER - Actual current sensor ADC voltage +TS = 0.0000, // SYSTEM PARAMETER - Raw temperature sensor ADC value +powerInput = 0.0000, // SYSTEM PARAMETER - Input power (solar power) in Watts +powerInputPrev = 0.0000, // SYSTEM PARAMETER - Previously stored input power variable for MPPT algorithm (Watts) +powerOutput = 0.0000, // SYSTEM PARAMETER - Output power (battery or charing power in Watts) +energySavings = 0.0000, // SYSTEM PARAMETER - Energy savings in fiat currency (Peso, USD, Euros or etc...) +voltageInput = 0.0000, // SYSTEM PARAMETER - Input voltage (solar voltage) +voltageInputPrev = 0.0000, // SYSTEM PARAMETER - Previously stored input voltage variable for MPPT algorithm +voltageOutput = 0.0000, // SYSTEM PARAMETER - Input voltage (battery voltage) +currentInput = 0.0000, // SYSTEM PARAMETER - Output power (battery or charing voltage) +currentOutput = 0.0000, // SYSTEM PARAMETER - Output current (battery or charing current in Amperes) +TSlog = 0.0000, // SYSTEM PARAMETER - Part of NTC thermistor thermal sensing code +ADC_BitReso = 0.0000, // SYSTEM PARAMETER - System detects the approriate bit resolution factor for ADS1015/ADS1115 ADC +daysRunning = 0.0000, // SYSTEM PARAMETER - Stores the total number of days the MPPT device has been running since last powered +Wh = 0.0000, // SYSTEM PARAMETER - Stores the accumulated energy harvested (Watt-Hours) +kWh = 0.0000, // SYSTEM PARAMETER - Stores the accumulated energy harvested (Kiliowatt-Hours) +MWh = 0.0000, // SYSTEM PARAMETER - Stores the accumulated energy harvested (Megawatt-Hours) +loopTime = 0.0000, // SYSTEM PARAMETER - +outputDeviation = 0.0000, // SYSTEM PARAMETER - Output Voltage Deviation (%) +buckEfficiency = 0.0000, // SYSTEM PARAMETER - Measure buck converter power conversion efficiency (only applicable to my dual current sensor version) +floatTemp = 0.0000; + +unsigned long +currentErrorMillis = 0, //SYSTEM PARAMETER - +currentButtonMillis = 0, //SYSTEM PARAMETER - +currentSerialMillis = 0, //SYSTEM PARAMETER - +currentRoutineMillis = 0, //SYSTEM PARAMETER - +currentLCDMillis = 0, //SYSTEM PARAMETER - +currentWiFiMillis = 0, //SYSTEM PARAMETER - +currentMenuSetMillis = 0, //SYSTEM PARAMETER - + +prevButtonMillis = 0, //SYSTEM PARAMETER - +prevSerialMillis = 0, //SYSTEM PARAMETER - +prevRoutineMillis = 0, //SYSTEM PARAMETER - +prevErrorMillis = 0, //SYSTEM PARAMETER - +prevWiFiMillis = 0, //SYSTEM PARAMETER - +prevLCDMillis = 0, //SYSTEM PARAMETER - + +timeOn = 0, //SYSTEM PARAMETER - +loopTimeStart = 0, //SYSTEM PARAMETER - Used for the loop cycle stop watch, records the loop start time +loopTimeEnd = 0, //SYSTEM PARAMETER - Used for the loop cycle stop watch, records the loop end time +secondsElapsed = 0; //SYSTEM PARAMETER - + +//========== MAIN PROGRAM BODY BEGINES HERE ============================================================== + +//================= CORE0: SETUP (DUAL CORE MODE) =====================// +void coreTwo(void * pvParameters){ + setupWiFi(); //TAB#7 - WiFi Initialization +//================= CORE0: LOOP (DUAL CORE MODE) ======================// + while(1){ + Wireless_Telemetry(); //TAB#7 - Wireless telemetry (WiFi & Bluetooth) + +}} +//================== CORE1: SETUP (DUAL CORE MODE) ====================// +void setup() { + + //SERIAL INITIALIZATION + Serial.begin(baudRate); //Set serial baud rate + Serial.println("> Serial Initialized"); //Startup message + + //GPIO PIN INITIALIZATION + pinMode(backflow_MOSFET,OUTPUT); + pinMode(buck_EN,OUTPUT); + pinMode(LED,OUTPUT); + pinMode(FAN,OUTPUT); + pinMode(TS,INPUT); + pinMode(ADC_ALERT,INPUT); + pinMode(buttonLeft,INPUT); + pinMode(buttonRight,INPUT); + pinMode(buttonBack,INPUT); + pinMode(buttonSelect,INPUT); + + //PWM INITIALIZATION + ledcSetup(pwmChannel,pwmFrequency,pwmResolution); //Set PWM Parameters + ledcAttachPin(buck_IN, pwmChannel); //Set pin as PWM + ledcWrite(pwmChannel,PWM); //Write PWM value at startup (duty = 0) + pwmMax = pow(2,pwmResolution)-1; //Get PWM Max Bit Ceiling + pwmMaxLimited = (PWM_MaxDC*pwmMax)/100.000; //Get maximum PWM Duty Cycle (pwm limiting protection) + //ADC INITIALIZATION + ADC_SetGain(); //Sets ADC Gain & Range + ads.begin(); //Initialize ADC + + //GPIO INITIALIZATION + buck_Disable(); + + //ENABLE DUAL CORE MULTITASKING + xTaskCreatePinnedToCore(coreTwo,"coreTwo",10000,NULL,0,&Core2,0); + + //INITIALIZE AND LIOAD FLASH MEMORY DATA + EEPROM.begin(512); + Serial.println("> FLASH MEMORY: STORAGE INITIALIZED"); //Startup message + initializeFlashAutoload(); //Load stored settings from flash memory + Serial.println("> FLASH MEMORY: SAVED DATA LOADED"); //Startup message + + //LCD INITIALIZATION + if(enableLCD==1){ + lcd.begin(); + lcd.backlight(); + lcd.setCursor(0,0); + lcd.print("MPPT INITIALIZED"); + delay(1000); + lcd.clear(); + } + + //SETUP FINISHED + Serial.println("> MPPT HAS INITIALIZED"); //Startup message +} +//================== CORE1: LOOP (DUAL CORE MODE) ======================// +void loop() { + Read_Sensors(); //TAB#2 - Sensor data measurement and computation + Device_Protection(); //TAB#3 - Fault detection algorithm + System_Processes(); //TAB#4 - Routine system processes + Charging_Algorithm(); //TAB#5 - Battery Charging Algorithm + Onboard_Telemetry(); //TAB#6 - Onboard telemetry (USB & Serial Telemetry) + LCD_Menu(); //TAB#8 - Low Power Algorithm +}