Edson Manoel da Silva / Mbed 2 deprecated Pedometer

Dependencies:   MMA8452 N5110 PowerControl mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /**
00002 @file main.cpp
00003  
00004 @brief Pedometer implementation using the sensor Triple Axis Accelerometer Breakout - MMA8452Q
00005  
00006 */
00007 
00008 #include "main.h"
00009 
00010 int main ()
00011 {
00012     /// Finite State Machine that cotrols the whole system
00013     //Setting the initial state. Avoiding rubish values
00014     state  = 0;
00015     I1_flag  = 0;
00016     I2_flag  = 0;
00017     
00018     // Adressing the rise of pin 15(which is connected to I1 of Sensor)to the interruption routine 1
00019     I1.rise(&Interrupt);
00020     
00021     // Adressing the rise of pin 16(which is connected to I2 of Sensor)to the interruption routine 2
00022     I2.rise(&Interrupt2);  
00023 
00024     while(1)
00025     {    
00026         // Main state machine 
00027         switch (state )
00028         {
00029             // Keep the device sleeping if no interruption is generated
00030             case 0:
00031             {
00032                     wait(0.7); 
00033                     // If an interruption is generated, check where it came from
00034                     if(I1_flag )
00035                     {
00036                         // Reading the cause of the interruption
00037                         Int_SourceSystem  = mma8452.readByteFromRegister(INT_SOURCE);
00038                         // Checking if the Transient detection is the cause of the interruption generated
00039                         if ((Int_SourceSystem &0x20)==0x20) 
00040                         {
00041                             // Clearing the interrupt system for Transient Detection
00042                             Int_SourceTrans  = mma8452.readByteFromRegister(TRANSIENT_SRC); 
00043                             // Clearing the interrupt system for Pulse Detection
00044                             Int_SourceTrans  = mma8452.readByteFromRegister(PULSE_SRC); 
00045                             Int_SourceSystem  = 0;
00046                             // Wait 200ms to make sure the intrrupt system is cleaned
00047                             wait(0.2); 
00048                             I1_flag  = 0; 
00049                             I2_flag  = 0; 
00050                             lcd.init();
00051                             // Choose the normal colour mode
00052                             lcd.normalMode();
00053                             // Set the LED backlight to 10%  
00054                             lcd.setBrightness(0.1);
00055                             // Clear the screen
00056                             lcd.clear();
00057                             // Starts the execution timer for next Menu
00058                             timer1.attach(&TimerExpired1,20.0);
00059                             timerFlag1  = 0;
00060                             // Going to the initial screen
00061                             state  = 1;
00062                        
00063                         }
00064                     }
00065                     // If no interruption is generated, it keeps mbed sleeping and display turned off
00066                     else
00067                     {
00068                         lcd.turnOff();
00069                         // Standard initialisation used here due to different initialisations settings used through the code
00070                         // Sets the scale to 4g, 100Hz of ODR and set the Transient and Pulse Detection
00071                         mma8452.init();
00072                         timer1.detach();
00073                         timer2.detach();
00074                         timerFlag1  = 0;
00075                         timerFlag2  = 0;
00076                         Sleep();
00077                     }       
00078                 break;
00079             }
00080             // Wait for an user command befor the timer counting ends
00081             case 1:
00082             {
00083                     lcd.printString("Welcome!",0,0);
00084                     lcd.printString("Tap for graph",0,2);
00085                     lcd.printString("Or",0,3);
00086                     lcd.printString("Shake for",0,4);
00087                     lcd.printString("Counting steps",0,5); 
00088                     wait(1); 
00089 
00090                     // Checking if an Transient Detection interrupt is generated (Countinuos shake)
00091                     if(I1_flag )
00092                     {
00093                         // Reading the cause of the interruption
00094                         Int_SourceSystem  = mma8452.readByteFromRegister(INT_SOURCE);
00095                         // If the Transient detection is the cause of the interrupt generated
00096                         if ((Int_SourceSystem &0x20)==0x20)
00097                         {
00098                             // Goes to step counting screen
00099                             state  = 2;
00100                         }
00101                     }
00102 
00103                     // Checking if an Pulse Detection interrupt is generated (Just a tap to left or right)                    
00104                     else if((I2_flag )&&(!I1_flag ))
00105                     {
00106                         // Reading the cause of the interrupt
00107                         Int_SourceSystem  = mma8452.readByteFromRegister(INT_SOURCE);
00108                         // If the Pulse detection is the cause of the interrupt generated
00109                         if ((Int_SourceSystem &0x08)==0x08) 
00110                         {
00111                             // Clearing the Transient interrupt system
00112                             Int_SourceTrans  = mma8452.readByteFromRegister(TRANSIENT_SRC);
00113                             // Clearing the Transient interrupt system
00114                             Int_SourceTrans  = mma8452.readByteFromRegister(PULSE_SRC);
00115                             Int_SourceSystem  = 0;
00116                             // Wait 200ms to make sure the intrrupt system is cleaned
00117                             wait(0.2);
00118                             I1_flag  = 0; 
00119                             I2_flag  = 0;   
00120                             timer1.attach(&TimerExpired1,20.0);
00121                             timerFlag1  = 0;
00122                             lcd.clear();
00123                             // Going to the Km/day graph screen
00124                             state  = 3;
00125                         }
00126                     }
00127                     // If no interrupt is generated and the timer finishes the counting, turn off the device again
00128                     else if(timerFlag1 )
00129                     {
00130                         timerFlag1  = 0;
00131                         Int_SourceTrans  = mma8452.readByteFromRegister(TRANSIENT_SRC); 
00132                         Int_SourceTrans  = mma8452.readByteFromRegister(PULSE_SRC); 
00133                         Int_SourceSystem  = 0;
00134                         wait(0.2);
00135                         I1_flag  = 0;  
00136                         I2_flag  = 0;  
00137                         state  = 0;   
00138                     }   
00139                 break;
00140             }
00141             // Steps counting Screen. Also save data.
00142             case 2:
00143             {
00144                     // Changes the scale to 2g, the ODR to 800Hz and set the output data to be read from the High Pass Filter
00145                     mma8452.transient_counting();                                                
00146                     lcd.clear();
00147                     buzzer = 0.5;
00148                     lcd.printString("Calibrating...",0,0);
00149                     wait(5);
00150                     // Take a average of the 50 values of the device before counting steps. Kind of calibration
00151                     acc_avg = mma8452.average();  
00152                     buzzer = 0;
00153                     step  = 0; 
00154                     km  = 0;
00155                     leds = 0x04; 
00156                     aux  = 0; 
00157                     timerFlag2  = 0;
00158                     timer3.attach(&TimerExpired3,1);
00159                     // While the timer does not end, keep counting
00160                     while(!timerFlag2 )
00161                     {    
00162                         acceleration = mma8452.readValues();   // read current values 
00163                         sub_x  = acceleration.x - acc_avg.x;
00164                         sub_y  = acceleration.y - acc_avg.y;
00165                         sub_z  = acceleration.z - acc_avg.z;
00166                         acc_vector  = (pow(sub_x ,2.0)+pow(sub_y ,2.0)+pow(sub_z ,2.0)); 
00167                         acc_vector  = sqrt(acc_vector );
00168                         // If the acceleration vector is greater than 0.15, add the steps
00169                         if(acc_vector  > 0.15)
00170                         {
00171                              step  = step  + 2;
00172                              // Runing
00173                              if (acc_vector  > 1.0)
00174                                 km  = km  + 0.002;
00175                              // Walking
00176                              else
00177                                 km  = km  + 0.001;     
00178                         }
00179 
00180                         lcd.clear(); 
00181                               
00182                         length  = sprintf(buffer ,"%6u steps",step ); 
00183                         if (length  <= 14)                 
00184                             lcd.printString(buffer ,0,0);  
00185                         
00186                         length  = sprintf(buffer ,"%6.3f km",km ); 
00187                         if (length  <= 14)                 
00188                             lcd.printString(buffer ,0,1); 
00189                         
00190                         length  = sprintf(buffer ,"%2u:%2u:%2u",hour , minute , second ); 
00191                         if (length  <= 14)                 
00192                             lcd.printString(buffer ,0,2);                             
00193                               
00194                         // get current date    
00195                         time_t seconds = time(NULL);  
00196                         // Convert date to a string
00197                         strftime(buffer , 14 , "%a-%d/%m/%Y", localtime(&seconds));
00198                         lcd.printString(buffer ,0,3);
00199                         
00200                         // Avoiding counting the same steps twice                                       
00201                         wait(0.65);
00202                         
00203                         // If one stops the activity, starts the timer
00204                         if ((acc_vector  <0.15)&& (aux ==0))
00205                         {
00206                             timer2.attach(&TimerExpired2,20.0);
00207                             aux  = 1;
00208                         }
00209                         // If one walks again, reset the timer
00210                         else if ((acc_vector  >0.15)&&(aux  == 1))
00211                         {
00212                             timer2.detach();
00213                             aux  = 0;
00214                         }
00215 
00216                     }   
00217                     buzzer = 0.5;
00218                     wait(3);
00219                     buzzer = 0;
00220                     Int_SourceTrans  = mma8452.readByteFromRegister(TRANSIENT_SRC); 
00221                     Int_SourceTrans  = mma8452.readByteFromRegister(PULSE_SRC);
00222                     Int_SourceSystem  = 0;
00223                     wait(0.2);
00224                     timer3.detach();
00225                     second  = 0;
00226                     minute  = 0;
00227                     hour  = 0;
00228                     I1_flag  = 0;
00229                     timerFlag2  = 0;
00230                     // Saving data to local system File
00231                     writeDataToFile(buffer ,step ,km );
00232                     // Accumulating the steps per day value
00233                     time_t seconds = time(NULL);
00234                     strftime(buffer , 3 , "%u", localtime(&seconds));
00235                     int value = atoi(buffer );   
00236                     km_day [value]=km_day [value]+km ;
00237                     state  = 0;
00238                     break;
00239                }
00240                // Graph Km/day Screen 
00241                case 3:
00242                {
00243                         lcd.printString("Km/day",10,0);
00244                         lcd.printString("8",10,1);
00245                         lcd.printString("6",10,2);
00246                         lcd.printString("4",10,3);
00247                         lcd.printString("2",10,4);
00248                         lcd.printString("0",10,5);
00249                         lcd.drawRect(17,7,60,40,0);
00250                         // Logic to print the graph with all days
00251                         for (int x = 1; x < 30; x++) 
00252                         {
00253                             float n_pix = 8.0/36.0;
00254                             int last_point = ((8.0-km_day [x-1])/(n_pix));
00255                             int point = ((8.0-km_day [x])/(n_pix));
00256                             lcd.drawLine((x-1)+18,last_point+9,x+18,point+9,1);
00257                         }
00258                         lcd.refresh();
00259                         // If the system detects the tap again, it goes back to initial screen
00260                         if(I2_flag )
00261                         {
00262                             Int_SourceSystem  = mma8452.readByteFromRegister(INT_SOURCE);
00263                             if ((Int_SourceSystem &0x08)==0x08)
00264                             {
00265                                 Int_SourceTrans  = mma8452.readByteFromRegister(TRANSIENT_SRC); 
00266                                 Int_SourceTrans  = mma8452.readByteFromRegister(PULSE_SRC);
00267                                 Int_SourceSystem  = 0;
00268                                 wait(0.2);
00269                                 I1_flag  = 0; 
00270                                 I2_flag  = 0;   
00271                                 timer1.attach(&TimerExpired1,20.0);
00272                                 timerFlag1  = 0;
00273                                 state  = 1;
00274                             }
00275                         }
00276                         // If the user does not perform any action in 20 seconds, turn off the device
00277                         else if(timerFlag1 )
00278                         {
00279                             timerFlag1  = 0;
00280                             Int_SourceTrans  = mma8452.readByteFromRegister(TRANSIENT_SRC);
00281                             Int_SourceTrans  = mma8452.readByteFromRegister(PULSE_SRC);
00282                             Int_SourceSystem  = 0;
00283                             wait(0.2);
00284                             I1_flag  = 0;  
00285                             I2_flag  = 0;  
00286                             state  = 0;   
00287                         }  
00288                         wait(1); 
00289                         lcd.clear();
00290                     break;
00291                 }
00292                
00293                default:
00294                     //invalid state - call error routine
00295                     error();
00296                 break;                   
00297         }
00298     }        
00299 }
00300 
00301 void Interrupt()
00302 {
00303     /// Controls the Transient Detection Interrupt flag
00304     I1_flag  = 1;
00305 }
00306 
00307 void Interrupt2()
00308 {
00309     /// Controls the Pulse(Tap)Detection Interrupt flag
00310     I2_flag  = 1;
00311 }
00312 
00313 void error() 
00314 {
00315     /// Error function. In case of error of the state machine
00316     while(1) 
00317     { 
00318         lcd.clear();
00319         lcd.printString("FSM Error!",0,0);
00320     } 
00321 }
00322 
00323 void TimerExpired1()
00324 {
00325     /// Timer 1 flag
00326     timerFlag1  = 1;
00327 }
00328 
00329 void TimerExpired2()
00330 {
00331     /// Timer 2 Flag
00332     timerFlag2  = 1;
00333 }
00334 
00335 void TimerExpired3()
00336 {
00337     /// Calculates the chronometer time
00338     second  = second  + 1;
00339     if (second  > 60)
00340     {
00341         second  = 0;
00342         minute  = minute  + 1;
00343         if (minute  > 60)
00344         {
00345             hour  = hour  + 1;
00346             minute  = 0;
00347         }
00348    
00349     }    
00350 }
00351 
00352 void writeDataToFile(char *date,int data1,float data2)
00353 {
00354     /// Saves the km and steps data to flash disk
00355     FILE *fp = fopen("/local/log.txt", "a");
00356     // Create the txt file
00357     fprintf(fp,"Date: %s\n",date);
00358     fprintf(fp,"Steps = %6u\n",data1);
00359     fprintf(fp,"Km = %6.3f\n \n",data2);
00360     fclose(fp);
00361 }