Firmware for BLE Tags
Dependencies: BLE_API MMA8452_tag_private mbed nRF51822
Fork of cow_beacon_adxl345 by
main.cpp
- Committer:
- luisbc92
- Date:
- 2016-06-14
- Revision:
- 2:eb47002f16b5
- Parent:
- 1:1c14c1d3ce09
File content as of revision 2:eb47002f16b5:
#include "mbed.h" #include "BLEDevice.h" #include "MMA8452.h" // Configuration #define BLE_ADV_INTERVAL 1000 // Interval between each advertising packet (in MS) #define ACC_RATE 8 // Accelerometer sampling rate (in Hz) #define ACC_BUFFER_SIZE 8 // Accelerometer history size (DON'T CHANGE) // Objects BLEDevice ble; // BLE DigitalOut led(P0_2); // LED (Active Low) InterruptIn btn(P0_3); // Button Interrupt (Active Low) MMA8452 acc(P0_22, P0_20, 100000); // Accelerometer Ticker acc_tick; // Ticker for the accelerometer Ticker led_tick; // Ticker for led Ticker alg_tick; // Ticker for algorithm // Data struct acc_ring { double data[3][ACC_BUFFER_SIZE]; int8_t data_int[3][ACC_BUFFER_SIZE]; int head; } acc_ring; // Prototypes void onError(); void onAccTick(); void onButton(); void onLedTick(); void ledBlink(int, float); void ledStop(); double getAccLast(int); double getAccMean(int); void setPayload(uint8_t*, uint8_t); // Events void onError() { led = 1; wait(0.25); led = 0; wait(0.25); } void onAccTick() { // Read accelerometer acc.readXGravity(&acc_ring.data[0][acc_ring.head]); acc.readYGravity(&acc_ring.data[1][acc_ring.head]); acc.readZGravity(&acc_ring.data[2][acc_ring.head]); // Convert to integer acc_ring.data_int[0][acc_ring.head] = (int8_t)(acc_ring.data[0][acc_ring.head] * 100); acc_ring.data_int[1][acc_ring.head] = (int8_t)(acc_ring.data[1][acc_ring.head] * 100); acc_ring.data_int[2][acc_ring.head] = (int8_t)(acc_ring.data[2][acc_ring.head] * 100); // Increment head acc_ring.head++; if (acc_ring.head >= ACC_BUFFER_SIZE) { acc_ring.head = 0; setPayload((uint8_t*)acc_ring.data_int, sizeof(acc_ring.data_int)); } } void onButton() { ledBlink(3, 1); } int led_blink; void onLedTick() { led = !led; // Invert LED state if (led == 1) // If led was turned off led_blink--; // Decrement blink counter if (led_blink == 0) led_tick.detach(); } // Functions void setPayload(uint8_t * data, uint8_t size) { ble.clearScanResponse(); ble.accumulateScanResponse(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data, size); ble.setAdvertisingPayload(); } void ledBlink(int num, float period) { led = 0; led_blink = num; led_tick.attach(&onLedTick, period/2); } void ledStop() { led_blink = 0; led_tick.detach(); } double getAccMean(int axis) { double mean = 0; for (int i = 0; i < ACC_BUFFER_SIZE; i++) { mean += acc_ring.data[axis][i]; } return (mean / (float)ACC_BUFFER_SIZE); } int main(void) { // Initialize LED and Button led = 1; btn.mode(PullUp); btn.fall(&onButton); // Initialize BLE uint8_t tagAddress[6]; uint8_t tagName[8]; ble.init(); // Initialize BLE stack ble.setTxPower(4); // Set power level (in dB) ble.setAddress(Gap::ADDR_TYPE_RANDOM_STATIC, NULL); // Static random address ble.getAddress(NULL, tagAddress); // Get random address from stack sprintf((char*)tagName, "TAG_%2X%2X", tagAddress[1], tagAddress[0]); ble.accumulateAdvertisingPayload( // Advertise as BLE GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.accumulateAdvertisingPayload( // Set name GapAdvertisingData::COMPLETE_LOCAL_NAME, tagName, sizeof(tagName)); ble.setAdvertisingInterval((uint16_t)((float)BLE_ADV_INTERVAL / 0.625)); // Advertising interval ble.startAdvertising(); // Start advertising // Initialize accelerometer char acc_id; acc.getDeviceID(&acc_id); // Check if accelerometer succesfully comunicates if (acc_id != 0x2A) onError(); acc.standby(); // Put into standby mode before configuration acc.setDataRate(acc.RATE_12_5); // Set hardware data rate to 12.5Hz acc.setDynamicRange(acc.DYNAMIC_RANGE_2G); // Set dynamic range up to 2G acc.setBitDepth(acc.BIT_DEPTH_12); // Set bit depth to 12bits for resolution acc.activate(); // Activate accelerometer acc_tick.attach(&onAccTick, (1.0 / (float)ACC_RATE)); // Setup periodic reads while (1) { ble.waitForEvent(); } }