Geo beacon for VF.

Dependencies:   MMA8452 aconno_bsp adc52832_common

Files at this revision

API Documentation at this revision

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();
+        }
+    }
+}