forked from AngeloCasi/FUGU-ARDUINO-MPPT-FIRMWARE
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
98b60c5
commit 9c959ee
Showing
7 changed files
with
658 additions
and
215 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<errorCountLimit){errorCount=0;} //Reset error count if it is below the limit before x milliseconds | ||
if(currentErrorMillis-prevErrorMillis>=errorTimeLimit){ //Run routine every millisErrorInterval (ms) | ||
prevErrorMillis = currentErrorMillis; //Store previous time | ||
if(errorCount<errorCountLimit){errorCount=0;} //Reset error count if it is below the limit before x milliseconds | ||
else{} // TO ADD: sleep and charging pause if too many errors persists | ||
} | ||
|
||
//////// PV BACKFLOW CONTROL (INPUT MOSFET) //////// | ||
if(voltageInput>voltageOutput+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(voltageOutput<vInSystemMin&&MPPT_Mode==1) {BNC=1;ERR++;} else{BNC=0;} //BNC - BATTERY NOT CONNECTED (Does not treat BNC as error when not under MPPT mode) //Do not treat BNC as error when not under PPWM mode | ||
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(voltageInput<voltageBatteryMax+voltageDropout&&MPPT_Mode==1) {IUV=1;ERR++;REC=1;} else{IUV=0;} //IUV - INPUT UNDERVOLTAGE: Input voltage is below battery voltage (for MPPT mode only) | ||
if(voltageOutput>voltageBatteryMax+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(voltageInput<vInSystemMin&&voltageOutput<vInSystemMin){FLV=1;ERR++;errorCount++;}else{FLV=0;} //FLV - Fatally low system voltage (unable to resume operation) | ||
|
||
if(output_Mode==0){ //PSU MODE specific protection protocol | ||
REC = 0; BNC = 0; //Clear recovery and battery not connected boolean identifiers | ||
if(voltageInput<voltageBatteryMax+voltageDropout){IUV=1;ERR++;errorCount++;}else{IUV=0;} //IUV - INPUT UNDERVOLTAGE: Input voltage is below battery voltage (for psu mode only) | ||
} | ||
else{ //Charger MODE specific protection protocol | ||
backflowControl(); //Enable backflow current detection & control | ||
if(voltageOutput<vInSystemMin) {BNC=1;ERR++;} else{BNC=0;} //BNC - BATTERY NOT CONNECTED (for charger mode only, does not treat BNC as error when not under MPPT mode) | ||
if(voltageInput<voltageBatteryMax+voltageDropout){IUV=1;ERR++;REC=1;}else{IUV=0;} //IUV - INPUT UNDERVOLTAGE: Input voltage is below max battery charging voltage (for charger mode only) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,71 @@ | ||
void buck_Enable(){ //Enable MPPT Buck Converter | ||
void buck_Enable(){ //Enable MPPT Buck Converter | ||
buckEnable = 1; | ||
digitalWrite(LED,HIGH); | ||
digitalWrite(buck_EN,HIGH); | ||
digitalWrite(LED,HIGH); | ||
} | ||
void buck_Disable(){ //Disable MPPT Buck Converter | ||
PWM = 0; | ||
buckEnable = 0; | ||
digitalWrite(LED,LOW); | ||
void buck_Disable(){ //Disable MPPT Buck Converter | ||
buckEnable = 0; | ||
digitalWrite(buck_EN,LOW); | ||
digitalWrite(LED,LOW); | ||
PWM = 0; | ||
} | ||
void predictivePWM(){ //PREDICTIVE PWM ALGORITHM | ||
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 | ||
PPWM = constrain(PPWM,0,pwmMaxLimited); | ||
} | ||
void predictivePWM(){ //PREDICTIVE PWM ALGORITHM | ||
if(enablePPWM==0){PPWM=0;} //PPWM Disabled - PPWM is set to the corresponding PPWM value for the voltage slightly beneath output voltage | ||
|
||
else if(MPPT_Mode==0){ //PPWM Enabled (CC-CV PSU 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*voltageBatteryMax)/(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 | ||
} | ||
|
||
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(voltageOutput<voltageBatteryMax && MPPT_Mode==0){PWM++;} //Increase duty cycle when output is below charging voltage (for CC-CV only mode) | ||
else{ | ||
if(MPPT_Mode==1){ //MPPT ALGORITHM | ||
PWM = PPWM; | ||
lcd.clear(); | ||
} | ||
else{ //NO ERROR PRESENT - Continue power conversion | ||
/////////////////////// CC-CV BUCK PSU ALGORITHM ////////////////////////////// | ||
if(MPPT_Mode==0){ //CC-CV PSU MODE | ||
if(currentOutput>currentCharging) {PWM--;} //Current Is Above → Decrease Duty Cycle | ||
else if(voltageOutput>voltageBatteryMax){PWM--;} //Voltage Is Above → Decrease Duty Cycle | ||
else if(voltageOutput<voltageBatteryMax){PWM++;} //Increase duty cycle when output is below charging voltage (for CC-CV only mode) | ||
else{} //Do nothing when set output voltage is reached | ||
PWM_Modulation(); //Set PWM signal to Buck PWM GPIO | ||
} | ||
/////////////////////// MPPT & CC-CV CHARGING ALGORITHM /////////////////////// | ||
else{ | ||
if(currentOutput>currentCharging){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 && voltageInput<voltageInputPrev){PWM++;} // ↑P ↓V ; MPP← //D++ | ||
else if(powerInput<powerInputPrev && voltageInput>voltageInputPrev){PWM++;} // ↓P ↑V ; MPP→ //D++ | ||
else if(powerInput<powerInputPrev && voltageInput<voltageInputPrev){PWM--;} // ↓P ↓V ; ←MPP //D-- | ||
else if(voltageOutput<voltageBatteryMax && MPPT_Mode==1) {PWM++;} // MP MV ; MPP Reached - | ||
else{} // MP MV ; MPP Reached - | ||
else if(voltageOutput<voltageBatteryMax) {PWM++;} // MP MV ; MPP Reached - | ||
powerInputPrev = powerInput; //Store Previous Recorded Power | ||
voltageInputPrev = voltageInput; //Store Previous Recorded Voltage | ||
} | ||
voltageInputPrev = voltageInput; //Store Previous Recorded Voltage | ||
PWM_Modulation(); //Set PWM signal to Buck PWM GPIO | ||
} | ||
} | ||
} | ||
/////////////////////// PWM MODULATION /////////////////////// | ||
predictivePWM(); | ||
if(PWM>pwmMaxLimited){PWM=pwmMaxLimited;} //PWM Ceiling Limiter - Limits maximum PWM value | ||
else if(PWM<PPWM){PWM=PPWM;} //PWM Floor Limiter - Limits minimum PWM value | ||
ledcWrite(pwmChannel,PWM); //Set PWM duty cycle and write to GPIO when buck is enabled | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
} |
Oops, something went wrong.