Geo beacon for VF.

Dependencies:   MMA8452 aconno_bsp adc52832_common

Revision:
26:148aa2e2460c
Parent:
25:8ac3ff431ab1
Child:
27:2c67f07590fd
--- a/main.cpp	Wed Sep 06 10:41:09 2017 +0000
+++ b/main.cpp	Fri Sep 08 10:49:50 2017 +0000
@@ -14,21 +14,24 @@
 #include "AckService.h"
 #include "nrf52_uart.h"
 #include "nrf52_digital.h"
+#include "acn_nrf52_pwm.h"
 
-#define DEBUG               (0)
-#define DEBUG_ACC           (0)
-#define PRINT               (0)
+#define DEBUG               (1)
+#define DEBUG_ACC           (1)
+#define DEBUG_PRINT_UART    (0)
 #define DEBUG_MAC           (0)
 #define DEBUG_CONNECTION    (0)
-#define USE_ACC             (0)
+#define DEBUG_WAKEUP_BUZZER (0)
+
+#define USE_ACC             (1)
 
 #define SLEEP_TIME_S              (8.00)           /* Sleep time (in s)          */
 #define ADV_TIMER_TIME_S          (0.50)           /* Advertising time (in s)    */
 #define SCAN_TIMER_TIME_S         (0.25)           /* Scanning time (in s)       */
-#define FREE_TIME_S               (0.1)           /* Time between end of a scanning and sleep mode */
+#define FREE_TIME_S               (0.1)            /* Time between end of a scanning and sleep mode */
 #define AWAKE_TIME_S              (ADV_TIMER_TIME_S+SCAN_TIMER_TIME_S+FREE_TIME_S)      /* Was 0.15 */
-#define SHORT_SLEEP_TIME_S        (0.5)           /* Shorter sleep time (s) */
-#define SHORT_SLEEP_TIME_PERIOD_S (10)            /* Time after a last scanned advertisment. In the period, sleep time is SHORT_SLEEP_TIME */
+#define SHORT_SLEEP_TIME_S        (0.5)            /* Shorter sleep time (s) */
+#define SHORT_SLEEP_TIME_PERIOD_S (10)             /* Time after a last scanned advertisment. In the period, sleep time is SHORT_SLEEP_TIME */
 #define BUZZ_PERIOD_US            (250)
 #define BUZZ_DURATION_MS          (1000)
 #define MAC_SIZE_B                (6)
@@ -38,7 +41,7 @@
 #define MSD_SIZE            (18)
 #define MSD_ID              (0xFF)
 
-#define BUZZ_TIME_S         (1)    /* Buzz time in s */
+#define BUZZ_TIME_S         (1)     /* Buzz time in s */
 #define ADV_INTERVAL        (100)   /* Advertising interval (in ms) */
 #define SCAN_INTERVAL       (SCAN_TIMER_TIME_S)   /* Scan interval (in ms) */
 #define SCAN_WINDOW         (SCAN_TIMER_TIME_S)
@@ -51,15 +54,18 @@
 #define INT2_PIN            (p4)
 #define BUZZER              (p31)
 
-#if PRINT
-    /* Defines for debugging over uart */
-    #define TX              (p25)
-    #define RX              (p26)
-    NRF52_UART uart(TX,RX, Baud9600);
-    char printBuffer[30] = {};
+#define BUZZER_FREQUENCY_Hz (1500)
+
+#if DEBUG_PRINT_UART
+#include "nrf52_uart.h"
+NRF52_UART uart(p25, p26, Baud9600);
+char buffer[255];
+#define SEND(...) {uint8_t len = sprintf(buffer, __VA_ARGS__); uart.send(buffer, len);}
+#else
+#define SEND(...)
 #endif
 
-
+bool beaconStateActive = 1;
 
 bool shushShush = false;
 const static uint16_t ACK_CHARA_UUID = 0xA001;
@@ -76,20 +82,18 @@
 enum RadioState{
     OFF,
     ADVERTISING,
-    SCANNING
-    };
+    SCANNING,
+};
 enum RadioState radioState = OFF;
 
-void TurnBuzzOff(void);
 void GoToSleep();
 void StartAdvertising();
 void startScanning();
 void WakeMeUp();
 
+    
 Ticker WakeSleepT;
-Ticker turnBuzzOffT;
 Ticker sleepChanger;
-NRF52_DigitalOut buzzer(BUZZER);
 #if USE_ACC
     DigitalOut accPower(p7);
     DigitalOut i2cPower(p5);
@@ -100,24 +104,25 @@
 ACKService<4> *ackServicePtr;
 
 #if DEBUG || DEBUG_MAC || DEBUG_CONNECTION
-    DigitalOut advLED(p22);         // Red
-    DigitalOut scanLED(p23);        // Blue
-    DigitalOut connectedLED(p24);   // Green
+    NRF52_DigitalOut advLED(p22);         // Red
+    NRF52_DigitalOut scanLED(p23);        // Blue
+    NRF52_DigitalOut connectedLED(p24);   // Green
 #endif
 
 #if DEBUG_ACC
-    DigitalOut int_led(p22);
+    NRF52_DigitalOut int_led(p22);
+    NRF52_DigitalOut act_led(p22);
 #endif
 
-void buzz(uint16_t period_us, uint32_t duration_ms){
-    int32_t counter;
-    for(counter=0; counter<((duration_ms*1000)/(period_us*1.0)); counter++){
-        buzzer.toggle();
-        wait_us(period_us/2);
-        buzzer.toggle();
-        wait_us(period_us/2);
-    }
-    buzzer = 0;
+NRF52_PWM buzzer(NRF_PWM0);
+
+void buzzerStart(){
+    buzzer.enable(3000);
+    buzzer.enableChannel(0, BUZZER);
+    buzzer.setDuty(0, 0.5f);
+}
+void buzzerStop(){
+    buzzer.disable();
 }
 
 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params){   
@@ -143,6 +148,7 @@
 
 /* Restart Advertising on disconnection*/
 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){
+    buzzerStop();
     #if DEBUG_CONNECTION
         advLED = !advLED;       // RED
         wait_ms(100);
@@ -180,17 +186,23 @@
                     connectedLED = 1;
                     wait_ms(100);
                 #endif    
-                buzz(BUZZ_PERIOD_US,BUZZ_DURATION_MS);
+                buzzerStart();
                 return;
             }
         }
-     else if(params->data[0] == stopBuzz[0]){
-        if(params->data[1] == stopBuzz[1]){
-            WakeSleepT.detach();
-            WakeSleepT.attach(WakeMeUp, FREE_TIME_S);
-            ble.disconnect(Gap::LOCAL_HOST_TERMINATED_CONNECTION);
+        else if(params->data[0] == stopBuzz[0]){
+            if(params->data[1] == stopBuzz[1]){
+                WakeSleepT.detach();
+                WakeSleepT.attach(WakeMeUp, FREE_TIME_S);
+                ble.disconnect(Gap::LOCAL_HOST_TERMINATED_CONNECTION);
+                buzzerStop();
             }
         }
+        else if(params->data[0] == 0x55){
+            beaconStateActive = 0;
+            ble.disconnect(Gap::LOCAL_HOST_TERMINATED_CONNECTION);
+        }
+        
     }
     else{
         // Execute this for wrong data written into characteristic
@@ -239,8 +251,6 @@
     
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)msd, MSD_SIZE);
     ble.gap().setAdvertisingInterval(ADV_INTERVAL);  // --> Has to be at least 100ms!
-    
-
 }
 
 
@@ -318,7 +328,6 @@
             if ((params->advertisingData[msdOffset+2]) == 0x00){
                 if(CheckMac(params, myMacAddress, msdOffset)){
                     //ble.gap().stopScan();
-                    buzz(BUZZ_PERIOD_US,BUZZ_DURATION_MS);
                     WakeSleepT.detach();
                     WakeSleepT.attach(WakeMeUp, FREE_TIME_S);
                 }
@@ -334,18 +343,6 @@
     sleepChanger.detach();
 }
 
-
-/**
- *  The function is called when ticker generates interrupt
- */
-void TurnBuzzOff(void){
-    tempSleepTime = SHORT_SLEEP_TIME_S;
-    turnBuzzOffT.detach();
-    WakeSleepT.detach();
-    sleepChanger.attach(changeSleepTime, SHORT_SLEEP_TIME_PERIOD_S);
-    WakeSleepT.attach(WakeMeUp, FREE_TIME_S);
-}
-
 void startAdvertising(){
     #if USE_ACC
         i2cPower = 1;
@@ -420,14 +417,22 @@
 }
 
 #if USE_ACC
-    void pulse_handler(void){
-        #if DEBUG_ACC
-            int_led = !int_led;
-        #endif
+void pulse_handler(){
+#if DEBUG_WAKEUP_BUZZER
+    if(beaconStateActive == 0){
+        buzzerStart();
+        wait_ms(500);
+        buzzerStop();
+        beaconStateActive = 1;
     }
 #endif
+#if DEBUG_ACC
+    int_led = !int_led;
+#endif
+}
+#endif
 
-int main(void){   
+int main(){
     #if DEBUG || DEBUG_MAC
         advLED = 1;
         scanLED = 1;
@@ -439,60 +444,68 @@
         i2cPower = 1;
     #endif
     
-    #if PRINT
-        int i;
-        for(i=0; i<10; i++){
-            printBuffer[0] = 'B';
-            printBuffer[1] = 'o';
-            printBuffer[2] = 'k';
-            uart.send(printBuffer, 3);
-        wait_ms(100);
-        }
-    #endif
+    int_led = 0;
     
     //WakeSleepT.attach(GoToSleep, AWAKE_TIME_S);
     GoToSleep();
     ble.init(bleInitComplete);
     ble.gap().setTxPower(txPower);
-    GapAdvertisingData postavke = GapAdvertisingData();
     
     #if USE_ACC
         // Pulse interrupt detection
-        acc.set_register((char)CTRL_REG_4, (char) 0x04);        //  INT_EN_FF_MT Freefall/motion interrupt enabled
+        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
+        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
+        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)
+        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)
+        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
         accPulse.rise(&pulse_handler);                                                                                //  -------------------------------------
-        acc.set_register((char)CTRL_REG_1, (char) 0x01);        // Flow data rate and Active mode           
+        acc.set_register((char)CTRL_REG_1, (char)0x01);        // Flow data rate and Active mode           
         wait(1);
     #endif
     
     __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 (ble.hasInitialized()  == false){ /* spin loop */ }
+    
     while(true){
-        if(sleepFlag){
-            //NRF_GPIO->PIN_CNF[31] = 0x00000002;
-            #if USE_ACC
-                i2cPower = 0;
-            #endif
-            ble.waitForEvent();
+        if(beaconStateActive){
+            // wake up
+            
+            startAdvertising();
+            while(beaconStateActive){
+                if(sleepFlag){
+                    #if USE_ACC
+                        i2cPower = 0;
+                    #endif
+                    ble.waitForEvent();
+                    __WFI();
+                }
+                else{
+                    ble.waitForEvent();
+                }
+            }
+        }
+        
+        scanLED = 0;
+        // prepare for sleep
+            
+        // disable everything
+        i2cPower = 0;
+        WakeSleepT.detach();
+        // set accelerometer refresh rate to lowest
+        
+        // do not wake up until beaconStateActive is set by the accelerometer
+        while(!beaconStateActive){
             __WFI();
         }
-        else{
-            ble.waitForEvent();
-        }
+        scanLED = 1;
     }
 }