Edson Manoel da Silva / Mbed 2 deprecated Pedometer

Dependencies:   MMA8452 N5110 PowerControl mbed

Revision:
0:28fa9993bcf9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon May 11 03:38:15 2015 +0000
@@ -0,0 +1,361 @@
+/**
+@file main.cpp
+ 
+@brief Pedometer implementation using the sensor Triple Axis Accelerometer Breakout - MMA8452Q
+ 
+*/
+
+#include "main.h"
+
+int main()
+{
+    /// Finite State Machine that cotrols the whole system
+    //Setting the initial state. Avoiding rubish values
+    state = 0;
+    I1_flag = 0;
+    I2_flag = 0;
+    
+    // Adressing the rise of pin 15(which is connected to I1 of Sensor)to the interruption routine 1
+    I1.rise(&Interrupt);
+    
+    // Adressing the rise of pin 16(which is connected to I2 of Sensor)to the interruption routine 2
+    I2.rise(&Interrupt2);  
+
+    while(1)
+    {    
+        // Main state machine 
+        switch (state)
+        {
+            // Keep the device sleeping if no interruption is generated
+            case 0:
+            {
+                    wait(0.7); 
+                    // If an interruption is generated, check where it came from
+                    if(I1_flag)
+                    {
+                        // Reading the cause of the interruption
+                        Int_SourceSystem = mma8452.readByteFromRegister(INT_SOURCE);
+                        // Checking if the Transient detection is the cause of the interruption generated
+                        if ((Int_SourceSystem&0x20)==0x20) 
+                        {
+                            // Clearing the interrupt system for Transient Detection
+                            Int_SourceTrans = mma8452.readByteFromRegister(TRANSIENT_SRC); 
+                            // Clearing the interrupt system for Pulse Detection
+                            Int_SourceTrans = mma8452.readByteFromRegister(PULSE_SRC); 
+                            Int_SourceSystem = 0;
+                            // Wait 200ms to make sure the intrrupt system is cleaned
+                            wait(0.2); 
+                            I1_flag = 0; 
+                            I2_flag = 0; 
+                            lcd.init();
+                            // Choose the normal colour mode
+                            lcd.normalMode();
+                            // Set the LED backlight to 10%  
+                            lcd.setBrightness(0.1);
+                            // Clear the screen
+                            lcd.clear();
+                            // Starts the execution timer for next Menu
+                            timer1.attach(&TimerExpired1,20.0);
+                            timerFlag1 = 0;
+                            // Going to the initial screen
+                            state = 1;
+                       
+                        }
+                    }
+                    // If no interruption is generated, it keeps mbed sleeping and display turned off
+                    else
+                    {
+                        lcd.turnOff();
+                        // Standard initialisation used here due to different initialisations settings used through the code
+                        // Sets the scale to 4g, 100Hz of ODR and set the Transient and Pulse Detection
+                        mma8452.init();
+                        timer1.detach();
+                        timer2.detach();
+                        timerFlag1 = 0;
+                        timerFlag2 = 0;
+                        Sleep();
+                    }       
+                break;
+            }
+            // Wait for an user command befor the timer counting ends
+            case 1:
+            {
+                    lcd.printString("Welcome!",0,0);
+                    lcd.printString("Tap for graph",0,2);
+                    lcd.printString("Or",0,3);
+                    lcd.printString("Shake for",0,4);
+                    lcd.printString("Counting steps",0,5); 
+                    wait(1); 
+
+                    // Checking if an Transient Detection interrupt is generated (Countinuos shake)
+                    if(I1_flag)
+                    {
+                        // Reading the cause of the interruption
+                        Int_SourceSystem = mma8452.readByteFromRegister(INT_SOURCE);
+                        // If the Transient detection is the cause of the interrupt generated
+                        if ((Int_SourceSystem&0x20)==0x20)
+                        {
+                            // Goes to step counting screen
+                            state = 2;
+                        }
+                    }
+
+                    // Checking if an Pulse Detection interrupt is generated (Just a tap to left or right)                    
+                    else if((I2_flag)&&(!I1_flag))
+                    {
+                        // Reading the cause of the interrupt
+                        Int_SourceSystem = mma8452.readByteFromRegister(INT_SOURCE);
+                        // If the Pulse detection is the cause of the interrupt generated
+                        if ((Int_SourceSystem&0x08)==0x08) 
+                        {
+                            // Clearing the Transient interrupt system
+                            Int_SourceTrans = mma8452.readByteFromRegister(TRANSIENT_SRC);
+                            // Clearing the Transient interrupt system
+                            Int_SourceTrans = mma8452.readByteFromRegister(PULSE_SRC);
+                            Int_SourceSystem = 0;
+                            // Wait 200ms to make sure the intrrupt system is cleaned
+                            wait(0.2);
+                            I1_flag = 0; 
+                            I2_flag = 0;   
+                            timer1.attach(&TimerExpired1,20.0);
+                            timerFlag1 = 0;
+                            lcd.clear();
+                            // Going to the Km/day graph screen
+                            state = 3;
+                        }
+                    }
+                    // If no interrupt is generated and the timer finishes the counting, turn off the device again
+                    else if(timerFlag1)
+                    {
+                        timerFlag1 = 0;
+                        Int_SourceTrans = mma8452.readByteFromRegister(TRANSIENT_SRC); 
+                        Int_SourceTrans = mma8452.readByteFromRegister(PULSE_SRC); 
+                        Int_SourceSystem = 0;
+                        wait(0.2);
+                        I1_flag = 0;  
+                        I2_flag = 0;  
+                        state = 0;   
+                    }   
+                break;
+            }
+            // Steps counting Screen. Also save data.
+            case 2:
+            {
+                    // Changes the scale to 2g, the ODR to 800Hz and set the output data to be read from the High Pass Filter
+                    mma8452.transient_counting();                                                
+                    lcd.clear();
+                    buzzer = 0.5;
+                    lcd.printString("Calibrating...",0,0);
+                    wait(5);
+                    // Take a average of the 50 values of the device before counting steps. Kind of calibration
+                    acc_avg = mma8452.average();  
+                    buzzer = 0;
+                    step = 0; 
+                    km = 0;
+                    leds = 0x04; 
+                    aux = 0; 
+                    timerFlag2 = 0;
+                    timer3.attach(&TimerExpired3,1);
+                    // While the timer does not end, keep counting
+                    while(!timerFlag2)
+                    {    
+                        acceleration = mma8452.readValues();   // read current values 
+                        sub_x = acceleration.x - acc_avg.x;
+                        sub_y = acceleration.y - acc_avg.y;
+                        sub_z = acceleration.z - acc_avg.z;
+                        acc_vector = (pow(sub_x,2.0)+pow(sub_y,2.0)+pow(sub_z,2.0)); 
+                        acc_vector = sqrt(acc_vector);
+                        // If the acceleration vector is greater than 0.15, add the steps
+                        if(acc_vector > 0.15)
+                        {
+                             step = step + 2;
+                             // Runing
+                             if (acc_vector > 1.0)
+                                km = km + 0.002;
+                             // Walking
+                             else
+                                km = km + 0.001;     
+                        }
+
+                        lcd.clear(); 
+                              
+                        length = sprintf(buffer,"%6u steps",step); 
+                        if (length <= 14)                 
+                            lcd.printString(buffer,0,0);  
+                        
+                        length = sprintf(buffer,"%6.3f km",km); 
+                        if (length <= 14)                 
+                            lcd.printString(buffer,0,1); 
+                        
+                        length = sprintf(buffer,"%2u:%2u:%2u",hour, minute, second); 
+                        if (length <= 14)                 
+                            lcd.printString(buffer,0,2);                             
+                              
+                        // get current date    
+                        time_t seconds = time(NULL);  
+                        // Convert date to a string
+                        strftime(buffer, 14 , "%a-%d/%m/%Y", localtime(&seconds));
+                        lcd.printString(buffer,0,3);
+                        
+                        // Avoiding counting the same steps twice                                       
+                        wait(0.65);
+                        
+                        // If one stops the activity, starts the timer
+                        if ((acc_vector <0.15)&& (aux==0))
+                        {
+                            timer2.attach(&TimerExpired2,20.0);
+                            aux = 1;
+                        }
+                        // If one walks again, reset the timer
+                        else if ((acc_vector >0.15)&&(aux == 1))
+                        {
+                            timer2.detach();
+                            aux = 0;
+                        }
+
+                    }   
+                    buzzer = 0.5;
+                    wait(3);
+                    buzzer = 0;
+                    Int_SourceTrans = mma8452.readByteFromRegister(TRANSIENT_SRC); 
+                    Int_SourceTrans = mma8452.readByteFromRegister(PULSE_SRC);
+                    Int_SourceSystem = 0;
+                    wait(0.2);
+                    timer3.detach();
+                    second = 0;
+                    minute = 0;
+                    hour = 0;
+                    I1_flag = 0;
+                    timerFlag2 = 0;
+                    // Saving data to local system File
+                    writeDataToFile(buffer,step,km);
+                    // Accumulating the steps per day value
+                    time_t seconds = time(NULL);
+                    strftime(buffer, 3 , "%u", localtime(&seconds));
+                    int value = atoi(buffer);   
+                    km_day[value]=km_day[value]+km;
+                    state = 0;
+                    break;
+               }
+               // Graph Km/day Screen 
+               case 3:
+               {
+                        lcd.printString("Km/day",10,0);
+                        lcd.printString("8",10,1);
+                        lcd.printString("6",10,2);
+                        lcd.printString("4",10,3);
+                        lcd.printString("2",10,4);
+                        lcd.printString("0",10,5);
+                        lcd.drawRect(17,7,60,40,0);
+                        // Logic to print the graph with all days
+                        for (int x = 1; x < 30; x++) 
+                        {
+                            float n_pix = 8.0/36.0;
+                            int last_point = ((8.0-km_day[x-1])/(n_pix));
+                            int point = ((8.0-km_day[x])/(n_pix));
+                            lcd.drawLine((x-1)+18,last_point+9,x+18,point+9,1);
+                        }
+                        lcd.refresh();
+                        // If the system detects the tap again, it goes back to initial screen
+                        if(I2_flag)
+                        {
+                            Int_SourceSystem = mma8452.readByteFromRegister(INT_SOURCE);
+                            if ((Int_SourceSystem&0x08)==0x08)
+                            {
+                                Int_SourceTrans = mma8452.readByteFromRegister(TRANSIENT_SRC); 
+                                Int_SourceTrans = mma8452.readByteFromRegister(PULSE_SRC);
+                                Int_SourceSystem = 0;
+                                wait(0.2);
+                                I1_flag = 0; 
+                                I2_flag = 0;   
+                                timer1.attach(&TimerExpired1,20.0);
+                                timerFlag1 = 0;
+                                state = 1;
+                            }
+                        }
+                        // If the user does not perform any action in 20 seconds, turn off the device
+                        else if(timerFlag1)
+                        {
+                            timerFlag1 = 0;
+                            Int_SourceTrans = mma8452.readByteFromRegister(TRANSIENT_SRC);
+                            Int_SourceTrans = mma8452.readByteFromRegister(PULSE_SRC);
+                            Int_SourceSystem = 0;
+                            wait(0.2);
+                            I1_flag = 0;  
+                            I2_flag = 0;  
+                            state = 0;   
+                        }  
+                        wait(1); 
+                        lcd.clear();
+                    break;
+                }
+               
+               default:
+                    //invalid state - call error routine
+                    error();
+                break;                   
+        }
+    }        
+}
+
+void Interrupt()
+{
+    /// Controls the Transient Detection Interrupt flag
+    I1_flag = 1;
+}
+
+void Interrupt2()
+{
+    /// Controls the Pulse(Tap)Detection Interrupt flag
+    I2_flag = 1;
+}
+
+void error() 
+{
+    /// Error function. In case of error of the state machine
+    while(1) 
+    { 
+        lcd.clear();
+        lcd.printString("FSM Error!",0,0);
+    } 
+}
+
+void TimerExpired1()
+{
+    /// Timer 1 flag
+    timerFlag1 = 1;
+}
+
+void TimerExpired2()
+{
+    /// Timer 2 Flag
+    timerFlag2 = 1;
+}
+
+void TimerExpired3()
+{
+    /// Calculates the chronometer time
+    second = second + 1;
+    if (second > 60)
+    {
+        second = 0;
+        minute = minute + 1;
+        if (minute > 60)
+        {
+            hour = hour + 1;
+            minute = 0;
+        }
+   
+    }    
+}
+
+void writeDataToFile(char *date,int data1,float data2)
+{
+    /// Saves the km and steps data to flash disk
+    FILE *fp = fopen("/local/log.txt", "a");
+    // Create the txt file
+    fprintf(fp,"Date: %s\n",date);
+    fprintf(fp,"Steps = %6u\n",data1);
+    fprintf(fp,"Km = %6.3f\n \n",data2);
+    fclose(fp);
+}
\ No newline at end of file