Part2

Dependencies:   MMA8451Q SLCD mbed

Fork of ACC_LCD_341_MID by Stanley Cohen

Revision:
3:bc69bca92c05
Parent:
2:6003ed409def
--- a/acc_341.cpp	Thu Sep 25 23:45:35 2014 +0000
+++ b/acc_341.cpp	Mon Oct 06 07:54:05 2014 +0000
@@ -1,19 +1,18 @@
+/* 
+ Test of the accelerometer, digital I/O, on-board LCD screen.
+ RED: Until absolute vertical is reached
+ GREEN: Until absolute horizontal is reached
+ 
+ Author: Siphamandla P. Simelane
+ Date: 10/6/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 +25,117 @@
 
 #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.1
+#define BLINKTIME 0.2// 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;
+    
+//    return (sqrt(arg));
 }
-   
 
+// 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;
+        
+    #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);
-#endif
-
-        sprintf (lcdData,"%4.3f",vector);
-        LCDMess(lcdData, DATATIME);
-// Wait then do the whole thing again.
-        wait(DATATIME);
+  // 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", vector);
+                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 {
+                    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