Project aiming to make a self-controlled solar reflector
Dependencies: Accelerometer LCD Inverter Algorithm MotorDriver Anemometer GUI ArduinoJson Misc Definitions Pushbutton WebSocketClient temp_fan
main.cpp
- Committer:
- khaiminhvn
- Date:
- 2021-03-24
- Revision:
- 20:0a6609515810
- Parent:
- 18:ee0aa6db3c8d
- Child:
- 21:e9978d9823fe
File content as of revision 20:0a6609515810:
/* For settings of system behaviour, see Defs_sett.h For pin assignment list, see PinAssignment.h */ //INCLUDES #include "mbed.h" #include "stdio.h" #include "string" // std::string, std::to_string #include "Accelerometer.h" #include "Anemometer.h" #include "Algorithm.h" #include "MotorDriver.h" #include "Defs_Sett.h" #include "Pushbutton.h" #include "PinAssignment.h" #include "LCD.h" #include "Misc.h" #include "temp_fans.h" #include <string> #include "EthernetInterface.h" #include "Inverter.h" #include "GUI.h" #define timer_read_s(x) chrono::duration_cast<chrono::seconds>((x).elapsed_time()).count() #define timer_read_ms(x) chrono::duration_cast<chrono::milliseconds>((x).elapsed_time()).count() //Initialize Global Variables I2C i2c(PIN_SDA,PIN_SCL); Anemometer ane; // MotorDriver motor; LowPowerTimer t,t_mode, t_disp; int mode = OP_CALIBRATION; EthernetInterface eth; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int main() { i2c.frequency(I2C_FREQ); Accelerometer acc(&i2c); //Accelerometer LCD lcd(&i2c); temp_fans fan; float ang_P,ang_R; float ref_R1,ref_R2; int t_elapsed; int wthres = WIND_THRES_INIT; //FLAGS int flag_time = 1; //Normal mode time int flag_idle = 0; //Idling time int flag_disp = 1; //Anti-flickering int flag_bres = 0; //Flag for checking button released int flag_flas = 1; //Flag for flashing symbol bool flag_eth; //Flag for ethernet connection bool flag_aTrack; //Flag for active tracking (0 - offline, 1 - online) bool flag_powerOn; float sun_angle; //PUSH BUTTONS Pushbutton bt_inc(PIN_BTINC); Pushbutton bt_dec(PIN_BTDEC); Pushbutton bt_fn(PIN_BTFN,&mode,&flag_disp,PIN_BTINC); string topL = "INITIALIZING"; string botL = ""; lcd.LCD_display(topL, botL); eth.connect(); GUI gui("ws://int-sol-ref.herokuapp.com/", ð, &flag_eth); Inverter inverter("int-sol-ref.herokuapp.com", 80, ð); bt_fn.setConnected(flag_eth); t.start(); //Start timer t_disp.start(); if (flag_eth){gui.getSunAngle();} wait_us(1000000); topL = "PUT SENSORS IN"; botL = "CALIBRATION SLOT"; lcd.LCD_display(topL, botL); while(1) { switch(mode) { case OP_PLACEMENT:{ if(flag_disp){ topL = "CALIBRATING"; botL = ""; lcd.LCD_display(topL,botL); acc.calibrate(); topL = "PUT SENSOR ON"; botL = "PANEL&REFLECTORS"; lcd.LCD_display(topL,botL); wait_us(1000000); lcd.LCD_display(topL,botL); flag_disp = 0; } break; } //////////////////////////////////////////////////////////////////////////////// case OP_CONFIRM:{ while(mode == OP_CONFIRM){ topL = "R1 || P || R2"; botL = Misc::itos(acc.getAngle(S_R1),3) + "||" + Misc::itos(acc.getAngle(S_PANEL),3) + "||" + Misc::itos(acc.getAngle(S_R2),3); lcd.LCD_display(topL,botL); flag_disp = 0; wait_us(LCD_RRATE); } } //////////////////////////////////////////////////////////////////////////////// case OP_NORMAL:{ if (flag_eth){gui.getSunAngle();} if (flag_eth){gui.receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);} fan.checkTemp(&mode);if(mode != OP_NORMAL){break;} ane.checkWind(&mode);if(mode != OP_NORMAL){break;} if (flag_eth){gui.windSpeed(ane.getWind());} topL = "NORMAL:IDLING"; if(timer_read_ms(t_disp) >= LCD_RRATE){ botL = Misc::itos(ane.getWind(&flag_disp),3) + "kph | " + Misc::itos(fan.getTemp()) + "C"; t_disp.reset(); t_disp.start(); } if(flag_disp){ lcd.LCD_display(topL,botL); flag_disp = 0; } if(flag_time) //If delay interval has passed { ane.checkWind(&mode); //Get Angle of Panel if(flag_aTrack) ang_P = acc.getAngle(S_PANEL); else{ if (flag_eth){gui.receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);} ang_P = sun_angle; } //Calculate the Angle of Both Reflector ref_R1 = Algorithm::calcAngle(1,ang_P); ref_R2 = Algorithm::calcAngle(2,ang_P); //Moving Reflector 1 ang_R = acc.getAngle(S_R1); while(ang_R <= ref_R1 && !acc.checkAngle(ref_R1,ang_R) && mode == OP_NORMAL) { if (flag_eth){gui.receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);} if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_NORMAL){break;} ane.checkWind(&mode);if(mode != OP_NORMAL){break;} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "NORMAL:R1 <=>" : "NORMAL:R1 <-=->"; flag_flas = !flag_flas; botL = Misc::itos(ane.getWind(&flag_disp),3) + "kph | " + Misc::itos(fan.getTemp()) + "C"; t_disp.reset(); t_disp.start(); } lcd.LCD_display(topL,botL); motor.moveForward(M1); ang_R = acc.getAngle(S_R1); } while(ang_R >= ref_R1 && !acc.checkAngle(ref_R1,ang_R) && mode == OP_NORMAL) { if (flag_eth){gui.receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);} if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_NORMAL){break;} ane.checkWind(&mode);if(mode != OP_NORMAL){break;} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "NORMAL:R1 > = < " : "NORMAL:R1 ->=<-"; flag_flas = !flag_flas; botL = Misc::itos(ane.getWind(&flag_disp),3) + "kph | " + Misc::itos(fan.getTemp()) + "C"; t_disp.reset(); t_disp.start(); } lcd.LCD_display(topL,botL); motor.moveBackward(M1); ang_R = acc.getAngle(S_R1); } motor.stop(); //Moving Reflector 2 ang_R = acc.getAngle(S_R2); while(ang_R <= ref_R2 && !acc.checkAngle(ref_R2,ang_R) && mode == OP_NORMAL) { if (flag_eth){gui.receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);} if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_NORMAL){break;} ane.checkWind(&mode);if(mode != OP_NORMAL){break;} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "NORMAL:R2 <=>" : "NORMAL:R2 <-=->"; flag_flas = !flag_flas; botL = Misc::itos(ane.getWind(&flag_disp),3) + "kph | " + Misc::itos(fan.getTemp()) + "C"; t_disp.reset(); t_disp.start(); } lcd.LCD_display(topL,botL); motor.moveForward(M2); ang_R = acc.getAngle(S_R2); } while(ang_R >= ref_R2 && !acc.checkAngle(ref_R2,ang_R) && mode == OP_NORMAL) { if (flag_eth){gui.receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);} if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_NORMAL){break;} ane.checkWind(&mode);if(mode != OP_NORMAL){break;} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "NORMAL:R2 > = < " : "NORMAL:R2 ->=<-"; flag_flas = !flag_flas; botL = Misc::itos(ane.getWind(&flag_disp),3) + "kph | " + Misc::itos(fan.getTemp()) + "C"; t_disp.reset(); t_disp.start(); } lcd.LCD_display(topL,botL); motor.moveBackward(M2); ang_R = acc.getAngle(S_R2); } motor.stop(); flag_time = 0; //Reset timer flag flag_disp = 1; //Reset display flag t.reset(); //Reset timer } t_elapsed = (int)timer_read_s(t); flag_time = (t_elapsed >= TIME_NORMAL) ? 1 : 0; //Enable flag if delay interval has passed flag_idle = 0; break; } //////////////////////////////////////////////////////////////////////////////// case OP_WIND:{ if (flag_eth){gui.receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);} if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_WIND){break;} ane.checkWind(&mode);if(mode != OP_WIND){break;} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "WIND SAFETY *!*" : "WIND SAFETY"; flag_flas = !flag_flas; botL = Misc::itos(ane.getWind(&flag_disp),3) + "kph | " + Misc::itos(fan.getTemp()) + "C"; t_disp.reset(); t_disp.start(); } if(flag_disp){ lcd.LCD_display(topL,botL); flag_disp = 0; } //Move all motor backward motor.moveBackward(M_ALL); flag_time = 1; //Set the system in motion once windspeed has subsided break; flag_idle = 0; break; } //////////////////////////////////////////////////////////////////////////////// case OP_MANUAL1:{ if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_MANUAL1){break;} topL = "MANUAL:M1"; botL = Misc::itos(ane.getWind(&flag_disp)) + "kph*" + Misc::itos(fan.getTemp()) + "C*" + ((flag_eth)?Misc::itos(inverter.getPower()):"---") + "W"; if(flag_disp){ lcd.LCD_display(topL,botL); flag_disp = 0; } //TIMEOUT //////////////////////////////////////////////////////////////////// if(!flag_idle) //Check if button is not pressed { t_mode.reset(); t_mode.start(); flag_idle = 1; //Indicate idling } else if(timer_read_s(t_mode) > TIME_MANUAL_TIMEOUT) { mode = OP_NORMAL; flag_disp = 1; break; } //////////////////////////////////////////////////////////////////// while(bt_inc.read()) //Extend { if (flag_eth){gui.windSpeed(ane.getWind());} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "MANUAL:M1 <=> " : "MANUAL:M1 <-=->"; flag_flas = !flag_flas; t_disp.reset(); t_disp.start(); botL = "EXTENDING"; lcd.LCD_display(topL,botL); } flag_idle = 0; motor.moveForward(M1); } while(bt_dec.read()) //Retract { if (flag_eth){gui.windSpeed(ane.getWind());} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "MANUAL:M1 > = <" : "MANUAL:M1 ->=<-"; flag_flas = !flag_flas; t_disp.reset(); t_disp.start(); botL = "RETRACTING"; lcd.LCD_display(topL,botL); } flag_idle = 0; motor.moveBackward(M1); } if(!bt_inc.read() && !bt_dec.read() && !flag_disp) { flag_disp = 1; motor.stop(); } flag_time = 1; break; } //////////////////////////////////////////////////////////////////////////////// case OP_MANUAL2:{ if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_MANUAL2){break;} topL = "MANUAL:M2"; botL = Misc::itos(ane.getWind(&flag_disp),3) + "kph | " + Misc::itos(fan.getTemp()) + "C"; if(flag_disp){ lcd.LCD_display(topL,botL); flag_disp = 0; } //TIMEOUT //////////////////////////////////////////////////////////////////// if(!flag_idle) //Check if button is not pressed { t_mode.reset(); t_mode.start(); flag_idle = 1; //Indicate idling } else if(timer_read_s(t_mode) > TIME_MANUAL_TIMEOUT) { mode = OP_NORMAL; flag_disp = 1; break; } //////////////////////////////////////////////////////////////////// while(bt_inc.read()) //Extend { if (flag_eth){gui.windSpeed(ane.getWind());} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "MANUAL:M2 <=> " : "MANUAL:M2 <-=->"; flag_flas = !flag_flas; t_disp.reset(); t_disp.start(); botL = "EXTENDING"; lcd.LCD_display(topL,botL); } flag_idle = 0; motor.moveForward(M2); } while(bt_dec.read()) //Retract { if (flag_eth){gui.windSpeed(ane.getWind());} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "MANUAL:M2 > = <" : "MANUAL:M2 ->=<-"; flag_flas = !flag_flas; t_disp.reset(); t_disp.start(); botL = "RETRACTING"; lcd.LCD_display(topL,botL); } flag_idle = 0; motor.moveBackward(M2); } if(!bt_inc.read() && !bt_dec.read() && !flag_disp) { flag_disp = 1; motor.stop(); } flag_time = 1; break; } //////////////////////////////////////////////////////////////////////////////// case OP_MANUAL_ALL:{ if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_MANUAL_ALL){break;} topL = "MANUAL:ALL"; botL = Misc::itos(ane.getWind(&flag_disp),3) + "kph | " + Misc::itos(fan.getTemp()) + "C"; if(flag_disp){ lcd.LCD_display(topL,botL); flag_disp = 0; } //TIMEOUT //////////////////////////////////////////////////////////////////// if(!flag_idle) //Check if button is not pressed { t_mode.reset(); t_mode.start(); flag_idle = 1; //Indicate idling } else if(timer_read_s(t_mode) > TIME_MANUAL_TIMEOUT) { mode = OP_NORMAL; flag_disp = 1; break; } //////////////////////////////////////////////////////////////////// while(bt_inc.read()) //Extend { if (flag_eth){gui.windSpeed(ane.getWind());} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "MANUAL:ALL <=> " : "MANUAL:ALL <-=->"; flag_flas = !flag_flas; t_disp.reset(); t_disp.start(); botL = "EXTENDING"; lcd.LCD_display(topL,botL); } flag_idle = 0; motor.moveForward(M_ALL); } while(bt_dec.read()) //Retract { if (flag_eth){gui.windSpeed(ane.getWind());} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "MANUAL:ALL > = <" : "MANUAL:ALL ->=<-"; flag_flas = !flag_flas; t_disp.reset(); t_disp.start(); botL = "RETRACTING"; lcd.LCD_display(topL,botL); } flag_idle = 0; motor.moveBackward(M_ALL); } if(!bt_inc.read() && !bt_dec.read() && !flag_disp) { flag_disp = 1; motor.stop(); } flag_time = 1; break; } //////////////////////////////////////////////////////////////////////////////// case OP_WSETTING:{ if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_WSETTING){break;} topL = "Threshold:"; botL = Misc::itos(wthres) + " kph"; if(flag_disp){ lcd.LCD_display(topL,botL); flag_disp = 0; } //TIMEOUT //////////////////////////////////////////////////////////////////// if(!flag_idle) //Check if button is not pressed { t_mode.reset(); t_mode.start(); flag_idle = 1; //Indicate idling } else if(timer_read_s(t_mode) > TIME_WSETTING_TIMEOUT) { mode = OP_NORMAL; flag_disp = 1; break; } //////////////////////////////////////////////////////////////////// if(!(flag_bres == 1 && bt_inc.read()) && !(flag_bres == -1 && bt_dec.read())){ if(bt_inc.read() && wthres < WIND_THRES_MAX) { ane.setThres(++wthres); if(flag_eth){gui.survivalSpeed(wthres);} botL = Misc::itos(wthres) + " kph"; lcd.LCD_display(topL,botL); flag_idle = 0; flag_bres = 1; } else if(bt_dec.read() && wthres > WIND_THRES_MIN) { ane.setThres(--wthres); if(flag_eth){gui.survivalSpeed(wthres);} botL = Misc::itos(wthres) + " kph"; lcd.LCD_display(topL,botL); flag_idle = 0; flag_bres = -1; } else{ flag_bres = 0; } } flag_time = 1; //Set the system in motion once done adjusting break; } //////////////////////////////////////////////////////////////////////// case OP_OVERHEAT:{ if (flag_eth){gui.windSpeed(ane.getWind());} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "*!* OVERHEAT *!*": " OVERHEAT "; botL = (flag_flas)? " KEEP DISTANCE " : (" " + Misc::itos(fan.getTemp(),3) + "C"); flag_flas = !flag_flas; t_disp.reset(); t_disp.start(); lcd.LCD_display(topL,botL); } motor.moveBackward(M_ALL); fan.checkTemp(&mode); flag_disp = 1; flag_time = 1; break; } //////////////////////////////////////////////////////////////////////// case OP_OVERHEAT_MAN:{ if (flag_eth){gui.windSpeed(ane.getWind());} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = (flag_flas)? "*!* OVERHEAT *!*": " OVERHEAT "; botL = (flag_flas)? " PRESS FN " : (" " + Misc::itos(fan.getTemp(),3) + "C"); flag_flas = !flag_flas; t_disp.reset(); t_disp.start(); lcd.LCD_display(topL,botL); } motor.stop(); flag_disp = 1; break; } //////////////////////////////////////////////////////////////////////// case OP_POWER_OFF:{ if (flag_eth){gui.receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);} if(mode != OP_POWER_OFF){break;} if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_WIND){break;} if(timer_read_ms(t_disp) >= LCD_RRATE){ topL = "SLEEP MODE"; flag_flas = !flag_flas; botL = Misc::itos(ane.getWind(&flag_disp),3) + "kph | " + Misc::itos(fan.getTemp()) + "C"; t_disp.reset(); t_disp.start(); } if(flag_disp){ lcd.LCD_display(topL,botL); flag_disp = 0; } //Move all motor backward motor.moveBackward(M_ALL); flag_time = 1; //Set the system in motion once windspeed has subsided break; flag_idle = 0; break; } //////////////////////////////////////////////////////////////////////// case OP_ATRACK:{ flag_aTrack = !flag_aTrack; if (flag_eth){gui.windSpeed(ane.getWind());} fan.checkTemp(&mode);if(mode != OP_WSETTING){break;} topL = "TRACKING MODE:"; botL = (flag_aTrack) ? "ACTIVE (ACC)" : "AUTO (ONLINE)"; lcd.LCD_display(topL,botL); flag_disp = 0; wait_us(TIME_ATRACK_TIMEOUT); mode = OP_NORMAL; flag_time = 1; //Set the system in motion once done adjusting break; } //////////////////////////////////////////////////////////////////////// } if (flag_eth){ gui.state(mode); } wait_us(LOOP_DELAY); flag_disp = 1; } } //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////