Mid_term1

Dependencies:   MMA8451Q SLCD mbed

Fork of ACC_LCD_341_MID by Stanley Cohen

Revision:
3:0e7f46de6d17
Parent:
2:6003ed409def
Child:
4:f17af9f983dc
--- a/acc_341.cpp	Thu Sep 25 23:45:35 2014 +0000
+++ b/acc_341.cpp	Mon Oct 06 07:16:01 2014 +0000
@@ -1,19 +1,31 @@
+/* 
+ Test of the accelerometer, digital I/O, on-board LCD screen.
+ RED: When absolute horizontal
+ GREEN : When absolute vertical
+ BLINKY: When in intermediate state
+ 
+ Author: Siphamandla Simelane
+ Date: 10/6/2014
+ */
+
+#include "mbed.h"
+#include "MMA8451Q.h"/* 
+ Test of the accelerometer, digital I/O, on-board LCD screen.
+ MISSION
+ LED RED: absolute horizontal
+ LED GREEN : absolute vertical
+ Should Blink: in intermediate state
+ 
+ Author: Siphamandla P. Simelane
+ Date: 10/7/2014
+ */
+
 #include "mbed.h"
 #include "MMA8451Q.h"
 #include "SLCD.h"
-
-/* 
-Test of the accelerometer, digital I/O, on-board LCD screen.
- Looing at vector product of the x-y components of the accelerometer.
- Works pretty well. Still rough, program wise - sc 140710
- */
+#include "math.h"
 
-#define DATATIME 0.200
-
-#define PROGNAME "ACCLCD341\r/n"
-
-#define PRINTDBUG
-// 
+// Configuring Accelerometer/Magnetometer: 
 #if   defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
   PinName const SDA = PTE25;  // Data pins for the accelerometer/magnetometer.
   PinName const SCL = PTE24;  // DO NOT CHANGE
@@ -26,52 +38,277 @@
 
 #define MMA8451_I2C_ADDRESS (0x1d<<1)
 
+#define PI 3.14159265
+#define DATATIME 0.150
+#define PROGNAME "ACCLCD341VB\r/n"
+#define PRINTDBUG
+#define LEDON false
+#define LEDOFF true
+#define LCDLEN 10
+#define LOW_POINT 0.0
+#define LOW_LIMIT 0.1
+#define HIGH_LIMIT 1.05
+#define BLINKTIME 0.5// milliseconds
+
+
+enum orientStates {INTERMEDIATE, LANDSCAPE, PORTRAIT}; // define the states
+PwmOut greenLed(LED_GREEN);
+PwmOut redLed(LED_RED);
 SLCD slcd; //define LCD display
 
 MMA8451Q acc(SDA, SCL, MMA8451_I2C_ADDRESS);
 Serial pc(USBTX, USBRX);
 
-float sqrt_newt(float argument) {
-    return (sqrt(argument));
+float sqrt_newt(float arg) {
+    int i = 0;
+    float X1 = 0.0;
+    int intMax = 30;
+    int epsilon = 1e-7;
+    float my_x = float(arg/2.0);
+    int delta = 1;
+    for(i=0; i<intMax; i++){
+        X1 = 0.5*(my_x + (arg/my_x));
+        delta = abs(X1-my_x);
+        if (delta < epsilon)
+            break;
+        else
+            my_x = X1;
+    }
+    return my_x;
+    
 }
-   
 
+// Print using LCD screen
 void LCDMess(char *lMess, float dWait){
-        slcd.Home();
-        slcd.clear();
-        slcd.printf(lMess);
-        wait(dWait);
+    slcd.Home();
+    slcd.clear();
+    slcd.printf(lMess);
+    wait(dWait);
 } 
 
 
 int main() {
     float xAcc;
     float yAcc;
-    float vector;  
-    char lcdData[10]; //buffer needs places dor decimal pt and colon
-    
-#ifdef PRINTDBUG
+    float vector;
+    float angle;  
+    char lcdData[LCDLEN]; //buffer needs places dor decimal pt and colon
+    orientStates PGMState = INTERMEDIATE;    
+    Timer LEDTimer;  // time till next PWM values is to change.
+    int ledState = LEDON;  
+    int timeToChangeDF = BLINKTIME;
+    // set up timer for next step of Duty Factor timing
+    LEDTimer.start();
+    LEDTimer.reset();
+
+    #ifdef PRINTDBUG
         pc.printf(PROGNAME);
-#endif
-// main loop forever 
-    while(true) {
+    #endif
 
-//Get accelerometer data - tilt angles minus offset for zero mark.
-        xAcc = abs(acc.getAccX());
-        yAcc = abs(acc.getAccY());     
- // Calulate vector sum of x and y reading.       
-        vector = sqrt_newt(pow(xAcc,2) + pow(yAcc,2));
-        
- 
-#ifdef PRINTDBUG
-        pc.printf("xAcc = %f\r\n", xAcc);
-        pc.printf("yAcc = %f\r\n", yAcc);
-        pc.printf("vector = %f\r\n",  vector);
+  // main loop forever 
+  while(true) {
+    switch (PGMState){ 
+            case INTERMEDIATE: 
+                //Get accelerometer data - tilt angles minus offset for zero mark.
+                xAcc = abs(acc.getAccX());
+                yAcc = abs(acc.getAccY()); 
+                
+                // Calulate vector sum and angle of x and y reading.       
+                vector = sqrt_newt(pow(xAcc,2) + pow(yAcc,2));
+                angle = atan(yAcc / xAcc)* 180 / PI;
+                
+                
+                #ifdef PRINTDBUG
+                   pc.printf("xAcc = %f\r\n", xAcc);
+                   pc.printf("yAcc = %f\r\n", yAcc);
+                   pc.printf("vector = %f\r\n",  vector);
+                   pc.printf("Angle = %f\r\n",  angle);
+                #endif                 
+                sprintf (lcdData,"%4.3f", yAcc);
+                LCDMess(lcdData, DATATIME);
+                                
+                
+                // Define the landscape and portrait position using x and y readings
+                if(yAcc < LOW_LIMIT && xAcc > LOW_POINT && xAcc < HIGH_LIMIT){
+                    PGMState = PORTRAIT;
+                } else if (xAcc < LOW_LIMIT && yAcc > LOW_POINT && yAcc < HIGH_LIMIT){
+                    PGMState = LANDSCAPE;
+                } else {                     
+                     // Blink the LED if in this state
+                     ledState = ! ledState;
+                     if (LEDTimer.read_ms() > timeToChangeDF){ // check for timer time out transtion
+                        redLed.write(ledState);
+                        greenLed.write(ledState);
+                        LEDTimer.reset();
+                        PGMState = INTERMEDIATE;
+                     }                                          
+                } 
+                break;
+              
+             case PORTRAIT:   
+                // Green led ON and red OFF            
+                redLed.write(LEDON);
+                greenLed.write(LEDOFF);               
+                PGMState = INTERMEDIATE;  // go idle state
+                break;
+              
+             case LANDSCAPE:  
+                // Green led OFF and red ON
+                redLed.write(LEDOFF);
+                greenLed.write(LEDON);                                
+                PGMState = INTERMEDIATE;  // go idle state
+                break;
+                
+            default:
+                PGMState = INTERMEDIATE;  // go idle state
+                break;
+              
+        } // end state machine
+    }
+}
+#include "SLCD.h"
+#include "math.h"
+
+// Configure Accelerometer/Magnetometer: 
+#if   defined (TARGET_KL25Z) || defined (TARGET_KL46Z)
+  PinName const SDA = PTE25;  // Data pins for the accelerometer/magnetometer.
+  PinName const SCL = PTE24;  // DO NOT CHANGE
+#elif defined (TARGET_KL05Z)
+  PinName const SDA = PTB4;
+  PinName const SCL = PTB3;
+#else
+  #error TARGET NOT DEFINED
 #endif
 
-        sprintf (lcdData,"%4.3f",vector);
-        LCDMess(lcdData, DATATIME);
-// Wait then do the whole thing again.
-        wait(DATATIME);
+#define MMA8451_I2C_ADDRESS (0x1d<<1)
+
+#define PI 3.14159265
+#define DATATIME 0.150
+#define PROGNAME "ACCLCD341VB\r/n"
+#define PRINTDBUG
+#define LEDON false
+#define LEDOFF true
+#define LCDLEN 10
+#define LOW_POINT 0.0
+#define LOW_LIMIT 0.125
+#define HIGH_LIMIT 1.1
+#define ONTIME 1.0
+#define BLINKTIME 0.1// milliseconds
+
+
+enum orientStates {INTERMEDIATE, LANDSCAPE, PORTRAIT}; // define the states
+PwmOut greenLed(LED_GREEN);
+PwmOut redLed(LED_RED);
+SLCD slcd; //define LCD display
+
+MMA8451Q acc(SDA, SCL, MMA8451_I2C_ADDRESS);
+Serial pc(USBTX, USBRX);
+
+float sqrt_newt(float arg) {
+    int i = 0;
+    float X1 = 0.0;
+    int intMax = 20;
+    int epsilon = 1e-7;
+    float my_x = float(arg/2.0);
+    int delta = 1;
+    for(i=0; i<intMax; i++){
+        X1 = 0.5*(my_x + (arg/my_x));
+        delta = abs(X1-my_x);
+        if (delta < epsilon)
+            break;
+        else
+            my_x = X1;
+    }
+    return my_x;
+    
+//    return (sqrt(arg));
+}
+
+// Print using LCD screen
+void LCDMess(char *lMess, float dWait){
+    slcd.Home();
+    slcd.clear();
+    slcd.printf(lMess);
+    wait(dWait);
+} 
+
+
+int main() {
+    float xAcc;
+    float yAcc;
+    float vector;
+    float angle;  
+    char lcdData[LCDLEN]; //buffer needs places dor decimal pt and colon
+    orientStates PGMState = INTERMEDIATE;    
+    Timer LEDTimer;  // time till next PWM values is to change.
+    int ledState = LEDON;  
+    int timeToChangeDF = BLINKTIME;
+    // set up timer for next step of Duty Factor timing
+    LEDTimer.start();
+    LEDTimer.reset();
+
+    #ifdef PRINTDBUG
+        pc.printf(PROGNAME);
+    #endif
+
+  // main loop forever 
+  while(true) {
+    switch (PGMState){ 
+            case INTERMEDIATE: 
+                //Get accelerometer data - tilt angles minus offset for zero mark.
+                xAcc = abs(acc.getAccX());
+                yAcc = abs(acc.getAccY()); 
+                
+                // Calulate vector sum and angle of x and y reading.       
+                vector = sqrt_newt(pow(xAcc,2) + pow(yAcc,2));
+                angle = atan(yAcc / xAcc)* 180 / PI;
+                
+                
+                #ifdef PRINTDBUG
+                   pc.printf("xAcc = %f\r\n", xAcc);
+                   pc.printf("yAcc = %f\r\n", yAcc);
+                   pc.printf("vector = %f\r\n",  vector);
+                   pc.printf("Angle = %f\r\n",  angle);
+                #endif                 
+                sprintf (lcdData,"%4.3f", yAcc);
+                LCDMess(lcdData, DATATIME);
+                                
+                
+                // Define the landscape and portrait position using x and y readings
+                if(yAcc < LOW_LIMIT && xAcc > LOW_POINT && xAcc < HIGH_LIMIT){
+                    PGMState = PORTRAIT;
+                } else if (xAcc < LOW_LIMIT && yAcc > LOW_POINT && yAcc < HIGH_LIMIT){
+                    PGMState = LANDSCAPE;
+                } else {                     
+                     // Blink the LED if in this state
+                     ledState = ! ledState;
+                     if (LEDTimer.read_ms() > timeToChangeDF){ // check for timer time out transtion
+                        redLed.write(ledState);
+                        greenLed.write(ledState);
+                        LEDTimer.reset();
+                        PGMState = INTERMEDIATE;
+                     }                                          
+                } 
+                break;
+              
+             case PORTRAIT:   
+                // Green led ON and red OFF            
+                redLed.write(LEDON);
+                greenLed.write(LEDOFF);               
+                PGMState = INTERMEDIATE;  // go idle state
+                break;
+              
+             case LANDSCAPE:  
+                // Green led OFF and red ON
+                redLed.write(LEDOFF);
+                greenLed.write(LEDON);                                
+                PGMState = INTERMEDIATE;  // go idle state
+                break;
+                
+            default:
+                PGMState = INTERMEDIATE;  // go idle state
+                break;
+              
+        } // end state machine
     }
 }
\ No newline at end of file