scooter correction for mbed_os V5.2

Dependencies:   bloc_io html_mbed_os

Fork of scooter_mbed by ERS3 2015-2016

main.cpp

Committer:
jlsalvat
Date:
2016-11-26
Revision:
4:b9b0276f5d11
Parent:
3:ac3990c4a479

File content as of revision 4:b9b0276f5d11:



//#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.2F // wheel size
#define NBPOLES 8 // magnetic pole number
#define DELTA_T 0.1F // speed measurement counting period

Ticker IT_Timer_Gaz,IT_Speed;
int gCPT=0;
 float fSpeed=0;
float fTabVal[10];// need to store analog value 
 float fGaz,fTemp,fBat,fIdc;
 float fGAZ_MAX=70,fGAZ_MIN=15;
 unsigned int uiCptImpuls=0;
Bloc_IO MyPLD(p25,p26,p5,p6,p7,p8,p9,p10,p23,p24);// instantiate object needed to communicate with PLD
AnalogIn Gaz(p17),Bat(p18),Temp(p19),Idc(p20);// analog input connected to mbed 
DigitalOut ValidPWM (p21,0);// reset valid pmw pin
Serial pc(USBTX, USBRX); // tx, rx
InterruptIn TopHall(p22);
    
    
 float fGaz_Brute;    
    
/************ persistent file parameters section *****************/
LocalFileSystem local("local");               // Create the local filesystem under the name "local"
 

  
    
    
    
    
/********************* web server section **********************************/
//char * ma_chaine3;
var_field_t tab_balise[10];  //une balise est présente dans le squelette
int giCounter=0;// acces counting


/*********************** can bus section  ************/
#define GAZ_CAN_ID 1000 // 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
CANMessage msg_receive,msg_send;
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 
CAN can_port (p30, p29); // initialisation du Bus CAN sur les broches 30 (rd) et 29(td) for lpc1768 + mbed shield
int iGaz_Can=0;
bool bCan_Active=false;
 

 
//************ prototypes *******************






 //***********
//* functions

/**************** Read persistent data from text file located on local file system ****************/
int Read_File_Data(char * pcFileName)
{
float fRayon;
int iPoles,iVit_Max;
FILE *DataFile;
DataFile= fopen(pcFileName, "rt");
if ( DataFile   == NULL)
   {    printf("\r\nError Open File: %s", pcFileName); //open data file from disk
    return(NULL);
   }
 else
 {fscanf (DataFile,"rayon:%f ",&fRayon);// insert ' ' after %format mode to separe numeric data
 fscanf (DataFile,"poles:%d ",&iPoles);
 fscanf (DataFile,"vit_max:%d ",&iVit_Max);
 fscanf (DataFile,"fgaz_max:%f ",&fGAZ_MAX);
  fscanf (DataFile,"fgaz_min:%f ",&fGAZ_MIN);
 printf("valeurs lues: rayon:%f poles:%d vit_max:%d gaz_max:%f gaz_min:%f \n\r",fRayon,iPoles,iVit_Max,fGAZ_MAX,fGAZ_MIN);
  fclose(DataFile);
  return 0; 
  } 
    
}


/**************** write persitant  data to text file located on local file system ****************/
int Write_File_Data(char * pcFileName)
{
float fRayon=0.45;
int iPoles=10,iVit_Max=15000;
FILE *DataFile;
DataFile= fopen(pcFileName,"wt");

 

if ( DataFile   == NULL)
   {    printf("\r\nError Open File: %s", pcFileName); //open data file from disk
    return(NULL);
   }
 else
 { fprintf (DataFile, "rayon:%f poles:%d vit_max:%d gaz_max:%f gaz_min:%f \n\r",fRayon,iPoles,iVit_Max,fGAZ_MAX,fGAZ_MIN);
    
 printf("valeurs ecrites: rayon:%f poles:%d vit_max:%d gaz_max:%f gaz_min:%f \n\r",fRayon,iPoles,iVit_Max,fGAZ_MAX,fGAZ_MIN);
  fclose(DataFile);
  return 0; 
  } 
    
}






//************** needed to record min_gaz and max_gaz value to persistent text file  ******************
void Calibrate_Gaz(void)
{ char cJunk;     

 fGaz=Gaz.read()*100;
       fTemp=Temp.read()*100;
       fBat=Bat.read()*100;
       fIdc=Idc.read()*100;
    
    pc.printf("mettre la poignee au minimum et appuyer sur une touche \n");
    pc.scanf(" %c",&cJunk);
    fTabVal[0]=Gaz.read()*100;// read min gaz value)
    fGAZ_MIN=fTabVal[0];// update local GAZ_MIN constante
    pc.printf("mettre la poignee au maximum et appuyer sur une touche \n");
    pc.scanf(" %c",&cJunk);
    fTabVal[1]=Gaz.read()*100;// read max gaz value
      fGAZ_MAX=fTabVal[1];// update local GAZ_MIN constante
    pc.printf("calibration terminee: gaz_min=%f    gaz_max=%f \n",fTabVal[0],fTabVal[1]); 
    Write_File_Data("/local/persist.txt"); // write persistent data to text file

}

// ************top hall counting interupt needed for speed measurement
void SpeedCount(void)
{uiCptImpuls++;// top hall encoured increment speed counter
    }


//********************** timer interrupt for speed measurement each 100ms  *************************
void MyITSpeed(void)
{unsigned int uiCptSpeed;

uiCptSpeed=uiCptImpuls;// read actual count
uiCptImpuls=0;// reset counter for next counting period
fSpeed=2*(float)3.14159*RADIUS*(float)uiCptSpeed*3600/(6*NBPOLES*DELTA_T);
}
    
    
    


//********************* Timer Interrupt for gaz ref management each 10ms   ********************
void MyITGaz (void) 
{unsigned char byRefPWM=0;

 fGaz=Gaz.read()*100;// read actual gaz
 fBat=Bat.read()*100;// read actual Bat voltage
 fIdc=Idc.read()*100;// read actual Idc current
 fTemp=Temp.read()*100;// readf actual Temp
 
 #ifndef USE_CAN_REF
 fGaz_Brute= (float)255/(fGAZ_MAX-fGAZ_MIN)* (fGaz-fGAZ_MIN);/ use local ref
 #else
 fGaz_Brute= iGaz_Can;// use can bus gaz ref
 #endif
 
 if (fGaz_Brute>255) fGaz_Brute=255;
 if (fGaz_Brute<0) fGaz_Brute=0;
 byRefPWM=(unsigned char) fGaz_Brute;
 MyPLD.write(byRefPWM);// update pwm ref on pld
}


/********* 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
{  char ma_chaine4[20]={};// needed to form html response  
                         sprintf (ma_chaine4,"%d",(int)gCPT++);// convert speed as ascii string
                            Html_Patch (tab_balise,0,ma_chaine4);// patch first label with dyn.string
                            
                            sprintf (ma_chaine4,"%d",(int)(fGaz_Brute*100)/255);// convert count as ascii string
                            Html_Patch (tab_balise,1,ma_chaine4);// patch first label with dyn.string
                            
                             sprintf (ma_chaine4,"%d",(int)fBat);// convert count as ascii string
                            Html_Patch (tab_balise,2,ma_chaine4);// patch first label with dyn.string
                            
                             sprintf (ma_chaine4,"%d",(int)fIdc);// convert count as ascii string
                            Html_Patch (tab_balise,3,ma_chaine4);// patch first label with dyn.string
                           
                             sprintf (ma_chaine4,"%d",(int)fTemp);// convert count as ascii string
                            Html_Patch (tab_balise,4,ma_chaine4);// patch first label with dyn.string
                            
    
    
    }
    
    
  /*********************** CAN BUS SECTION  **********************/
    


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

 while (bCan_Active)
 {Thread::wait(100);// wait 100ms  
    //printf("CAN_REC_Thread\n\r");
    if(can_port.read(msg_receive)) //si on lit un message reçu */
    //can_port.read(msg_receive);
    {iError=0; 
    #ifdef _CAN_DEBUG
    printf("CAN Message received : %s\n id=%d\n\r", msg_receive.data,msg_receive.id);
  # endif
    switch (msg_receive.id) {
      case GAZ_CAN_ID: // received Gaz from can
       sscanf((char *)msg_receive.data,"%03d",&iGaz_Can);// read and convert gaz ref from can bus
       led4=!led4;
        #ifdef _CAN_DEBUG
      for (iCount=0; iCount<=5;iCount++)
            {led4=!led4;
           Thread::wait(100);
            }
         #endif  
       break;
    
    }
    }
    }
    
}
       
    
  

int main() {
    
    char cChoix=0;
int iVal,iRefPWM;


Read_File_Data("/local/persist.txt"); // read persistent data from text file
 //Write_File_Data("/local/persist.txt"); // write persistent data to text file
//***************************************** 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
//******************************************* end web section  ************************************* / 


//ma_chaine3 = Gen_HtmlCode_From_File("/local/pagecgi2.htm",tab_balise,5);// read and localise ^VARDEF[X] tag
Gen_HtmlCode_From_File("/local/compteur.htm",tab_balise,2);// read and localise ^VARDEF[X] tag in empty html file

IT_Timer_Gaz.attach_us(&MyITGaz, 10000);// install timer it each 10ms
IT_Speed.attach_us(&MyITSpeed, 100000);// install timer it each 10ms
TopHall.rise(&SpeedCount);

pc.printf(" programme scooter mbed \n");
MyPLD.write(0);// set initial PWM ref=0
ValidPWM.write(1);// enable pwm generator

can_port.frequency(125000); //on impose une fréquence commune pour etre s’incroniser
//can_port.attach(&CAN_REC_IRQ); // install CAN BUS IRQ on data received 
bCan_Active=true;
Thread CanThread(CAN_REC_THREAD);// create and launch can receiver  thread


while(cChoix!='q' and cChoix!='Q')
{/*pc.printf(" veuillez saisir un choix parmi la liste proposee: \n");
 pc.printf(" a:saisie consigne pwm \n");
pc.printf(" b:lecture registre PLD \n");
pc.printf(" c:lecture ADC 4 voies \n");
pc.printf(" d:calibration poignee Gaz \n");
pc.printf(" e:affichage vitesse  \n");
 pc.printf(" q:quitter \n");*/
 /************* multithreading : main thread need to sleep in order to allow web response */
 while (pc.readable()==0) // determine if char availabler
 {Thread::wait(10);} // wait 10 until char available on serial input
 /************* end of main thread sleep  ****************/ 
 pc.scanf(" %c",&cChoix);
 switch (cChoix){
     case 'a': pc.printf(" veuillez saisir une consigne pwm entre 0 et 255 \n");
     pc.scanf("%d",&iRefPWM);
     if (iRefPWM>255) iRefPWM=255;
        if (iRefPWM<0) iRefPWM=0;
     MyPLD.write((unsigned char)iRefPWM);// update pwm ref on pld
     break;
     case 'b': iVal=MyPLD.read();// read PLd internal register
       pc.printf("valeur lue dans le registre PLD: %02x \n",iVal);
       pc.printf("secteur hall: %01d \n",iVal&0x07);
       pc.printf("direction:%01d \n",(iVal&0x08)>>3);
       pc.printf("flta:%01d \n",(iVal&0x10)>>4);
       pc.printf("brake:%01d \n",(iVal&0x20)>>5);
       pc.printf("overCurrent:%01d \n",(iVal&0x40)>>6);
       break;
       
       case 'c': // lecture ADC 4 voies
       fGaz=Gaz.read()*100;
       fTemp=Temp.read()*100;
       fBat=Bat.read()*100;
       fIdc=Idc.read()*100;
       pc.printf("valeur gaz:%3f  Temperature:%3f   Vbat:%3f   Idc:%3f \n",fGaz,fTemp,fBat,fIdc);
       pc.printf("valeur temp:%3f \n\r",fTemp*5.1282-53.53);
       break;
       
       case 'd': // calibration poignée gaz
       Calibrate_Gaz();
       break;
        case 'e': // display actual speed m/h
         pc.printf("vitesse=%f m/h \n",fSpeed);
         break;
     
     case 'q': break;
     }

 /*for (iIndex=0;iIndex<=255;iIndex++)
 {MyPLD.write((unsigned char) iIndex);
 // iVal=MyPLD.read();
     
        wait_ms(0.02);
    }*/
    }
    IT_Timer_Gaz.detach();// uninstall timer interrupt
    IT_Speed.detach();// uninstall timer interrupt
    MyPLD.write(0);// stop motor before exiting
    ValidPWM.write(0);// disable pwm generator
     DeInit_Web_Server();
     bCan_Active=false;
     CanThread=false;// close can received thread
    pc.printf(" fin programme scooter mbed \n");
}