Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
AngeloCasi authored Aug 29, 2021
1 parent 98b60c5 commit 9c959ee
Show file tree
Hide file tree
Showing 7 changed files with 658 additions and 215 deletions.
10 changes: 7 additions & 3 deletions 2_Read_Sensors.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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; i<avgCountCS; i++){
CSI = CSI + ads.computeVolts(ads.readADC_SingleEnded(2));
}

CSI_converted = (CSI/avgCountCS)*1.3300;
currentInput = ((CSI_converted-currentMidPoint)*-1)/currentSensV;
if(currentInput<0){currentInput=0.0000;}
if(voltageOutput<=0){currentOutput = 0.0000;}
else{currentOutput = (voltageInput*currentInput)/voltageOutput;}

//POWER SOURCE DETECTION
if(voltageInput<=3 && voltageOutput<=3){inputSource=0;} //System is only powered by USB port
else if(voltageInput>voltageOutput) {inputSource=1;} //System is running on solar as power source
else if(voltageInput<voltageOutput) {inputSource=2;} //System is running on batteries as power source

//////// AUTOMATIC CURRENT SENSOR CALIBRATION ////////
if(buckEnable==0 && FLV==0 && OOV == 0){
Expand All @@ -66,8 +71,7 @@ void Read_Sensors(){

//STATE OF CHARGE - Battery Percentage
batteryPercent = ((voltageOutput-voltageBatteryMin)/(voltageBatteryMax-voltageBatteryMin))*101;
if(batteryPercent<0){batteryPercent=0;}
else if(batteryPercent>100){batteryPercent=100;}
batteryPercent = constrain(batteryPercent,0,100);

//TIME DEPENDENT SENSOR DATA COMPUTATION
currentRoutineMillis = millis();
Expand Down
46 changes: 29 additions & 17 deletions 3_Device_Protection.ino
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)
}
}
111 changes: 54 additions & 57 deletions 4_Charging_Algorithm.ino
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
}
}




}
Loading

0 comments on commit 9c959ee

Please sign in to comment.