8.1 MT solution for accelerometer program with hysteresis

Dependencies:   MMA8451Q SLCD mbed

Fork of ACC_LCD_341_MID by Stanley Cohen

acc_341.cpp

Committer:
scohennm
Date:
2014-10-06
Revision:
3:b425cdf7c99c
Parent:
2:6003ed409def

File content as of revision 3:b425cdf7c99c:

#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
 */
// solution UG 1
#define NUMLEDS 2
#define PORTRAIT 0
#define PORTRAIT1 1 // Add bandwidth
#define LANDSCAPE 10
#define LANDSCAPE1 9
#define LEDON 0
#define LEDOFF 1
#define RED 0
#define GREEN 1
#define ACCSCALING 10.0
#define HYSTOFFSET 4
DigitalOut LEDs[NUMLEDS]={LED_RED, LED_GREEN}; // plan for scalability
// end UG 1
#define DATATIME 0.200

#define PROGNAME "ACCLCD341\r/n"

// #define PRINTDBUG
// 
#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)

SLCD slcd; //define LCD display

MMA8451Q acc(SDA, SCL, MMA8451_I2C_ADDRESS);
Serial pc(USBTX, USBRX);

float sqrt_newt(float argument) {
    int i = 0;
    float xnew = 0.0;
    int itermax = 20;
    float epsilon = 1e-7;
    float xold = argument/2.0;
    float delta = 1;
    while ((delta > epsilon) && (i < itermax)){
        xnew = 0.5*(xold + (argument/xold));
        delta = abs(xnew-xold);      
        xold = xnew;
        i++;
#ifdef PRINTDBUG
        // wait(0.1);
        pc.printf("%5.4f %5.4e\r\n",xold, delta);
#endif       
    } // end while
    return (xold);
    
}
   

void LCDMess(char *lMess, float dWait){
        slcd.Home();
        slcd.clear();
        slcd.printf(lMess);
        wait(dWait);
} 


int main() {
    int i;
    float xAcc;
    float yAcc;
    float zAcc;
    float vector;  
    int positionState;
    char lcdData[10]; //buffer needs places dor decimal pt and colon
    Timer DATATimer; 
    int hyst = HYSTOFFSET;
    
    
    
#ifdef PRINTDBUG
        pc.printf(PROGNAME);
#endif
    DATATimer.start();
    DATATimer.reset();
// main loop forever 
    while(true) {
        while (DATATimer.read_ms() >  DATATIME) {
        
//Get accelerometer data - tilt angles minus offset for zero mark.
            xAcc = abs(acc.getAccX());
            yAcc = abs(acc.getAccY()); 
            zAcc = abs(acc.getAccZ());       
 // Calulate vector sum of x and y reading.       
            vector = sqrt_newt(pow(xAcc,2) + pow(yAcc,2));
            // Calculate the state based on orientaion
            positionState = int(ACCSCALING * xAcc) + hyst; // Create a Deadband
            if (positionState >= LANDSCAPE){
                positionState = LANDSCAPE;
            } else {
                positionState = PORTRAIT;
            }
                
// State Machine
            switch (positionState){
                case LANDSCAPE:
                case LANDSCAPE1: {
                    LEDs[RED].write(LEDON);
                    LEDs[GREEN].write (LEDOFF);
                    hyst = HYSTOFFSET;
                    break;
                }
                case  PORTRAIT:
                case  PORTRAIT1: {
                    LEDs[RED].write(LEDOFF);
                    LEDs[GREEN].write (LEDON);
                    hyst= 0;
                    break;
                }
                default: {
                    for (i = 0; i< NUMLEDS; i++){
                        LEDs[i].write(LEDON);
                    }
                    break;
                }
            }  //switch
        
#ifdef PRINTDBUG
        pc.printf("xAcc = %f\r\n", xAcc);
        pc.printf("yAcc = %f\r\n", yAcc);
        pc.printf("xAcc = %f\r\n", zAcc);
        pc.printf("vector = %f\r\n",  vector);
#endif

            sprintf (lcdData,"%4.3f",vector);
            LCDMess(lcdData, vector);
            DATATimer.reset();
// Wait then do the whole thing again.
        } // end whle for timer
    }// end forever while
}