IUT GEII SEMESTRE 3 SCOOTER PROJECT

Dependencies:   EthernetInterface bloc_io html mbed-rtos mbed

Fork of scooter_mbed_etudiant by ERS3 2015-2016

main.cpp

Committer:
syasya
Date:
2018-01-22
Revision:
1:8d356d22e69c
Parent:
0:e30c9ba95bd4

File content as of revision 1:8d356d22e69c:

#include "EthernetInterface.h"
#include <stdlib.h>
#include <string.h>
#include "mbed.h"
#include "rtos.h" // need for main thread sleep
#include "html.h" // need for html patch working with web server
#include "bloc_io.h"
#define RADIUS  0.22F // wheel size
#define NBPOLES 19 // magnetic pole number
#define DELTA_T 0.2F // speed measurement counting period
#define T_TICKER 0.05 // time for ticker to call function Gaz
#define PI 3.1415 // pie value
#define RESISTANCE // resistance value
#define T_COEF 0.01 // constant for temperature calculation
#define T_REST 0.2 // constant for current mesure 
#define INIT_IREST 60000 // capacite initial en mAs

Bloc_IO MyPLD(p25,p26,p5,p6,p7,p8,p9,p10,p23,p24);// instantiate object needed to communicate with PLD
AnalogIn Val_Poignee(p17);// analog input for gaz connected to mbed
AnalogIn Vbat(p18);// analog input for battery connected to mbed
AnalogIn Vtemp(p19);// analog input for temperature connected to mbed
AnalogIn VImes(p20);// analog input for current connected to mbed
DigitalOut Valid_PWM(p21);// valid pmw mbed pin
InterruptIn Valid_PWM_In(p22); // count value for pole number
Serial pc(USBTX, USBRX); // tx, rx
// Top_Hall Pin




/************ persistent file parameters section *****************/
LocalFileSystem local("local");               // Create the local filesystem under the name "local"







/********************* web server section **********************************/
var_field_t tab_balise[10];  //une balise est présente dans le squelette
int giCounter=0,giCounter2=0;// acces counting
int giMode=0,giFlag=0;//to validate between mode automatic or manual
float gfNmax=0.0,gfNmin=0.0,gfVit=0.0;//initialising values minimum and maximum for equation
int giBrake = 0;
int giPwm=0; //value initial for PWM mode manuel
float gfPwm=0.0; //value initial for PWM mode auto
float gfPwm_final=0.0; //value initial for incrementation PWM mode auto
float gfVit_bride; //speed value (bride) in mode auto
float gfVbat,gfIbat,gfTemp,gfPourc,gfGIrest,gfImes;
float gfIrest = 60000;

Ticker Tick;//Ticker to call function Gaz
Ticker Tick2;//Ticker to call function Vitesse
Ticker Tick3;//Ticker to call function Imesure

/*********************** can bus section  ************/
// determine message ID used to send Gaz ref over can bus
#define _CAN_DEBUG // used to debug can bus activity
#define USE_CAN_REF // uncomment to receive gaz ref over can_bus
CAN can_port (p30, p29); // initialisation du Bus CAN sur les broches 30 (rd) et 29(td) for lpc1768 + mbed shield
bool bCan_Active=false;
int iCounter=0;// a counter for speed counting


DigitalOut led1(LED1); //initialisation des Leds présentes sur le micro-controleur Mbed*/
DigitalOut led2(LED2);
DigitalOut led3(LED3); // blink when can message is sent
DigitalOut led4(LED4); // blink when can message is received





//************ local function prototypes *******************

void Imessure ()  //function for mesuring battery current capacity to be called every 200ms
{

    int ic; // local counter

    ic++;
    if(ic>5) { // to wait for calculation after 1s
        gfIrest = gfIrest - 1000; // because every 1s, the battery consume 1000
        gfGIrest = (gfIrest/INIT_IREST)*100;

        if(gfGIrest>100)
            gfGIrest = 100;
        if(gfGIrest<0)
            gfGIrest=0;

        ic=1;
        gfImes = 0;
    }
    //gfImes = (gfImes + gfVbat)/ic ;
}


void Affiche(void) //function only for display
{
    gfVbat=(25*Vbat.read())/0.33; // battery tension value
    gfIbat=(33000*VImes.read())-13510; // current value
    gfTemp=((Vtemp.read()*3.3)/T_COEF)-273; // surrounding temperature
    gfPourc=((gfPwm*100)/255); // pedal turning percentage

    pc.printf(" Vitesse = %g m/h\n\r",gfVit); //speed diplay
    pc.printf(" Vbat=%.3g \n\r",gfVbat); // battery tension display
    pc.printf(" Ibat=%.2f mA\n\r",gfIbat); //current value display
    pc.printf(" Temperature = %g C\n\r",gfTemp); // surrounding temperature display
    pc.printf(" Pourcentage = %.0f %% \n\r",gfPourc); //pedal turning percentage display
    pc.printf(" Capacite = %.0f %% \n\r",gfGIrest); // battery capacity display

}

void Registre_PLD(void) // function for internal checkups display 
{

    /**** association with block io****/
    int iSect = MyPLD.read() & 7;
    int iDir = MyPLD.read() & 8;
    int iFLTA = MyPLD.read() & 16;
    int iOver_Current = MyPLD.read() & 64;

    pc.printf("\n\r\n\r");

    pc.printf(" Secteur : %d\n\r" , iSect);
    
    //direction
    if ( iDir == 0)
        pc.printf(" Direction = ARRIERE \n\r");
    else {
        pc.printf(" Direction = AVANCE \n\r");
    }
    //braking system
    if ( giBrake == 0)
        pc.printf(" Brake = ON \n\r");
    if ( giBrake != 0)
        pc.printf(" Brake = OFF \n\r");
    //internal error
    if ( iFLTA == 1)
        pc.printf(" Il y a un erreur \n\r");
    if ( iFLTA != 1)
        pc.printf(" Pas d'erreur \n\r");
    //overcurrent
    if ( iOver_Current == 0)
        pc.printf(" Over Current \n\r");
    if ( iOver_Current != 0)
        pc.printf(" Normal Current  \n\r");

    pc.printf("\n\r");

}



/**************** Read persistent data from text file located on local file system ****************/
void Read_file(void)
{
    FILE* Calibrage = fopen("/local/TEST.txt","r");

    if(Calibrage != NULL) {
        pc.printf(" OK\n\r");
        fscanf (Calibrage, "%g %g %g %g", &gfNmin,&gfNmax,&gfVit_bride);
        pc.printf(" Nmin = %.3g \n\r",gfNmin);
        pc.printf(" Nmax = %.3g \n\r",gfNmax);
        pc.printf(" Vbride = %.2f\n\r",gfVit_bride);

    } else {

        pc.printf(" KO\n\r");
    }

    fclose(Calibrage);
}

//************** calibation gaz function needed to record min_gaz and max_gaz value to persistent text file  ******************
void Calibration(void)
{
    char cNext=0; //a variable just to exit command scanf

    FILE* Calibrage =fopen("/local/TEST.txt","w"); //opening file
    if(Calibrage != NULL) { //validation for file existence
        pc.printf(" OK\n\r");
        switch (giFlag) {
            case 0 ://calibration of pedal

                pc.printf(" lachez la poignee, appuyez 'k' et 'entree' \n\r");
                pc.scanf(" %c",&cNext);
                gfNmin = Val_Poignee.read();
                pc.printf(" Nmin = %.3g \n\r",gfNmin);

                pc.printf(" enfoncez la poignee, appuyez 'k' et 'entree'\n\r");
                pc.scanf(" %c",&cNext);
                gfNmax = Val_Poignee.read();
                pc.printf(" Nmax = %.3g \n\r",gfNmax);
                break;

            case 1 ://calibration of maximum speed
                pc.printf(" veuillez saisir la vitesse de la bride : \n\r");
                pc.scanf(" %f",&gfVit_bride);
                break;


        }
    } else {
        pc.printf(" KO\n\r");
    }
    fprintf(Calibrage,"%f %f %f %f",gfNmin,gfNmax,gfVit_bride,gfIrest);//saving infos in text file
    fclose(Calibrage);
}



// ************top hall counting interrupt needed for speed measurement
void toggle(void)
{
    giCounter=giCounter+1;

}

//********************** timer interrupt for speed measurement each 100ms  *************************
void Vitesse(void)
{
    giCounter2=giCounter;
    giCounter=0;

    gfVit=((float)giCounter2*2*PI*RADIUS*3600)/(6*NBPOLES*DELTA_T);// speed calculation
}

/*********************** INITIALISATION **********************/
void Initial(void)
{
    Valid_PWM.write(0);
    MyPLD.write(0);
    Valid_PWM.write(1);
    Read_file();
    Valid_PWM_In.mode(PullUp);

}


//********************* Timer Interrupt for gaz ref management each 10ms   ********************
void Gaz(void)
{
    giBrake = MyPLD.read() & 32;


    switch (giMode) {
        case 0 ://mode manuel

            if (giPwm<0)
                giPwm=0;
            if (giPwm>255)
                giPwm=255;

            MyPLD.write(giPwm);
            break;
        case 1 :// mode auto

            gfPwm = 255*(Val_Poignee.read()-gfNmin)/(gfNmax-gfNmin);
            if (gfPwm<0)
                gfPwm=0;
            if (gfPwm>255)
                gfPwm=255;

            //safety
            if ( giBrake == 0) {
                gfPwm_final = 0;
            } else  if (gfVit >= gfVit_bride) {
                if (gfPwm_final >= 1.0)
                    gfPwm_final = gfPwm_final-1.0;
            } else if (gfPwm_final < gfPwm) {
                gfPwm_final = gfPwm_final+1.0;
            }  else if (gfPwm_final >= gfPwm) {
                gfPwm_final = gfPwm_final-1.0;
            }


            MyPLD.write(gfPwm_final);
            break;
    }
}


/********* main cgi function used to patch data to the web server thread **********************************/





void CGI_Function(void)   // cgi function that patch web data to empty web page
{

    gfVbat=(25*Vbat.read())/0.33;
    gfIbat=(33000*VImes.read())-13510;
    gfTemp=((Vtemp.read()*3.3)/T_COEF)-273;
    gfPourc=((gfPwm*100)/255);

    char ma_chaine4[20]= {}; // needed to form html response
    sprintf (ma_chaine4,"%d",iCounter);// convert speed as ascii string
    Html_Patch (tab_balise,0,ma_chaine4);
    iCounter++;

    sprintf (ma_chaine4,"%f",gfVbat);
    Html_Patch (tab_balise,1,ma_chaine4);// patch first label with dyn.string

    sprintf (ma_chaine4,"%.4f",gfIbat);
    Html_Patch (tab_balise,2,ma_chaine4);

    sprintf (ma_chaine4,"%.4f",gfTemp);
    Html_Patch (tab_balise,3,ma_chaine4);

    sprintf (ma_chaine4,"%.4f",gfPourc);
    Html_Patch (tab_balise,4,ma_chaine4);

    sprintf (ma_chaine4,"%.4f",gfVit);
    Html_Patch (tab_balise,5,ma_chaine4);
    
    sprintf (ma_chaine4,"%.4f",gfGIrest);
    Html_Patch (tab_balise,6,ma_chaine4);


}


/*********************** CAN BUS SECTION  **********************/



void CAN_REC_THREAD(void const *args)
{
    int iCount,iError;

    while (bCan_Active) {
        Thread::wait(100);// wait 100ms

    }

}



//*************************** main function *****************************************
int main()
{
    //pc.printf("\n demarrage\n\r");
    Initial();

    Valid_PWM_In.rise(&toggle);
    Tick.attach(&Gaz,T_TICKER);
    Tick2.attach(&Vitesse,DELTA_T);
    Tick3.attach(&Imessure,T_REST);

    char cChoix=0;

//***************************************** web section ********************************************/
    Init_Web_Server(&CGI_Function); // create and initialize tcp server socket and pass function pointer to local CGI function
    Thread WebThread(Web_Server_Thread);// create and launch web server thread
    /********* main cgi function used to patch data to the web server thread **********************************/
    Gen_HtmlCode_From_File("/local/pagecgi4.htm",tab_balise,7);// read and localise ^VARDEF[X] tag in empty html file
//******************************************* end web section  ************************************* /




//********************* can bus section initialisation *******************************************
    bCan_Active=true;// needed to lauchn CAN thread
    Thread CanThread(CAN_REC_THREAD);// create and launch can receiver  thread
//********************* end can bus section *****************************************************


    while(cChoix!='q' and cChoix!='Q') {
        pc.printf(" veuillez saisir un choix parmi la liste proposee: \n\r");
        pc.printf(" a:Mode Manuel\n\r");
        pc.printf(" b:Mode Auto \n\r");
        pc.printf(" c:Calibration \n\r");
        pc.printf(" d:Registre PLD \n\r");
        pc.printf(" e:Affiche vitesse \n\r");
        pc.printf(" f:Reset capacite \n\r");
        pc.printf(" q:Quitter \n\r");

        /************* multithreading : main thread need to sleep in order to allow web response */
        while (pc.readable()==0) { // determine if char available
            Thread::wait(10);   // wait 10 until char available on serial input
        }
        /************* end of main thread sleep  ****************/



        pc.scanf(" %c",&cChoix);
        switch (cChoix) {
            case 'a':
                giMode=0;//activation mode manual 
                pc.printf(" veuillez saisir la valeur Pwm (0 jusqu'au 255) : \n\r");
                pc.scanf("%d",&giPwm);
                break;

            case 'b':
                giMode=1;//activation mode auto
                giFlag=1;//activation calibration for speed limit
                Calibration();
                break;

            case 'c':
                giMode=0;//activation mode manual to stop speed ticker function
                giFlag=0;//activation calibration for pedal 
                Calibration();
                break;

            case 'd':
                giMode=1;//activation mode auto to start speed ticker function
                Registre_PLD();
                break;

            case 'e':
                giMode=1;//activation mode auto
                Affiche();
                break;
                
            case 'f':
                giMode=1;//activation mode auto
                gfIrest=60000; // initialisation 
                break;

            case 'q':
                giMode=0;//activation mode manual
                Valid_PWM.write(0);
                break;
        }
    } // end while

    //************** thread deinit *********************
    // DeInit_Web_Server();
    //bCan_Active=false;
    //CanThread=false;// close can received thread
    pc.printf(" fin programme scooter mbed \n\r");
} // end main