Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MMA8452_tag_private BLE_API mbed nRF51822
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 }
Generated on Thu Aug 25 2022 05:48:35 by
1.7.2