Geo beacon for VF.
Dependencies: MMA8452 aconno_bsp adc52832_common
Revision 26:148aa2e2460c, committed 2017-09-08
- Comitter:
- Dautor
- Date:
- Fri Sep 08 10:49:50 2017 +0000
- Parent:
- 25:8ac3ff431ab1
- Child:
- 27:2c67f07590fd
- Commit message:
- Accelerometer and shush protocol.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/acn_nrf52_pwm.lib Fri Sep 08 10:49:50 2017 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/Dautor/code/acn_nrf52_pwm/#882e7c1b19b4
--- a/aconno_nrf52_uart.lib Wed Sep 06 10:41:09 2017 +0000 +++ b/aconno_nrf52_uart.lib Fri Sep 08 10:49:50 2017 +0000 @@ -1,1 +1,1 @@ -https://developer.mbed.org/users/Dautor/code/aconno_nrf52_uart/#ebebc790336a +https://developer.mbed.org/users/Dautor/code/aconno_nrf52_uart/#270c2cab3f9f
--- a/adc52832_common.lib Wed Sep 06 10:41:09 2017 +0000 +++ b/adc52832_common.lib Fri Sep 08 10:49:50 2017 +0000 @@ -1,1 +1,1 @@ -https://developer.mbed.org/teams/aconno-dev-team/code/adc52832_common/#522ed4572c53 +https://developer.mbed.org/teams/aconno-dev-team/code/adc52832_common/#b694bfd63c68
--- 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;
}
}
--- a/main.cpp.orig Wed Sep 06 10:41:09 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,324 +0,0 @@
-/*
- *
- * 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();
- }
- }
-}

