Hello Koepel,
Thanks for the reply and thanks for sticking with this, but unfortunately your code did not work. I say this because gravity is still coupled with my measurements. When I plot X, Y & Z, Z still reads 1g.
The reason that I thought that the bytes would automatically write to the next register is because of this from the data sheet...
Multiple Byte Write
The MMA8452Q automatically increments the received register address commands after a write command is received.
Therefore, after following the steps of a single byte write, multiple bytes of data can be written to sequential registers after each MMA8452Q acknowledgment (ACK) is received.
I can post all my code, but it is pretty ugly as it is a "working sketch" at best. (I had to trim a bunch to post, too large)
I will look at safety mode again.
I have the Sparkfun library but did not find anything that worked or was helpful, am I missing something obvious?
/******************************************************************************
#include <Wire.h> // Must include Wire library for I2C
#include <SparkFun_MMA8452Q.h> // Includes the SFE_MMA8452Q library
// Begin using the library by creating an instance of the MMA8452Q
// class. We'll call it "accel". That's what we'll reference from
// here on out.
MMA8452Q accel;
// The setup function simply starts serial and initializes the accelerometer.
const byte LED = 13;
const byte Brake = 11; // LED that "Brake" function triggers.
static float smoothedValue = 0.0;
const float alpha = 0.99; // Smoothing variable, 0 = No smoothing, 1 = maximum smooting.
float Past = 0 ;
// Variables will change:
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 125; // interval at which to blink (milliseconds)
//char tmpstring[10];
const float Deg2Rad = 0.01745329251994329576923690768489;
int toprint = 0;
//float TrueAccX = 0;
const float Lim = 1.00;
const float Lim2 = 0.1;
void setup()
{
Serial.begin(9600);
Wire.begin(); // Join i2c bus (address optional for master)
Wire.beginTransmission(0x1D); // address of MMA8452Q
Wire.write(0x1D); // TRANSIENT_CFG
Wire.write(0b00010000); // Sends 00010000
Wire.endTransmission();
Wire.beginTransmission(0x1D); // address of MMA8452Q
Wire.write(0x1F); // TRANSIENT_THS
Wire.write(0b00001110); // Sends 00001110
Wire.endTransmission();
Wire.beginTransmission(0x1D); // address of MMA8452Q
Wire.write(0x20); // TRANSIENT_COUNT
Wire.write(0b00001010); // Sends 00001010
Wire.endTransmission();
// Wire.beginTransmission((byte)0x1D); // Begins transmission to 0x38 address of MMA8452Q
//
// // Wire.write((byte)14); // Sends 00000000 (0x0E) to MMA8452Q 0x0D register (0x0D = TRANSIENT_CFG register)
// Wire.write((byte)0x0E); // Sends 00000000 (14) to MMA8452Q 0x0D register (0x0D = TRANSIENT_CFG register)
// // Wire.write(0); // Sends 00000000 (0x00) to MMA8452Q 0x1E register (0x1E = TRANSIENT_SRC register)
// // Wire.write((byte)0); // Sends 00000000 (0x00) to MMA8452Q 0x1F register (0x1F = TRANSIENT_THS register)
// Wire.write((byte)0x00); // Sends 00000000 (0x00) to MMA8452Q 0x1F register (0x1F = TRANSIENT_THS register)
// // Wire.write((byte)10); // Sends 00001010 (0x0A) to MMA8452Q 0x20 register (0x20 = TRANSIENT_COUNT register)
// Wire.write((byte)0x20); // Sends 00001010 (0x0A) to MMA8452Q 0x20 register (0x20 = TRANSIENT_COUNT register)
//
// Wire.endTransmission();
Serial.println("Brake_021320");
pinMode(LED, OUTPUT);
pinMode(Brake, OUTPUT);
// Choose your adventure! There are a few options when it comes
// to initializing the MMA8452Q:
// 1. Default init. This will set the accelerometer up
// with a full-scale range of +/-2g, and an output data rate
// of 800 Hz (fastest).
accel.init();
// 2. Initialize with FULL-SCALE setting. You can set the scale
// using either SCALE_2G, SCALE_4G, or SCALE_8G as the value.
// That'll set the scale to +/-2g, 4g, or 8g respectively.
//accel.init(SCALE_4G); // Uncomment this out if you'd like
// 3. Initialize with FULL-SCALE and DATA RATE setting. If you
// want control over how fast your accelerometer produces
// data use one of the following options in the second param:
// ODR_800, ODR_400, ODR_200, ODR_100, ODR_50, ODR_12,
// ODR_6, or ODR_1.
// Sets to 800, 400, 200, 100, 50, 12.5, 6.25, or 1.56 Hz.
//accel.init(SCALE_8G, ODR_6);
// accel.init(SCALE_2G, ODR_12);
}
// The loop function will simply check for new data from the
// accelerometer and print it out if it's available.
void loop()
{
// Use the accel.available() function to wait for new data
// from the accelerometer.
if (accel.available()) // If new data is available...
{
// First, use accel.read() to read the (3) new variables:
accel.read();
// accel.read() will update two sets of variables.
// * int's x, y, and z will store the signed 12-bit values
// read out of the accelerometer.
// * floats cx, cy, and cz will store the calculated
// acceleration from those 12-bit values. These variables
// are in units of g's.
// Check the two function declarations below for an example
// of how to use these variables.
printCalculatedAccels();
// printAccels(); // Uncomment to print digital readings
// The library also supports the portrait/landscape detection
// of the MMA8452Q. Check out this function declaration for
// an example of how to use that.
// printOrientation();
// PrintData(); // Formatted to print data to Serial Monitor with data lables.
// PlotData(); // Formatted to print data to Serial Plotter withou data lables.
int xAcceleration = accel.x; // Read in raw x-axis acceleration data
toprint = map(xAcceleration, 0, 1000, 0, 90);
// sprintf(tmpstring, "%2d", toprint);
// Serial.print("Angle measurement is ");
// Serial.print(toprint); Serial.print("°");
// Serial.print("angle: ");
// Serial.println(tmpstring);
Serial.println(); // Print new line every time. This is needed to plot to the Serial Plotter correctly.
static float smoothedValue = 0.0; // re-zeros smoothedValue??? Variable has to be declared "static float" here in code for calculations to work.
// smoothedValue = 0.0;
// float newReading = (accel.cx);
// smoothedValue = (alpha * smoothedValue) + ((1 - alpha) * newReading);
smoothedValue = (alpha * smoothedValue) + ((1 - alpha) * accel.cx);
// Serial.print(newReading); Serial.print(", ");
// Serial.print(accel.cx); Serial.print(", ");
// Serial.print(smoothedValue); Serial.println("\t ");
// Current = accel.cx;
// if (smoothedValue > 0.015)
// if ((Past - Current) > 0.015)
// Serial.print(Past - smoothedValue);
// if (Past - smoothedValue < 0)
// TrueAccX = (smoothedValue - (cos((90 - toprint) * Deg2Rad)));
// if ((smoothedValue - (sin(toprint * Deg2Rad))) < 0)
// if ((TrueAccX > 0.25) || (TrueAccX < -0.25))
// if (TrueAccX < -0.1)
if (smoothedValue < -0.1)
{
analogWrite(Brake, 255);
digitalWrite(LED, LOW);
// Serial.println("---Decelerating---");
}
else
{
analogWrite(Brake, 0);
digitalWrite(LED, HIGH);
// Serial.println("Acclerating");
}
// Past = smoothedValue;
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval)
{
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(LED, ledState);
}
}
}
}