Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MMA8452 N5110 PowerControl mbed
main.cpp
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 }
Generated on Sun Jul 24 2022 20:18:03 by
1.7.2