diff --git a/2_Read_Sensors.ino b/2_Read_Sensors.ino index 90c8a39..0f35ee6 100644 --- a/2_Read_Sensors.ino +++ b/2_Read_Sensors.ino @@ -42,17 +42,22 @@ void Read_Sensors(){ } voltageInput = (VSI/avgCountVS)*39.9000; voltageOutput = (VSO/avgCountVS)*24.5000; + //CURRENT SENSOR - Instantenous Averaging for(int i = 0; ivoltageOutput) {inputSource=1;} //System is running on solar as power source + else if(voltageInput100){batteryPercent=100;} + batteryPercent = constrain(batteryPercent,0,100); //TIME DEPENDENT SENSOR DATA COMPUTATION currentRoutineMillis = millis(); diff --git a/3_Device_Protection.ino b/3_Device_Protection.ino index 5e52480..4517475 100644 --- a/3_Device_Protection.ino +++ b/3_Device_Protection.ino @@ -1,24 +1,36 @@ +void backflowControl(){ //PV BACKFLOW CONTROL (INPUT MOSFET) + if(output_Mode==0){bypassEnable=1;} //PSU MODE: Force backflow MOSFET on + else{ //CHARGER MODE: Force backflow MOSFET on + if(voltageInput>voltageOutput+voltageDropout){bypassEnable=1;} //CHARGER MODE: Normal Condition - Turn on Backflow MOSFET (on by default when not in MPPT charger mode) + else{bypassEnable=0;} //CHARGER MODE: Input Undervoltage - Turn off bypass MOSFET and prevent PV Backflow (SS) + } + digitalWrite(backflow_MOSFET,bypassEnable); //Signal backflow MOSFET GPIO pin +} + void Device_Protection(){ //ERROR COUNTER RESET currentRoutineMillis = millis(); - if(currentErrorMillis-prevErrorMillis>=errorTimeLimit){ //Run routine every millisErrorInterval (ms) - prevErrorMillis = currentErrorMillis; //Store previous time - if(errorCount=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 + //FAULT DETECTION + ERR = 0; //Reset local error counter + backflowControl(); //Run backflow current protection protocol + if(temperature>temperatureMax) {OTE=1;ERR++;errorCount++;}else{OTE=0;} //OTE - OVERTEMPERATURE: System overheat detected + if(currentInput>currentInAbsolute) {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(voltageOutput>voltageBatteryMax+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 PWM_Modulation(){ + if(output_Mode==0){PWM = constrain(PWM,0,pwmMaxLimited);} //PSU MODE PWM = PWM OVERFLOW PROTECTION (limit floor to 0% and ceiling to maximim allowable duty cycle) + else{ + predictivePWM(); //Runs and computes for predictive pwm floor + PWM = constrain(PWM,PPWM,pwmMaxLimited); //CHARGER MODE PWM - limit floor to PPWM and ceiling to maximim allowable duty cycle) + } + ledcWrite(pwmChannel,PWM); //Set PWM duty cycle and write to GPIO when buck is enabled + buck_Enable(); //Turn on MPPT buck (IR2104) +} + 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 + 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{ + if(REC==1){ //IUV RECOVERY - (Only active for charging mode) + REC=0; //Reset IUV recovery boolean identifier + buck_Disable(); //Disable buck before PPWM initialization + lcd.setCursor(0,0);lcd.print("POWER SOURCE "); //Display LCD message + lcd.setCursor(0,1);lcd.print("DETECTED "); //Display LCD message + Serial.println("> Solar Panel Detected"); //Display serial message + Serial.print("> Computing For Predictive PWM "); //Display serial message + for(int i = 0; i<40; i++){Serial.print(".");delay(30);} //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(voltageOutputcurrentCharging) {PWM--;} //Current Is Above → Decrease Duty Cycle + else if(voltageOutput>voltageBatteryMax){PWM--;} //Voltage Is Above → Decrease Duty Cycle + else if(voltageOutputcurrentCharging){PWM--;} //Current Is Above → Decrease Duty Cycle + else if(voltageOutput>voltageBatteryMax){PWM--;} //Voltage Is Above → Decrease Duty Cycle + else{ //MPPT ALGORITHM if(powerInput>powerInputPrev && 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(temperature0 && settingMode==0){ + currentLCDBackLMillis = millis(); + if(currentLCDBackLMillis-prevLCDBackLMillis>=backLightInterval){ //Run routine every millisRoutineInterval (ms) + prevLCDBackLMillis = currentLCDBackLMillis; //Store previous time + lcd.setBacklight(LOW); //Increment time counter + } + } +} void padding100(int padVar){ if(padVar<10){lcd.print(" ");} else if(padVar<100){lcd.print(" ");} @@ -5,23 +30,22 @@ void padding100(int padVar){ 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(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,0); + 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");} + else{lcd.setCursor(5,1);lcd.print("NOBAT ");} lcd.setCursor(11,1);lcd.print(currentOutput,1);lcd.print("A");padding10(currentOutput); } void displayConfig2(){ @@ -36,15 +60,15 @@ void displayConfig2(){ 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 + 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 @@ -61,23 +85,33 @@ void displayConfig4(){ else{lcd.print("OFF");} } void displayConfig5(){ - lcd.setCursor(0,0);lcd.print(" SETTINGS MENU "); + lcd.setCursor(0,0);lcd.print(" SETTINGS MENU "); lcd.setCursor(0,1);lcd.print("--PRESS SELECT--"); } + +void factoryResetMessageLCD(){ + lcd.setCursor(0,0);lcd.print(" FACTORY RESET "); + lcd.setCursor(0,1);lcd.print(" SUCCESSFUL "); + delay(1000); +} void savedMessageLCD(){ - lcd.setCursor(0,0);lcd.print(" SETTINGS SAVED "); - lcd.setCursor(0,1);lcd.print(" SUCCESSFULLY "); - delay(500); +// lcd.setCursor(0,0);lcd.print(" SETTINGS SAVED "); +// lcd.setCursor(0,1);lcd.print(" SUCCESSFULLY "); +// delay(500); +// lcd.clear(); } void cancelledMessageLCD(){ // lcd.setCursor(0,0);lcd.print(" SETTINGS "); // lcd.setCursor(0,1);lcd.print(" CANCELLED "); // delay(500); +// lcd.clear(); } + +//////////////////////////////////////////// MAIN LCD MENU CODE ///////////////////////////////////////////// void LCD_Menu(){ int menuPages = 4, - subMenuPages = 10, + subMenuPages = 12, longPressTime = 3000, longPressInterval = 500, shortPressInterval = 100; @@ -92,6 +126,7 @@ void LCD_Menu(){ if(digitalRead(buttonLeft)==1) {subMenuPage--;} if(digitalRead(buttonBack)==1) {settingMode=0;subMenuPage=0;} //bool engage, main menu int page if(digitalRead(buttonSelect)==1){setMenuPage=1;} //enter sub menu settings - bool engage + lcdBacklight_Wake(); while(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1 ||digitalRead(buttonBack)==1||digitalRead(buttonSelect)==1){} } @@ -99,13 +134,13 @@ void LCD_Menu(){ if(subMenuPage>subMenuPages){subMenuPage=0;} else if(subMenuPage<0){subMenuPage=subMenuPages;} //--------------------------- SETTINGS MENU PAGES: ---------------------------// - ///// SETTINGS MENU ITEM: CHARGING MODE ///// + ///// SETTINGS MENU ITEM: SUPPLY ALGORITHM SELECT ///// if(subMenuPage==0){ - lcd.setCursor(0,0);lcd.print("CHARGING MODE "); + lcd.setCursor(0,0);lcd.print("SUPPLY ALGORITHM"); 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");} + if(MPPT_Mode==1){lcd.print("MPPT + CC-CV ");} + else{lcd.print("CC-CV ONLY ");} //SET MENU - BOOLTYPE if(setMenuPage==0){boolTemp = MPPT_Mode;} @@ -118,8 +153,30 @@ void LCD_Menu(){ if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveSettings();setMenuPage=0;savedMessageLCD();} } } - ///// SETTINGS MENU ITEM: MAX BATTERY V ///// + + ///// SETTINGS MENU ITEM: CHARER/PSU MODE ///// else if(subMenuPage==1){ + lcd.setCursor(0,0);lcd.print("CHARGER/PSU MODE"); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + if(output_Mode==1){lcd.print("CHARGER MODE ");} + else{lcd.print("PSU MODE ");} + + //SET MENU - BOOLTYPE + if(setMenuPage==0){boolTemp = output_Mode;} + else{ + if(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){ + while(digitalRead(buttonRight)==1||digitalRead(buttonLeft)==1){} + if(output_Mode==1){output_Mode=0;}else{output_Mode=1;} + } + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}output_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==2){ 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("= ");} @@ -165,7 +222,7 @@ void LCD_Menu(){ } } ///// SETTINGS MENU ITEM: MIN BATTERY V ///// - else if(subMenuPage==2){ + else if(subMenuPage==3){ 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("= ");} @@ -211,7 +268,7 @@ void LCD_Menu(){ } } ///// SETTINGS MENU ITEM: CHARGING CURRENT ///// - else if(subMenuPage==3){ + else if(subMenuPage==4){ lcd.setCursor(0,0);lcd.print("CHARGING CURRENT"); if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} else{lcd.setCursor(0,1);lcd.print("= ");} @@ -257,7 +314,7 @@ void LCD_Menu(){ } } ///// SETTINGS MENU ITEM: COOLING FAN ///// - else if(subMenuPage==4){ + else if(subMenuPage==5){ lcd.setCursor(0,0);lcd.print("COOLING FAN "); if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} else{lcd.setCursor(0,1);lcd.print("= ");} @@ -276,8 +333,8 @@ void LCD_Menu(){ } } ///// SETTINGS MENU ITEM: FAN TRIG TEMP ///// - else if(subMenuPage==5){ - lcd.setCursor(0,0);lcd.print("FAN TRIG TEMP "); + else if(subMenuPage==6){ + lcd.setCursor(0,0);lcd.print("FAN TRIGGER TEMP"); if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} else{lcd.setCursor(0,1);lcd.print("= ");} lcd.setCursor(2,1);lcd.print(temperatureFan); @@ -307,7 +364,7 @@ void LCD_Menu(){ } } ///// SETTINGS MENU ITEM: SHUTDOWN TEMP ///// - else if(subMenuPage==6){ + else if(subMenuPage==7){ lcd.setCursor(0,0);lcd.print("SHUTDOWN TEMP "); if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} else{lcd.setCursor(0,1);lcd.print("= ");} @@ -322,7 +379,7 @@ void LCD_Menu(){ 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 + temperatureMax = constrain(temperatureMax,0,120); //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 } @@ -330,7 +387,7 @@ void LCD_Menu(){ 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 + temperatureMax = constrain(temperatureMax,0,120); //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 } @@ -338,7 +395,7 @@ void LCD_Menu(){ } } ///// SETTINGS MENU ITEM: WIFI FEATURE ///// - else if(subMenuPage==7){ + else if(subMenuPage==8){ lcd.setCursor(0,0);lcd.print("WIFI FEATURE "); if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} else{lcd.setCursor(0,1);lcd.print("= ");} @@ -358,7 +415,7 @@ void LCD_Menu(){ } ///// SETTINGS MENU ITEM: AUTOLOAD ///// - else if(subMenuPage==8){ + else if(subMenuPage==9){ lcd.setCursor(0,0);lcd.print("AUTOLOAD FEATURE"); if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} else{lcd.setCursor(0,1);lcd.print("= ");} @@ -376,9 +433,64 @@ void LCD_Menu(){ if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}saveAutoloadSettings();setMenuPage=0;savedMessageLCD();} } } - + ///// SETTINGS MENU ITEM: BACKLIGHT SLEEP ///// + else if(subMenuPage==10){ + lcd.setCursor(0,0);lcd.print("BACKLIGHT SLEEP "); + if(setMenuPage==1){lcd.setCursor(0,1);lcd.print(" >");} + else{lcd.setCursor(0,1);lcd.print("= ");} + lcd.setCursor(2,1); + if(backlightSleepMode==1) {lcd.print("10 SECONDS ");} + else if(backlightSleepMode==2){lcd.print("5 MINUTES ");} + else if(backlightSleepMode==3){lcd.print("1 HOUR ");} + else if(backlightSleepMode==4){lcd.print("6 HOURS ");} + else if(backlightSleepMode==5){lcd.print("12 HOURS ");} + else if(backlightSleepMode==6){lcd.print("1 DAY ");} + else if(backlightSleepMode==7){lcd.print("3 DAYS ");} + else if(backlightSleepMode==8){lcd.print("1 WEEK ");} + else if(backlightSleepMode==9){lcd.print("1 MONTH ");} + else{lcd.print("NEVER ");} + + //SET MENU - INTMODETYPE + if(setMenuPage==0){intTemp = backlightSleepMode;} + else{ + if(digitalRead(buttonBack)==1){while(digitalRead(buttonBack)==1){}backlightSleepMode = 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) + backlightSleepMode++; //Increment by 1 + backlightSleepMode = constrain(backlightSleepMode,0,9); //Limit settings values to a range + lcd.setCursor(2,1); + if(backlightSleepMode==1) {lcd.print("10 SECONDS ");} + else if(backlightSleepMode==2){lcd.print("5 MINUTES ");} + else if(backlightSleepMode==3){lcd.print("1 HOUR ");} + else if(backlightSleepMode==4){lcd.print("6 HOURS ");} + else if(backlightSleepMode==5){lcd.print("12 HOURS ");} + else if(backlightSleepMode==6){lcd.print("1 DAY ");} + else if(backlightSleepMode==7){lcd.print("3 DAYS ");} + else if(backlightSleepMode==8){lcd.print("1 WEEK ");} + else if(backlightSleepMode==9){lcd.print("1 MONTH ");} + else{lcd.print("NEVER ");} + while(digitalRead(buttonRight)==1){} + } + else if(digitalRead(buttonLeft)==1){ //Left button press (decrements setting values) + backlightSleepMode--; //Increment by 1 + backlightSleepMode = constrain(backlightSleepMode,0,9); //Limit settings values to a range + lcd.setCursor(2,1); + if(backlightSleepMode==1) {lcd.print("10 SECONDS ");} + else if(backlightSleepMode==2){lcd.print("5 MINUTES ");} + else if(backlightSleepMode==3){lcd.print("1 HOUR ");} + else if(backlightSleepMode==4){lcd.print("6 HOURS ");} + else if(backlightSleepMode==5){lcd.print("12 HOURS ");} + else if(backlightSleepMode==6){lcd.print("1 DAY ");} + else if(backlightSleepMode==7){lcd.print("3 DAYS ");} + else if(backlightSleepMode==8){lcd.print("1 WEEK ");} + else if(backlightSleepMode==9){lcd.print("1 MONTH ");} + else{lcd.print("NEVER ");} + while(digitalRead(buttonLeft)==1){} + } + } + } ///// SETTINGS MENU ITEM: FACTORY RESET ///// - else if(subMenuPage==9){ + else if(subMenuPage==11){ if(setMenuPage==0){ lcd.setCursor(0,0);lcd.print("FACTORY RESET "); lcd.setCursor(0,1);lcd.print("> PRESS SELECT "); @@ -388,18 +500,21 @@ void LCD_Menu(){ 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;} + if(digitalRead(buttonSelect)==1){while(digitalRead(buttonSelect)==1){}if(confirmationMenu==1){factoryReset();factoryResetMessageLCD();}setMenuPage=0;confirmationMenu=0;subMenuPage=0;} } } ///// SETTINGS MENU ITEM: FIRMWARE VERSION ///// - else if(subMenuPage==10){ + else if(subMenuPage==12){ if(setMenuPage==0){ lcd.setCursor(0,0);lcd.print("FIRMWARE VERSION"); lcd.setCursor(0,1);lcd.print(firmwareInfo); + lcd.setCursor(8,1);lcd.print(firmwareDate); + + } else{ lcd.setCursor(0,0);lcd.print(firmwareContactR1); - lcd.setCursor(0,1);lcd.print(firmwareContactR1); + lcd.setCursor(0,1);lcd.print(firmwareContactR2); if(digitalRead(buttonBack)==1||digitalRead(buttonSelect)==1){while(digitalRead(buttonBack)==1||digitalRead(buttonSelect)==1){}setMenuPage=0;} //Cancel } } @@ -408,21 +523,24 @@ void LCD_Menu(){ else if(settingMode==0){ chargingPause = 0; + //LCD BACKLIGHT SLEEP + lcdBacklight(); + //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;} + if(digitalRead(buttonRight)==1) {buttonRightCommand=1;lcdBacklight_Wake();} + if(digitalRead(buttonLeft)==1) {buttonLeftCommand=1;lcdBacklight_Wake();} + if(digitalRead(buttonBack)==1) {buttonBackCommand=1;lcdBacklight_Wake();} + if(digitalRead(buttonSelect)==1){buttonSelectCommand=1;lcdBacklight_Wake();} 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(buttonRightCommand==1) {buttonRightCommand=0;menuPage++;lcd.clear();} + else if(buttonLeftCommand==1) {buttonLeftCommand=0;menuPage--;lcd.clear();} + else if(buttonBackCommand==1) {buttonBackCommand=0;menuPage=0;lcd.clear();} + else if(buttonSelectCommand==1&&menuPage==4){buttonSelectCommand=0;settingMode=1;lcd.clear();} if(menuPage>menuPages){menuPage=0;} else if(menuPage<0){menuPage=menuPages;} diff --git a/ARDUINO_MPPT_FIRMWARE_V20.ino b/ARDUINO_MPPT_FIRMWARE_V20.ino new file mode 100644 index 0000000..ca6c7d2 --- /dev/null +++ b/ARDUINO_MPPT_FIRMWARE_V20.ino @@ -0,0 +1,303 @@ +//================================ MPPT FIRMWARE LCD MENU INFO =====================================// +// The lines below are for the Firmware Version info displayed on the MPPT's LCD Menu Interface // +//==================================================================================================// +String +firmwareInfo = "V1.00 ", +firmwareDate = "22/08/21", +firmwareContactR1 = "www.youtube.com/", +firmwareContactR2 = "TechBuilder "; + +//====================== ARDUINO LIBRARIES (ESP32 Compatible Libraries) ============================// +// You will have to download and install the following libraries below in order to program the MPPT // +// unit. Visit TechBuilder's YouTube channel for the "MPPT" tutorial. // +//============================================================================================= ====// +#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 + +//====================================== USER PARAMETERS ===========================================// +// The parameters below are the default parameters used when the MPPT charger settings have not // +// been set or saved through the LCD menu interface or mobile phone WiFi app. Some parameters here // +// would allow you to override or unlock features for advanced users (settings not on the LCD menu) // +//==================================================================================================// +#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 ==============================================// +// This MPPT firmware uses the Blynk phone app and arduino library for controls and data telemetry // +// Fill in your WiFi SSID and password. You will also have to get your own authentication token // +// from email after registering from the Blynk platform. // +//==================================================================================================// +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 + +//====================================== USER PARAMETERS ==========================================// +// The parameters below are the default parameters used when the MPPT charger settings have not // +// been set or saved through the LCD menu interface or mobile phone WiFi app. Some parameters here // +// would allow you to override or unlock features for advanced users (settings not on the LCD menu)// +//=================================================================================================// +bool +MPPT_Mode = 1, // USER PARAMETER - Enable MPPT algorithm, when disabled charger uses CC-CV algorithm +output_Mode = 1, // USER PARAMETER - 0 = PSU MODE, 1 = Charger 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 +int +serialTelemMode = 1, // 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 - Hz (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) +millisLCDBackLInterval = 2000, // USER PARAMETER - Time Interval Refresh Rate For WiFi Telemetry (ms) +backlightSleepMode = 0, // USER PARAMETER - 0 = Never, 1 = 10secs, 2 = 5mins, 3 = 1hr, 4 = 6 hrs, 5 = 12hrs, 6 = 1 day, 7 = 3 days, 8 = 1wk, 9 = 1month +baudRate = 500000; // USER PARAMETER - USB Serial Baud Rate (bps) + +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) + +//================================== CALIBRATION PARAMETERS =======================================// +// The parameters below can be tweaked for designing your own MPPT charge controllers. Only modify // +// the values below if you know what you are doing. The values below have been pre-calibrated for // +// MPPT charge controllers designed by TechBuilder (Angelo S. Casimiro) // +//=================================================================================================// +bool +ADS1015_Mode = 1; // CALIB PARAMETER - Use 1 for ADS1015 ADC model use 0 for ADS1115 ADC model +int +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 (Recommended: 3) +avgCountCS = 4, // CALIB PARAMETER - Current Sensor Average Sampling Count (Recommended: 4) +avgCountTS = 500; // CALIB PARAMETER - Temperature Sensor Average Sampling Count +float +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 - +vOutSystemMin = 0.0000, // CALIB PARAMETER - +vOutSystemMax = 50.0000, // CALIB PARAMETER - +cOutSystemMax = 50.0000; // CALIB PARAMETER - + +//===================================== SYSTEM PARAMETERS =========================================// +// Do not change parameter values in this section. The values below are variables used by system // +// processes. Changing the values can damage the MPPT hardware. Kindly leave it as is! However, // +// you can access these variables to acquire data needed for your mods. // +//=================================================================================================// +bool +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, // SYSTEM PARAMETER - +buttonLeftStatus = 0, // SYSTEM PARAMETER - +buttonBackStatus = 0, // SYSTEM PARAMETER - +buttonSelectStatus = 0, // SYSTEM PARAMETER - +buttonRightCommand = 0, // SYSTEM PARAMETER - +buttonLeftCommand = 0, // SYSTEM PARAMETER - +buttonBackCommand = 0, // SYSTEM PARAMETER - +buttonSelectCommand = 0, // SYSTEM PARAMETER - +settingMode = 0, // SYSTEM PARAMETER - +setMenuPage = 0, // SYSTEM PARAMETER - +boolTemp = 0, // SYSTEM PARAMETER - +flashMemLoad = 0, // SYSTEM PARAMETER - +confirmationMenu = 0, // SYSTEM PARAMETER - +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 +inputSource = 0, // SYSTEM PARAMETER - 0 = MPPT has no power source, 1 = MPPT is using solar as source, 2 = MPPTis using battery as power source +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 - +conv1 = 0, // SYSTEM PARAMETER - +conv2 = 0, // SYSTEM PARAMETER - +intTemp = 0; // SYSTEM PARAMETER - +float +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 - +currentLCDBackLMillis = 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 - +prevLCDBackLMillis = 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 =============================================// +// The codes below contain all the system processes for the MPPT firmware. Most of them are called // +// from the 8 .ino tabs. The codes are too long, Arduino tabs helped me a lot in organizing them. // +// The firmware runs on two cores of the Arduino ESP32 as seen on the two separate pairs of void // +// setups and loops. The xTaskCreatePinnedToCore() freeRTOS function allows you to access the // +// unused ESP32 core through Arduino. Yes it does multicore processes simultaneously! // +//=================================================================================================// + +//================= 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.setBacklight(HIGH); + lcd.setCursor(0,0); + lcd.print("MPPT INITIALIZED"); + lcd.setCursor(0,1); + lcd.print("FIRMWARE "); + lcd.print(firmwareInfo); + delay(1500); + 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 +}