Mid_term1.0

Dependencies:   MMA8451Q SLCD mbed

Fork of ACC_LCD_341_MID1 by Siphamandla Simelane

acc_341.cpp

Committer:
sphasim
Date:
2014-10-06
Revision:
4:f17af9f983dc
Parent:
3:0e7f46de6d17

File content as of revision 4:f17af9f983dc:

/* 
 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"
#include "math.h"

// 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
#elif defined (TARGET_KL05Z)
  PinName const SDA = PTB4;
  PinName const SCL = PTB3;
#else
  #error TARGET NOT DEFINED
#endif

#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 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);
} 


int main() {
    float xAcc;
    float yAcc;
    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) {
    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
    }
}