Geo beacon for VF.
Dependencies: MMA8452 aconno_bsp adc52832_common
Revision 12:6b072c2a061c, committed 2017-07-25
- Comitter:
- jurica238814
- Date:
- Tue Jul 25 12:19:39 2017 +0000
- Parent:
- 11:92a9fffd5015
- Parent:
- 7:89c9abaa257e
- Child:
- 13:d51127eed926
- Commit message:
- After merge. Has to be tested. Looks stable.
Changed in this revision
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
| main.cpp.orig | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Tue Jul 25 11:29:01 2017 +0000
+++ b/main.cpp Tue Jul 25 12:19:39 2017 +0000
@@ -2,7 +2,7 @@
*
* Made by Jurica Resetar @ aconno
* aconno.de
- * All rights reserved
+ * All rights reserved.
*
*/
@@ -20,16 +20,21 @@
#define SCAN_TIMER_TIME (0.5) // Scanning time (in s)
#define FREE_TIME (0.01) // Time between end of a scanning and sleep mode
#define AWAKE_TIME (ADV_TIMER_TIME+SCAN_TIMER_TIME+FREE_TIME) // Was 0.15
+#define SHORT_SLEEP_TIME (0.5) // Shorter sleep time (s)
+#define SHORT_SLEEP_TIME_PERIOD (60) // Time after a last scanned advertisment. In the period, sleep time is SHORT_SLEEP_TIME
+
/* Static constants for the BLE example */
#define MAX_BLE_PACKET_SIZE (31)
#define MSD_SIZE (18)
#define MSD_ID (0xFF)
+
#define BUZZ_TIME (1.0) // Buzz time in s
#define ADV_INTERVAL (100) // Advertising interval (in ms)
#define SCAN_INTERVAL (100) // Scan interval (in ms)
#define SCAN_WINDOW (50)
+
/* Static constants for the accelerometer */
#define WHO_AM_I 0x0D // Type 'read' : This should return the device id of 0x2A
#define OUT_Z_MSB 0x05 // Type 'read' : z axis - 8 most significatn bit of a 12 bit sample
@@ -39,6 +44,7 @@
#define BUZZER (p31)
uint8_t sleepFlag = 0;
+uint8_t tempSleepTime = SLEEP_TIME;
int8_t txPower = 4;
uint8_t MSD[MSD_SIZE] = {0x59, 0x00, 0xE1, 0x61, 0x35, 0xBA, 0xC0, 0xEC, 0x47, 0x2A, 0x98, 0x00, 0xAF, 0x18, 0x43, 0xFF, 0x05, 0x00};
uint8_t my_mac_address[6] = {};
@@ -59,6 +65,7 @@
Ticker WakeSleepT;
Ticker turnBuzzOffT;
+Ticker sleepChanger;
PwmOut buzzer(BUZZER);
PwmOut gyro_power(p7);
PwmOut i2c_power(p5); // I2C Pull-ups power pin
@@ -81,6 +88,7 @@
//BLE::Instance().gap().startAdvertising();
}
+
/**
* This function is called when the ble initialization process has failed
*/
@@ -175,14 +183,24 @@
}
}
+
+/* Call this function few minutes (TBD) after a last scanned advertisment */
+void changeSleepTime(){
+ tempSleepTime = SLEEP_TIME;
+ sleepChanger.detach();
+}
+
+
/**
* The function is called when ticker generates interrupt
*/
void turnBuzzOff(void){
buzzer.write(0.0F);
+ tempSleepTime = SHORT_SLEEP_TIME;
turnBuzzOffT.detach();
ble.gap().startScan(advertisementCallback);
WakeSleepT.attach(goToSleep, AWAKE_TIME);
+ sleepChanger.attach(changeSleepTime, SHORT_SLEEP_TIME_PERIOD);
}
void startAdvertising(){
@@ -239,7 +257,7 @@
void goToSleep(){
WakeSleepT.detach();
- WakeSleepT.attach(WakeMeUp, SLEEP_TIME);
+ WakeSleepT.attach(WakeMeUp, tempSleepTime);
ble.gap().stopAdvertising();
ble.gap().stopScan();
sleepFlag = 1;
@@ -278,7 +296,7 @@
//ble.gap().setScanTimeout(0.5);
//ble.gap().startScan(advertisementCallback);
- buzzer.period(0.001F);
+ buzzer.period(0.0009F);
buzzer.write(0.0F);
gyro_power.period(0.01F);
gyro_power.write(1.0F);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp.orig Tue Jul 25 12:19:39 2017 +0000
@@ -0,0 +1,324 @@
+/*
+ *
+ * Made by Jurica Resetar @ aconno
+ * aconno.de
+ * All rights reserved
+ *
+ */
+
+#include "mbed.h"
+#include "ble/BLE.h"
+#include "GapAdvertisingData.h"
+#include "acd52832_bsp.h"
+#include "mma8452.h"
+
+#define DEBUG (1)
+#define DEBUG_ACC (0)
+
+#define SLEEP_TIME (2.0) // Sleep time in seconds WAS 0.85
+#define ADV_TIMER_TIME (0.1) // Advertising time (in s)
+#define SCAN_TIMER_TIME (0.5) // Scanning time (in s)
+#define FREE_TIME (0.01) // Time between end of a scanning and sleep mode
+#define AWAKE_TIME (ADV_TIMER_TIME+SCAN_TIMER_TIME+FREE_TIME) // Was 0.15
+
+/* Static constants for the BLE example */
+#define MAX_BLE_PACKET_SIZE (31)
+#define MSD_SIZE (18)
+#define MSD_ID (0xFF)
+#define BUZZ_TIME (1.0) // Buzz time in s
+#define ADV_INTERVAL (100) // Advertising interval (in ms)
+#define SCAN_INTERVAL (100) // Scan interval (in ms)
+#define SCAN_WINDOW (50)
+
+/* Static constants for the accelerometer */
+#define WHO_AM_I 0x0D // Type 'read' : This should return the device id of 0x2A
+#define OUT_Z_MSB 0x05 // Type 'read' : z axis - 8 most significatn bit of a 12 bit sample
+#define I2C_DATA (p29)
+#define I2C_CLK (p2)
+#define INT2_PIN (p4)
+#define BUZZER (p31)
+
+uint8_t sleepFlag = 0;
+int8_t txPower = 4;
+uint8_t MSD[MSD_SIZE] = {0x59, 0x00, 0xE1, 0x61, 0x35, 0xBA, 0xC0, 0xEC, 0x47, 0x2A, 0x98, 0x00, 0xAF, 0x18, 0x43, 0xFF, 0x05, 0x00};
+uint8_t my_mac_address[6] = {};
+uint8_t buzzer_flag = 0;
+
+enum _radioState{
+ OFF,
+ ADVERTISING,
+ SCANNING
+ };
+enum _radioState radioState = OFF;
+
+void turnBuzzOff(void);
+void goToSleep();
+void startAdvertising();
+void startScanning();
+void WakeMeUp();
+
+Ticker WakeSleepT;
+Ticker turnBuzzOffT;
+PwmOut buzzer(BUZZER);
+PwmOut gyro_power(p7);
+PwmOut i2c_power(p5); // I2C Pull-ups power pin
+InterruptIn gyro_pulse(INT2_PIN);
+Acc_MMA8452 acc(I2C_DATA, I2C_CLK, MMA8452_ADDRESS);
+BLE &ble = BLE::Instance();
+
+
+#if DEBUG
+ DigitalOut advLED(p22);
+ DigitalOut scanLED(p23);
+ DigitalOut awake(p24);
+#endif
+#if DEBUG_ACC
+ DigitalOut int_led(p22);
+#endif
+
+/* Restart Advertising on disconnection*/
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){
+ //BLE::Instance().gap().startAdvertising();
+}
+
+/**
+ * This function is called when the ble initialization process has failed
+ */
+void onBleInitError(BLE &ble, ble_error_t error){
+ /* Avoid compiler warnings */
+ (void) ble;
+ (void) error;
+ /* Initialization error handling should go here */
+}
+
+/**
+ * Callback triggered when the ble initialization process has finished
+ */
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){
+ BLE& ble = params->ble;
+ ble_error_t error = params->error;
+
+ if (error != BLE_ERROR_NONE) {
+ /* In case of error, forward the error handling to onBleInitError */
+ onBleInitError(ble, error);
+ return;
+ }
+
+ /* Ensure that it is the default instance of BLE */
+ if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+ return;
+ }
+
+ ble.gap().onDisconnection(disconnectionCallback);
+
+ /* Get my MAC address */
+ BLEProtocol::AddressType_t temp_address_type;
+ ble.gap().getAddress(&temp_address_type, my_mac_address);
+
+
+ /* setup advertising */
+
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)MSD, MSD_SIZE);
+ ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
+ ble.gap().setAdvertisingInterval(ADV_INTERVAL); // --> Has to be at least 100ms!
+ //ble.gap().startAdvertising();
+}
+
+
+uint8_t findMSDIndex(const Gap::AdvertisementCallbackParams_t *params){
+ uint8_t i=0;
+ uint8_t len;
+
+ do{
+ len = params->advertisingData[i];
+ i++;
+ if(params->advertisingData[i] == MSD_ID) return i;
+ else i += (len-1);
+ }while(i<MAX_BLE_PACKET_SIZE);
+
+ return 0;
+}
+
+/**
+ * Function is called when BLE radio discovers any kind of advertisment
+ */
+void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params){
+ uint8_t i=0;
+ uint8_t msdOffset;
+
+ ble.gap().stopScan();
+ msdOffset = findMSDIndex(params);
+ if(msdOffset == 0){
+ // There's no MSD in BLE advertisement data
+ return;
+ }
+
+ if ((params->advertisingData[msdOffset]) == MSD_ID){
+ // Follows Manufacturer Specific Data
+ if ((params->advertisingData[msdOffset+1]) == 0x59){
+ if ((params->advertisingData[msdOffset+2]) == 0x00){
+ for(i=0; i<6; i++){
+ if((params->advertisingData[msdOffset+i+3]) == my_mac_address[5-i]){
+ continue;
+ }
+ else{
+ return;
+ }
+ }
+ turnBuzzOffT.detach();
+ WakeSleepT.detach();
+ buzzer.write(0.5F);
+ turnBuzzOffT.attach(turnBuzzOff, BUZZ_TIME);
+ }
+ }
+ }
+}
+
+/**
+ * The function is called when ticker generates interrupt
+ */
+void turnBuzzOff(void){
+ buzzer.write(0.0F);
+ turnBuzzOffT.detach();
+ ble.gap().startScan(advertisementCallback);
+ WakeSleepT.attach(goToSleep, AWAKE_TIME);
+}
+
+void startAdvertising(){
+ ble.gap().startAdvertising();
+ radioState = ADVERTISING;
+ #if DEBUG
+ advLED = 0;
+ scanLED = 1;
+ #endif
+ WakeSleepT.detach();
+ WakeSleepT.attach(WakeMeUp, ADV_TIMER_TIME); // Call the wakeMeUp function
+}
+
+void startScanning(){
+ ble.gap().stopAdvertising();
+ ble.gap().setScanParams(SCAN_INTERVAL, SCAN_WINDOW);
+ ble.gap().setScanTimeout(SCAN_TIMER_TIME);
+ ble.gap().startScan(advertisementCallback);
+ radioState = SCANNING;
+ #if DEBUG
+ advLED = 1;
+ scanLED = 0;
+ #endif
+ WakeSleepT.detach();
+ WakeSleepT.attach(WakeMeUp, SCAN_TIMER_TIME);
+}
+
+void WakeMeUp(){
+ sleepFlag = 0;
+ switch(radioState){
+ case OFF:{
+ startAdvertising();
+ break;
+ }
+ case ADVERTISING:{
+ startScanning();
+ break;
+ }
+ case SCANNING:{
+ radioState = OFF;
+ ble.gap().stopAdvertising(); // Just in case
+ ble.gap().stopScan();
+ WakeSleepT.detach();
+ WakeSleepT.attach(goToSleep, FREE_TIME);
+ #if DEBUG
+ advLED = 1;
+ scanLED = 1;
+ #endif
+ break;
+ }
+ default: return;
+ }
+}
+
+void goToSleep(){
+ WakeSleepT.detach();
+ WakeSleepT.attach(WakeMeUp, SLEEP_TIME);
+ ble.gap().stopAdvertising();
+ ble.gap().stopScan();
+ sleepFlag = 1;
+}
+
+void buzz(void){
+ buzzer.write(0.5f);
+ wait_ms(100);
+ buzzer.write(0.0f);
+ sleepFlag = 0;
+}
+
+void pulse_handler(void){
+ #if DEBUG_ACC
+ int_led = !int_led;
+ #endif
+ i2c_power.write(1.0F);
+ buzzer_flag = 1;
+ // Be awake some time
+ //WakeSleepT.detach();
+ //WakeSleepT.attach(goToSleep, AWAKE_TIME);
+}
+
+int main(void){
+ #if DEBUG
+ awake = 1;
+ advLED = 1;
+ scanLED = 1;
+ #endif
+ WakeSleepT.attach(goToSleep, AWAKE_TIME);
+ ble.init(bleInitComplete);
+ ble.gap().setTxPower(txPower);
+ GapAdvertisingData postavke = GapAdvertisingData();
+
+ //ble.gap().setScanParams(SCAN_INTERVAL, SCAN_WINDOW);
+ //ble.gap().setScanTimeout(0.5);
+ //ble.gap().startScan(advertisementCallback);
+
+ buzzer.period(0.001F);
+ buzzer.write(0.0F);
+ gyro_power.period(0.01F);
+ gyro_power.write(1.0F);
+ i2c_power.period(0.01F);
+ i2c_power.write(1.0F);
+ wait_ms(1000);
+
+ /* Pulse interrupt detection */
+ acc.set_register((char)CTRL_REG_4, (char) 0x04); // INT_EN_FF_MT Freefall/motion interrupt enabled
+ wait_ms(1);
+ acc.set_register((char)FF_MT_CFG, (char) 0b01011000); //ELE, Motion Flag ON, YEFE, X Event Flag Enable
+ wait_ms(1);
+ acc.set_register((char)CTRL_REG_5, (char) 0x00); // INT_EN_FF_MT interrupt is router t0 INT2
+ wait_ms(1);
+ acc.set_register((char)FF_COUNT, (char) 0x08); // Set Counter degister value (10ms)
+ wait_ms(1);
+ acc.set_register((char)FF_MT_THS, (char) 0x90); // Set TH value for motion detection on 1 G (1/0.063) and DBCNTM = 1 (Increments or clears counter)
+ wait_ms(1);
+
+ /* Setup for the interrupt handler */
+ //gyro_pulse.rise(&pulse_handler); // -------------------------------------
+ acc.set_register((char)CTRL_REG_1, (char) 0x01); // Flow data rate and Active mode
+ wait(1);
+
+ __enable_irq();
+
+ /* SpinWait for initialization to complete. This is necessary because the
+ * BLE object is used in the main loop below. */
+ while (ble.hasInitialized() == false){
+ /* spin loop */
+ }
+
+ while(true){
+ if(sleepFlag){
+ if(!awake) awake = 1;
+ __WFI();
+ }
+ else{
+ if(awake) awake = 0;
+ ble.waitForEvent();
+ }
+ }
+}

