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-04-15
Revision:
35:aa4395b4a1a0
Parent:
32:7b58f5574b7a

File content as of revision 35:aa4395b4a1a0:

/* 
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, t_recon, t_wind;
int mode = OP_ETHERNET;
int prevm = mode;
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
int flag_cali = 0; //Flag for calibration
int flag_rec = 0; //Flag for auto reconnection
bool flag_eth = false; //Flag for ethernet connection
bool flag_aTrack; //Flag for active tracking (0 - offline, 1 - online)
bool flag_powerOn = true;
float sun_angle;
int pow;

//PUSHBUTTONS
Pushbutton bt_inc(PIN_BTINC);
Pushbutton bt_dec(PIN_BTDEC);
Pushbutton bt_fn(PIN_BTFN,&mode,&flag_disp,PIN_BTINC);

//ETHERNET INTERFACE
GUI* gui;
Inverter* inverter;

string topL = "INITIALIZING";
string botL = "";
lcd.LCD_display(topL, botL);

t.start(); //Start timer
t_disp.start();
t_wind.start();

while(1)
{
    switch(mode)
    {
        case OP_ETHERNET:{
            topL = "CONNECT ONLINE?";
            botL = "NO[DE]   YES[IN]";
            lcd.LCD_display(topL,botL);
            while(true){
                if(bt_inc.read()){
                    topL = "CONNECTING";
                    botL = "";
                    lcd.LCD_display(topL, botL);
                    flag_rec = 1;
                    eth.connect();
                    gui = new GUI("ws://int-sol-ref.herokuapp.com/", &eth, &flag_eth);
                    inverter = new Inverter("int-sol-ref.herokuapp.com", 80, &eth);
                    bt_fn.setConnected(flag_eth);
                    
                    if (flag_eth){gui->getSunAngle();}
                    if (flag_eth){
                        topL = "ETHERNET";
                        botL = "CONNECTED";
                        lcd.LCD_display(topL, botL);
                    }
                    else{
                        topL = "ETHERNET";
                        botL = "NOT CONNECTED";
                        lcd.LCD_display(topL, botL);
                    }
                    wait_us(1000000);
                    t_recon.start();
                    break;
                }
                else if(bt_dec.read()){
                    flag_rec = 0;
                    break;
                }
            }
            
            mode = OP_CALIBRATION;
            break;
        }
////////////////////////////////////////////////////////////////////////////////
        case OP_CALIBRATION:{
            if(flag_disp){
                topL = "PUT SENSORS IN";
                botL = "CALIBRATION SLOT";
                lcd.LCD_display(topL, botL);
                flag_disp = 0;
            }
            break;
        }
////////////////////////////////////////////////////////////////////////////////
        case OP_PLACEMENT:{
            if(flag_cali == 0){
                topL = "CALIBRATING";
                botL = "";
                lcd.LCD_display(topL,botL);
                acc.calibrate();
                topL = "PUT SENSOR ON";
                botL = "PANEL&REFLECTORS";
                lcd.LCD_display(topL,botL);
                flag_cali = 1;
            }
            flag_disp = 1;
            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 && prevm != mode){gui->state(mode);}
            if (flag_eth){gui->getSunAngle();}
            if (flag_eth){gui->receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);}
            prevm = mode;
            mode = (flag_powerOn) ? mode : OP_POWER_OFF; if(mode != OP_NORMAL){break;}
            fan.checkTemp(&mode);if(mode != OP_NORMAL){break;}
            ane.checkWind(&mode);if(mode != OP_NORMAL){break;}
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            topL = "NORMAL:IDLING";
            topL = (flag_aTrack) ? topL : "*" + topL;
            if(timer_read_ms(t_disp) >= LCD_RRATE){
                botL = Misc::itos(ane.getWind(&flag_disp)) + "kph " + Misc::itos(fan.getTemp()) + "C "
                        + ((flag_eth)?Misc::itos(inverter->getPower()):"---") + "W";
                t_disp.reset();
                t_disp.start();
                lcd.LCD_display(topL,botL);
            }
            
            pow = (flag_eth) ? inverter->getPower() : -1;
            if(pow == -1 || pow > THRESHOLD_PER*MAX_POWER){
                break;
            }
            
            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);}
                    mode = (flag_powerOn) ? mode : OP_POWER_OFF; if(mode != OP_NORMAL){break;}
                    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);}
                    mode = (flag_powerOn) ? mode : OP_POWER_OFF; if(mode != OP_NORMAL){break;}
                    if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                    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 <-=->";
                        topL = (flag_aTrack) ? topL : "*" + topL;
                        flag_flas = !flag_flas;
                        botL = Misc::itos(ane.getWind(&flag_disp)) + "kph " + Misc::itos(fan.getTemp()) + "C "
                        + ((flag_eth)?Misc::itos(inverter->getPower()):"---") + "W";
                        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);}
                    mode = (flag_powerOn) ? mode : OP_POWER_OFF; if(mode != OP_NORMAL){break;}
                    if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                    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 ->=<-";
                        topL = (flag_aTrack) ? topL : "*" + topL;
                        flag_flas = !flag_flas;
                        botL = Misc::itos(ane.getWind(&flag_disp)) + "kph " + Misc::itos(fan.getTemp()) + "C "
                        + ((flag_eth)?Misc::itos(inverter->getPower()):"---") + "W";
                        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);}
                    mode = (flag_powerOn) ? mode : OP_POWER_OFF; if(mode != OP_NORMAL){break;}
                    if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                    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 <-=->";
                        topL = (flag_aTrack) ? topL : "*" + topL;
                        flag_flas = !flag_flas;
                        botL = Misc::itos(ane.getWind(&flag_disp)) + "kph " + Misc::itos(fan.getTemp()) + "C "
                        + ((flag_eth)?Misc::itos(inverter->getPower()):"---") + "W";
                        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);}
                    mode = (flag_powerOn) ? mode : OP_POWER_OFF; if(mode != OP_NORMAL){break;}
                    if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                    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 ->=<-";
                        topL = (flag_aTrack) ? topL : "*" + topL;
                        flag_flas = !flag_flas;
                        botL = Misc::itos(ane.getWind(&flag_disp)) + "kph " + Misc::itos(fan.getTemp()) + "C "
                        + ((flag_eth)?Misc::itos(inverter->getPower()):"---") + "W";
                        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 && prevm != mode){gui->state(mode);}
            if (flag_eth){gui->receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);}
            mode = (flag_powerOn) ? mode : OP_POWER_OFF; if(mode != OP_WIND){break;}
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            prevm = mode;
            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)) + "kph " + Misc::itos(fan.getTemp()) + "C "
                        + ((flag_eth)?Misc::itos(inverter->getPower()):"---") + "W";
                lcd.LCD_display(topL,botL);
                t_disp.reset();
                t_disp.start();
            }
            
            //Move all motor backward
            motor.moveBackward(M_ALL);
            flag_time = 1; //Set the system in motion once windspeed has subsided
            flag_idle = 0;
            break;
        }
////////////////////////////////////////////////////////////////////////////////
        case OP_MANUAL1:{
            if (flag_eth && prevm != mode){gui->state(mode);}
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            prevm = mode;
            fan.checkTemp(&mode);if(mode != OP_MANUAL1){break;}
            topL = "MANUAL:M1";
            botL = Misc::itos(ane.getWind(&flag_disp)) + "kph " + Misc::itos(fan.getTemp()) + "C "
                        + Misc::itos(acc.getAngle(S_R1)) + "deg";
            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 && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                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 = "EXTEND" + Misc::blank(1) + Misc::itos(acc.getAngle(S_R1)) + "deg";
                    lcd.LCD_display(topL,botL);
                }
                    
                flag_idle = 0;
                motor.moveForward(M1);
            }
            while(bt_dec.read()) //Retract
            {
                if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                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 = "RETRACT"+ Misc::blank(1) + Misc::itos(acc.getAngle(S_R1)) + "deg";
                    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 && prevm != mode){gui->state(mode);}
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            prevm = mode;
            fan.checkTemp(&mode);if(mode != OP_MANUAL2){break;}
            topL = "MANUAL:M2";
            botL = Misc::itos(ane.getWind(&flag_disp)) + "kph " + Misc::itos(fan.getTemp()) + "C "
                        + Misc::itos(acc.getAngle(S_R2)) + "deg";
            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 && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                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 = "EXTEND" + Misc::blank(1) + Misc::itos(acc.getAngle(S_R2)) + "deg";
                    lcd.LCD_display(topL,botL);
                }
                    
                flag_idle = 0;
                motor.moveForward(M2);
            }
            while(bt_dec.read()) //Retract
            {
                if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                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 = "RETRACT" + Misc::blank(1) + Misc::itos(acc.getAngle(S_R2)) + "deg";
                    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 && prevm != mode){gui->state(mode);}
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            prevm = mode;
            fan.checkTemp(&mode);if(mode != OP_MANUAL_ALL){break;}
            topL = "MANUAL:ALL";
            botL = Misc::itos(ane.getWind(&flag_disp)) + "kph " + Misc::itos(fan.getTemp()) + "C " 
                    + Misc::itos(acc.getAngle(S_R1)) + "|" + Misc::itos(acc.getAngle(S_R2));
            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 && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                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 = "EXTEND" + Misc::blank(1) + Misc::itos(acc.getAngle(S_R1)) + "|" + Misc::itos(acc.getAngle(S_R2));
                    lcd.LCD_display(topL,botL);
                }
                    
                flag_idle = 0;
                motor.moveForward(M_ALL);
            }
            while(bt_dec.read()) //Retract
            {
                if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
                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 = "RETRACT" + Misc::blank(1) + Misc::itos(acc.getAngle(S_R1)) + "|" + Misc::itos(acc.getAngle(S_R2));
                    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 && prevm != mode){gui->state(mode);}
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            prevm = mode;
            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)
                {
                    wthres += WIND_INC;
                    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)
                {
                    wthres -= WIND_INC;
                    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 && prevm != mode){gui->state(mode);}
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            prevm = mode;
            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 && prevm != mode){gui->state(mode);}
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            prevm = mode;
            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 && prevm != mode){gui->state(mode);}
            if (flag_eth){gui->receives(&wthres, &flag_aTrack, &flag_powerOn,&sun_angle);}
            prevm = mode;
            if(mode != OP_POWER_OFF){break;}
            if(flag_powerOn){
                mode = OP_NORMAL;
                break;
            }
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            fan.checkTemp(&mode);if(mode != OP_POWER_OFF){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();
                lcd.LCD_display(topL,botL);
            }
            
            //Move all motor backward
            motor.moveBackward(M_ALL);
            flag_time = 1; //Set the system in motion once windspeed has subsided
            break;
        }
        ////////////////////////////////////////////////////////////////////////
        case OP_ATRACK:{
            if (flag_eth && prevm != mode){gui->state(mode);}
            prevm = mode;
            flag_aTrack = !flag_aTrack;
            gui->activeTracking(flag_aTrack);
            if (flag_eth && timer_read_ms(t_wind) >= TIME_GUIWIND){gui->windSpeed(ane.getWind());t_wind.reset();t_wind.start();}
            fan.checkTemp(&mode);if(mode != OP_ATRACK){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;
        }
        ////////////////////////////////////////////////////////////////////////
        case OP_RECONNECT:{
            topL = "CONNECTING";
            botL = "";
            lcd.LCD_display(topL,botL);
            
            for(int i = 0; (i < CONN_N && !flag_eth); i++){
                eth.connect();
                gui->refreshConnection(URL,&flag_eth);
                wait_us(1000000);
                inverter->connect(URL, PORT);
            }
            wait_us(1000000);
            bt_fn.setConnected(flag_eth);
            
            if (flag_eth){gui->getSunAngle();}
            if (flag_eth){
                topL = "ETHERNET";
                botL = "CONNECTED";
                lcd.LCD_display(topL, botL);
            }
            else{
                topL = "ETHERNET";
                botL = "NOT CONNECTED";
                lcd.LCD_display(topL, botL);
            }
            wait_us(TIME_RECONNECT_TIMEOUT);
            
            mode = OP_NORMAL;
            flag_time = 1; //Set the system in motion once done adjusting
            break;
        }
        ////////////////////////////////////////////////////////////////////////
    }
    if(!flag_eth && timer_read_s(t_recon) >= TIME_RECON && flag_rec){
        eth.connect();
        gui->refreshConnection(URL,&flag_eth);
        inverter->connect(URL, PORT);
        bt_fn.setConnected(flag_eth);
    }
        
    wait_us(LOOP_DELAY);
}

}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////