Luis Bañuelos Chacon / Mbed 2 deprecated cow_beacon_adxl345

Dependencies:   MMA8452_tag_private BLE_API mbed nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "BLEDevice.h"
00003 #include "MMA8452.h"
00004 
00005 // Configuration
00006 #define BLE_ADV_INTERVAL    500         // Interval between each advertising packet (in MS)
00007 #define ACC_RATE            10          // Accelerometer sampling rate (in Hz)
00008 #define ACC_BUFFER_SIZE     10          // Accelerometer history size
00009 
00010 // Algorithm
00011 #define ALG_PERIOD          1           // Algorithm period
00012 #define ALG_ACC_AXIS        0           // Which accelerometer axis to use
00013 #define ALG_UP_THRES        0.3         // Up State Threshold
00014 #define ALG_UP_TTCKS        10          // Up State Trigger Time
00015 #define ALG_DOWN_THRES      0.3         // Down State Threshold
00016 #define ALG_DOWN_TICKS      4           // Down State Trigger Time
00017 
00018 // Objects
00019 BLEDevice   ble;                        // BLE
00020 DigitalOut  led(P0_2);                  // LED (Active Low)
00021 InterruptIn btn(P0_3);                  // Button Interrupt (Active Low)
00022 MMA8452     acc(P0_22, P0_20, 100000);  // Accelerometer
00023 Ticker      acc_tick;                   // Ticker for the accelerometer
00024 Ticker      led_tick;                   // Ticker for led
00025 Ticker      alg_tick;                   // Ticker for algorithm
00026 
00027 // Data
00028 struct acc_ring {
00029     double data[3][ACC_BUFFER_SIZE];
00030     int head;
00031 } acc_ring;
00032 
00033 enum AlgState {
00034     UP,
00035     DOWN
00036 };
00037 
00038 // Prototypes
00039 void onError();
00040 void onAccTick();
00041 void onButton();
00042 void onLedTick();
00043 void ledBlink(int, float);
00044 void ledStop();
00045 double getAccLast(int);
00046 double getAccMean(int);
00047 void setPayload(uint8_t*, uint8_t);
00048 
00049 // Events
00050 void onError() {
00051     led = 1;
00052     wait(0.25);
00053     led = 0;
00054     wait(0.25);
00055 }
00056 
00057 void onAccTick() {
00058     // Increment head
00059     acc_ring.head++;
00060     if (acc_ring.head >= ACC_BUFFER_SIZE) acc_ring.head = 0;
00061     
00062     // Read accelerometer
00063     acc.readXGravity(&acc_ring.data[0][acc_ring.head]);
00064     acc.readYGravity(&acc_ring.data[1][acc_ring.head]);
00065     acc.readZGravity(&acc_ring.data[2][acc_ring.head]);
00066 }
00067 
00068 void onButton() {
00069     ledBlink(3, 1);
00070 }
00071 
00072 int led_blink;
00073 void onLedTick() {
00074     led = !led;         // Invert LED state
00075     
00076     if (led == 1)       // If led was turned off
00077         led_blink--;    // Decrement blink counter
00078         
00079     if (led_blink == 0)
00080         led_tick.detach();
00081 }
00082 
00083 void onAlgTick() {
00084     static AlgState state = UP;
00085     static AlgState last = DOWN;
00086     static int timer;
00087     
00088     double pos = getAccMean(ALG_ACC_AXIS);
00089     
00090     switch (state) {
00091         case UP:
00092             if (pos < ALG_DOWN_THRES) {
00093                 timer = 0;
00094             } else {
00095                 ledBlink(1, 1);
00096             }
00097             if (timer > ALG_DOWN_TICKS) {
00098                 state = DOWN;
00099             }
00100             break;
00101             
00102         case DOWN:
00103             if (pos > ALG_UP_THRES) {
00104                 timer = 0;
00105             } else {
00106                 ledBlink(1, 1);
00107             }
00108             if (timer > 10) {
00109                 state = UP;
00110             }
00111             break;
00112     }
00113     
00114     if (state != last) {
00115         last = state;
00116         setPayload((uint8_t*)&state, 1);
00117         ledBlink(2, 0.25);
00118     }
00119     
00120     timer++;
00121 }
00122 
00123 // Functions
00124 void setPayload(uint8_t * data, uint8_t size) {
00125     ble.clearScanResponse();
00126     ble.accumulateScanResponse(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data, size);
00127     ble.setAdvertisingPayload();
00128 }
00129 
00130 void ledBlink(int num, float period) {
00131     led = 0;
00132     led_blink = num;
00133     led_tick.attach(&onLedTick, period/2);
00134 }
00135 
00136 void ledStop() {
00137     led_blink = 0;
00138     led_tick.detach();
00139 }
00140 
00141 double getAccLast(int axis) {
00142     return acc_ring.data[axis][acc_ring.head];
00143 }
00144 
00145 double getAccMean(int axis) {
00146     double mean = 0;
00147     for (int i = 0; i < ACC_BUFFER_SIZE; i++) {
00148         mean += acc_ring.data[axis][i];
00149     }
00150     return (mean / (float)ACC_BUFFER_SIZE);
00151 }
00152 
00153 
00154 int main(void) {
00155     // Initialize LED and Button
00156     led = 1;
00157     btn.mode(PullUp);
00158     btn.fall(&onButton);
00159     
00160     // Initialize BLE
00161     uint8_t tagAddress[6];
00162     uint8_t tagName[8];
00163     ble.init();                                             // Initialize BLE stack
00164     ble.setTxPower(4);                                      // Set power level (in dB)
00165     ble.setAddress(Gap::ADDR_TYPE_RANDOM_STATIC, NULL);     // Static random address
00166     ble.getAddress(NULL, tagAddress);                       // Get random address from stack
00167     sprintf((char*)tagName, "TAG_%2X%2X", tagAddress[1], tagAddress[0]);
00168     ble.accumulateAdvertisingPayload(                       // Advertise as BLE
00169         GapAdvertisingData::BREDR_NOT_SUPPORTED |
00170         GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00171     ble.accumulateAdvertisingPayload(                       // Set name
00172         GapAdvertisingData::COMPLETE_LOCAL_NAME,
00173         tagName,
00174         sizeof(tagName));
00175     ble.setAdvertisingInterval((uint16_t)((float)BLE_ADV_INTERVAL / 0.625));    // Advertising interval
00176     ble.startAdvertising();                                 // Start advertising
00177     
00178     // Initialize accelerometer
00179     char acc_id;
00180     acc.getDeviceID(&acc_id);                               // Check if accelerometer succesfully comunicates
00181     if (acc_id != 0x2A) onError();
00182     acc.standby();                                          // Put into standby mode before configuration
00183     acc.setDataRate(acc.RATE_12_5);                         // Set hardware data rate to 12.5Hz
00184     acc.setDynamicRange(acc.DYNAMIC_RANGE_2G);              // Set dynamic range up to 2G
00185     acc.setBitDepth(acc.BIT_DEPTH_12);                      // Set bit depth to 12bits for resolution
00186     acc.activate();                                         // Activate accelerometer
00187     acc_tick.attach(&onAccTick, (1.0 / (float)ACC_RATE));   // Setup periodic reads
00188     
00189     // Setup algorithm
00190     alg_tick.attach(&onAlgTick, ALG_PERIOD);
00191     
00192     while (1) {
00193         ble.waitForEvent();
00194     }
00195 }