Movement – acceleration

Accelerometers are sensors that detect the rate of change of movement (i.e. acceleration), and can come in single-axis, two-axis or three-axis variants. The MMA8451 3-axis accelerometer that we are using is a simple, affordable sensor that provides precise acceleration readings from +/- 2g to 8g.

Some of you might have come across more complex motion sensors known as IMUs or Inertial Measurement Units – those combine an accelerometer, gyroscope and magnetometer to provide orientation information. The bulk of the magic in these motion sensors is the math used to integrate and calculate orientation information by folding accelerometer/gyro/magnetic heading readings using complex algorithms, a process also known as ‘sensor fusion’. Those IMUs will cost a bit more, but you are highly encouraged to try them out on your own.

With just a 3-axis analogue accelerometer, we can measure bumps, swings, drops, any type of three-dimensional motion.

Code-wise we adopt the same approach with I2C-based sensors: use the SDA+SCL lines, power it with 3V3 and connect GND, and find the code library to interface with the sensor.

Details on sensor: https://learn.adafruit.com/adafruit-mma8451-accelerometer-breakout/pinouts


Libraries Used

(learn how to import them in the Build IDE):


Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_MMA8451.h>
#include <Adafruit_Sensor.h>

// how long between each log update? feel free to change this value,
// but this must not be anything less than 1000 milliseconds!
#define INTERVAL_BETWEEN_LOGS 5000

// initialise the MMA8451 sensor
Adafruit_MMA8451 mma = Adafruit_MMA8451();

// code in this setup function runs just once, when Photon is powered up or reset
void setup() {
    Serial.begin(9600);         // Open a connection via the Serial port – useful for debugging

    if (! mma.begin()) {
        Serial.println("Couldn't start");
        while (1);
    }
    Serial.println("MMA8451 found!");

    mma.setRange(MMA8451_RANGE_2_G);

    Serial.print("Range = ");
    Serial.print(2 << mma.getRange());  
    Serial.println("G");

    delay(5000);                // Common practice to allow board to 'settle' after connecting online
}

// code in this loop function runs forever, until you cut power!
// for the A/D blackbox, there is nothing much in here except to update the Blynk App & the update timer
void loop() {

}

// doDataUpdate runs every interval set in INTERVAL_BETWEEN_LOGS – this is
// useful to send data streams to services like IFTTT to log data on Google
// spreadsheets, for example
void doDataUpdate() {
    // To keep their server load optimal, the Particle cloud can only accept
    // update rates of once per second with the option to 'burst' 4 updates in a
    // second (but then you'll get blocked for the next 4 seconds). 'Ration' your
    // INTERVAL_BETWEEN_LOGS and the number of readings you are publishing; in our
    // default example we are using just 1 publish but concatenating all the data
    // we want into a single publish statement

    // first we save what we want to read into temporary variables first.
    // feel free to add/remove these lines as you see fit in your application:

    // Read the 'raw' data in 14-bit counts
    mma.read();

    sensors_event_t event;
    mma.getEvent(&event);

    /* Get the orientation of the sensor */
    uint8_t o = mma.getOrientation();

    String ori = "";
    switch (o) {
        case MMA8451_PL_PUF:
            ori = "Portrait Up Front";
            break;
        case MMA8451_PL_PUB:
            ori = "Portrait Up Back";
            break;    
        case MMA8451_PL_PDF:
            ori = "Portrait Down Front";
            break;
        case MMA8451_PL_PDB:
            ori = "Portrait Down Back";
            break;
        case MMA8451_PL_LRF:
            ori = "Landscape Right Front";
            break;
        case MMA8451_PL_LRB:
            ori = "Landscape Right Back";
            break;
        case MMA8451_PL_LLF:
            ori = "Landscape Left Front";
            break;
        case MMA8451_PL_LLB:
            ori = "Landscape Left Back";
            break;
    }
    Serial.println(ori);

    /* Display the results (acceleration is measured in m/s^2) */
    String res = "X:" + String(event.acceleration.x) + ",Y:" + String(event.acceleration.y) + ",Z:" + String(event.acceleration.z) + ",O:" + String(ori);

    Serial.println(res);
    Particle.publish("sensorData", res);
}