init
Dependencies: aconno_I2C Lis2dh12 WatchdogTimer
Diff: main.cpp
- Revision:
- 52:bd7678eade77
- Parent:
- 51:9078e6928412
- Child:
- 53:c6942af186d7
--- a/main.cpp Thu May 23 11:39:28 2019 +0000
+++ b/main.cpp Wed May 29 22:59:12 2019 +0000
@@ -6,109 +6,143 @@
• Ensure APP DATA address is correct
*/
-
/*
TO DO
STOP FRASH WRITE FROM CRASHING IF THERE IS A PROBLEM
-
*/
-
//------------------------------------------------------------------------------
//FUNCTION PROTOTYPES - NEED TO ADD ALL OF THE MISSING ONES
//------------------------------------------------------------------------------
//should really add these - will just add as and when needed for now
void event_activity_tx();
void event_location_tx(bool failsafe);
+#if BLE_ENABLED
+ void bleShutdown();
+#endif
//------------------------------------------------------------------------------
// GLOBALS
//------------------------------------------------------------------------------
-bool GLOBAL_debugLED = false;
-char* GLOBAL_defaultApi = "b:gps2";
-bool GLOBAL_accel_healthy = false;
-bool GLOBAL_motionStopFlagTriggered = false;
-bool GLOBAL_needToConfigureLis3dh = false;
-bool GLOBAL_registeredOnNetwork = false;
-bool GLOBAL_modemOn = false;
-bool GLOBAL_LEDSequenceinProgress = false;
-time_t GLOBAL_wakeTime = 0;
+char* GLOBAL_defaultApi = "b:gps2";
+bool GLOBAL_accel_healthy = false;
+bool GLOBAL_motionStopFlagTriggered = false;
+bool GLOBAL_needToConfigureLis3dh = false;
+bool GLOBAL_registeredOnNetwork = false;
+bool GLOBAL_modemOn = false;
+bool GLOBAL_LEDSequenceinProgress = false;
+time_t GLOBAL_wakeTime = 0;
char GLOBAL_exceptionString[30];
-char GLOBAL_debug_buffer[200];
+char GLOBAL_debug_buffer[DEBUG_BUFFERSIZE];
char GLOBAL_failed_broadcasts[10][160];
bool GLOBAL_failed_broadcast_slots[10];
+char GLOBAL_GPSlocString_prev[70];
+bool GLOBAL_have_GPSlocString_prev = false;
//SETTINGS
-int RET_setting_firmware;
-uint32_t RET_setting_minimumupdate_hrs;
-uint8_t RET_setting_location_mode;
-uint8_t RET_setting_location_accuracy;
-uint32_t RET_setting_location_tx_interval_mins;
-uint32_t RET_setting_location_tx_failsafe_hrs;
-uint16_t RET_setting_location_timeout;
-uint32_t RET_setting_activity_tx_interval_hrs;
-uint8_t RET_setting_activity_mode;
-uint32_t RET_setting_environmental_tx_interval_mins;
-uint16_t RET_setting_motion_g;
-time_t RET_setting_motion_start_seconds;
-time_t RET_setting_motion_stop_seconds;
-uint16_t RET_setting_impact_g;
-uint8_t RET_setting_impact_alert;
-uint16_t RET_setting_connection_timeout;
-uint16_t RET_setting_beacon_interval_seconds;
-uint16_t RET_setting_beacon_scan;
+int RET_setting_firmware = 0;
+uint32_t RET_setting_minimumupdate_hrs = 0;
+uint8_t RET_setting_location_mode = DEFAULT_LOCATION_MODE;
+uint8_t RET_setting_location_accuracy = DEFAULT_LOCATION_ACCURACY;
+uint32_t RET_setting_location_tx_interval_mins = DEFAULT_LOCATION_TX_INTERVAL_MINS;
+uint32_t RET_setting_location_tx_failsafe_hrs = DEFAULT_LOCATION_TX_FAILSAFE_HRS;
+uint16_t RET_setting_location_timeout = DEFAULT_LOCATION_TIMEOUT;
+uint32_t RET_setting_activity_tx_interval_hrs = 0;
+uint8_t RET_setting_activity_mode = 1;
+uint32_t RET_setting_environmental_tx_interval_mins = 0;
+uint16_t RET_setting_motion_g = DEFAULT_MOTION_G;
+time_t RET_setting_motion_start_seconds = DEFAULT_MOTION_START_SECONDS;
+time_t RET_setting_motion_stop_seconds = DEFAULT_MOTION_STOP_SECONDS;
+uint16_t RET_setting_impact_g = 0;
+uint8_t RET_setting_impact_alert = 0;
+uint16_t RET_setting_connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
+uint16_t RET_setting_beacon_interval_seconds = 0;
+uint8_t RET_setting_beacon_scan = 0;
//STATE
char RET_pf_identifier[7];
-uint8_t RET_coldBoot = 1;
-bool RET_asleep = false;
-bool RET_busy = false;
-time_t RET_RTCunixtime;
-bool RET_haveSettings;
-uint8_t RET_state;
-uint8_t RET_state_prev;
-uint8_t RET_buttonPressCount;
-time_t RET_buttonPressTime;
-time_t RET_buttonReleaseTime;
-time_t RET_buttonReleaseTime_prev;
-time_t RET_buttonHoldTime;
-time_t RET_SetupRunAt;
-time_t RET_SettingsGotAt;
-bool RET_setupInProgress;
-bool RET_force2G;
-bool RET_watchdogfired;
-bool RET_receivedNewSettings;
-uint32_t RET_GPSFailCount;
-uint32_t RET_NetworkFailCount;
-bool RET_debug = true;
-time_t RET_debug_offat;
-float RET_voltage;
-float RET_temperature;
-float RET_temperature_max = -999.0; //Within broadcast frame. Set inital value to low
-float RET_temperature_min = 999.0; //Within broadcase frame. Set inital value to high
+uint8_t RET_coldBoot = 1;
+bool RET_asleep = false;
+bool RET_busy = false;
+time_t RET_RTCunixtime = 0;
+bool RET_haveSettings = false;
+uint8_t RET_state = STATE_SETUP;
+uint8_t RET_state_prev = RET_state;
+uint8_t RET_buttonPressCount = 0;
+time_t RET_buttonPressTime = 0;
+time_t RET_buttonReleaseTime = 0;
+time_t RET_buttonReleaseTime_prev = 0;
+time_t RET_buttonHoldTime = 0;
+time_t RET_SetupRunAt = 0;
+time_t RET_SettingsGotAt = 0;
+bool RET_setupInProgress = false;
+bool RET_force2G = DEFAULT_FORCE2G;
+bool RET_watchdogfired = false;
+bool RET_receivedNewSettings = false;
+uint32_t RET_GPSFailCount = 0;
+uint32_t RET_NetworkFailCount = 0;
+bool RET_debug = true;
+time_t RET_debug_offat = 0;
+float RET_voltage = 0.0;
+float RET_temperature = 0.0;
+float RET_temperature_max = -999.0; //Within broadcast frame. Set inital value to low
+float RET_temperature_min = 999.0; //Within broadcase frame. Set inital value to high
+uint32_t RET_modemBrownOutCountInSession = 0;
//MOTION STATE
-bool RET_motionTriggeredinFrame;
-bool RET_motionTriggeredInLocTXInterval;
-time_t RET_motionStartTime;
-time_t RET_motionStopTime;
-bool RET_motionPendingOnState;
-bool RET_motionPendingOffState;
-bool RET_motionState;
-float RET_motionTotalActivityHours;
-float RET_motionTotalActivityHoursSincePost;
-time_t RET_motionFrameStart;
+bool RET_motionTriggeredinFrame = false;
+bool RET_motionStateOnInLocTXInterval = false;
+time_t RET_motionStartTime = 0;
+time_t RET_motionStopTime = 0;
+bool RET_motionPendingOnState = false;
+bool RET_motionPendingOffState = false;
+bool RET_motionState = false;
+float RET_motionTotalActivityHours = 0.0f;
+float RET_motionTotalActivityHoursSincePost = 0.0f;
+time_t RET_motionFrameStart = 0;
char RET_activityData[ACTIVITY_BUFFERSIZE];
//IMPACT
-bool RET_impactTriggered;
+bool RET_impactTriggered = 0;
//EVENTS LOGGING
-time_t RET_eventTime_location_log;
-time_t RET_eventTime_environmental_log;
+time_t RET_eventTime_location_log = 0;
+time_t RET_eventTime_environmental_log = 0;
//EVENTS TX
-time_t RET_eventTime_location_tx;
-time_t RET_eventTime_location_failsafe_tx;
-time_t RET_eventTime_environmental_tx;
-time_t RET_eventTime_activity_tx;
-time_t RET_eventTime_wakeFromDormant;
-
+time_t RET_eventTime_location_tx = 0;
+time_t RET_eventTime_location_failsafe_tx = 0;
+time_t RET_eventTime_environmental_tx = 0;
+time_t RET_eventTime_activity_tx = 0;
+time_t RET_eventTime_wakeFromDormant = 0;
+//BLE
+#if BLE_ENABLED
+ bool RET_bleBroadcasting = false;
+ uint8_t RET_bleAdv_flags = 0;
+ char RET_closestLocationTag_id[17];
+ int RET_closestLocationTag_rssi = 999;
+ bool RET_locationTag_present = false;
+ bool RET_detector_present = false;
+ const uint8_t bleAdv_motionTriggeredinFrame_flag = 0b01000000;
+ const uint8_t bleAdv_motionState_flag = 0b00100000;
+ const uint8_t bleAdv_impact_flag = 0b00010000;
+ #pragma pack(1)
+ struct bleData_t {
+ uint16_t applicationSpecificId;
+ uint8_t firmware;
+ uint8_t flags;
+ uint16_t voltage;
+ uint8_t buttonpresses;
+ int16_t temperature;
+ uint8_t humidity;
+ uint8_t lux;
+ int8_t accel_x;
+ int8_t accel_y;
+ int8_t accel_z;
+ /*char id_1; //cant use this and local name as it pushes us over size limit
+ char id_2;
+ char id_3;
+ char id_4;
+ char id_5;
+ char id_6;*/
+ };
+ #pragma pack()
+#endif
//------------------------------------------------------------------------------
//GPIO
//------------------------------------------------------------------------------
@@ -117,22 +151,27 @@
//------------------------------------------------------------------------------
//PERIPHERALS
//------------------------------------------------------------------------------
-WatchdogTimer watchdog; //Do not set to less than 4500ms or can cause issues with softdevice
-void watchdogKick() { watchdog.kick();}
-//SI7060 si7060(PN_I2C_SDA, PN_I2C_SCL);
+#if BLE_ENABLED
+ BLE myble;
+#endif
+WatchdogTimer watchdog;
LIS3DH lis3dh(PN_SPI_MOSI, PN_SPI_MISO, PN_SPI_CS0, PN_SPI_CLK);
+SI7060 si7060(PN_I2C_SDA, PN_I2C_SCL);
Modem modem(PN_GSM_PWR_KEY, PN_VREG_EN, PN_GSM_WAKE_DISABLE);
LowPowerTicker RTCticker;
LowPowerTimer LPtimer;
//------------------------------------------------------------------------------
-//THREAD SEMAPHORES
+//SEMAPHORES
//------------------------------------------------------------------------------
Semaphore mainthread;
//------------------------------------------------------------------------------
// LOW LEVEL FUNCS
//------------------------------------------------------------------------------
+void watchdogKick() {
+ watchdog.kick();
+}
void set_8bit_flag(uint8_t& flags, uint8_t flag) {
flags |= flag;
}
@@ -152,20 +191,16 @@
nrf_gpio_cfg_input(PN_GSM_PWR_KEY, NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_input(PN_GSM_WAKE_DISABLE, NRF_GPIO_PIN_NOPULL);
- /*
- //ERRATA 89, shut down i2c channels properly
//TWI0
- //NRF_TWI0->ENABLE=0;//TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
- //NRF_TWI0->ENABLE=1;//TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
+ NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
*(volatile uint32_t *)0x40003FFC = 0;
*(volatile uint32_t *)0x40003FFC;
*(volatile uint32_t *)0x40003FFC = 1;
//TWI1
- //NRF_TWI1->ENABLE=TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
+ NRF_TWI1->ENABLE=TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
*(volatile uint32_t *)0x40004FFC = 0;
*(volatile uint32_t *)0x40004FFC;
*(volatile uint32_t *)0x40004FFC = 1;
- */
}
void setState(uint8_t state) {
RET_state_prev = RET_state;
@@ -197,6 +232,9 @@
}
}
void recordFirmwareAsValid() {
+ #if BLE_ENABLED
+ bleShutdown();
+ #endif
debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RECORD FW %d AS VALID...", FW_VERSION);debug_exe();
read_app_data_from_flash(&app_data);
bool write_app_data_to_flash_execute = false;
@@ -237,54 +275,22 @@
}
RET_voltage = (voltage_accumulator / (float)readings);
}
-float nrfTemperature() {
- float temperature = 0.0;
-
- //INTERNAL NRF52 TEMP SENSOR
- uint32_t safetycounter = 0;
- NRF_TEMP->TASKS_START=1;
- while (NRF_TEMP->EVENTS_DATARDY==0 && safetycounter < 10000) {
- safetycounter ++;
- };
- NRF_TEMP->EVENTS_DATARDY=0;
- temperature = nrf_temp_read()/4.0;
- NRF_TEMP->TASKS_STOP=1;
-
- //SOFTDEVICE METHOD - To use this method you need to include #include "nrf_soc.h"
- //THIS GAVE SOME INTERMITENT ODD RESULTS AND DOESNT SEEM AS RELIABLE
- /*
- int32_t t;
- sd_temp_get(&t);
- temperature = t/4.0;
- */
-
- return temperature;
-}
+//------------------------------------------------------------------------------
+// TEMPERATURE
+//------------------------------------------------------------------------------
float getTemperature() {
- float temperature;
- if (USE_NRF_TEMP_SENSOR) {
- temperature = nrfTemperature();
- } else {
- //temperature = si7060.getTemperature(); //currently disabled because its causing a high current 450ua sleep, most likely due to sensor not sleeping correctly, or i2c sleep issue
- }
- return temperature;
+ return si7060.getTemperature();
}
void updateTemperatures() {
- //RET_temperature = getTemperature(); //not smoothed
- if (RET_temperature == 0.0f) {RET_temperature = getTemperature();}
+ if (RET_temperature == 0.0) {RET_temperature = getTemperature();}
RET_temperature = (RET_temperature + (getTemperature() - RET_temperature) * 0.25f); //smoothed
-
- if (RET_temperature < RET_temperature_min) {
- RET_temperature_min = RET_temperature;
- }
- if (RET_temperature > RET_temperature_max) {
- RET_temperature_max = RET_temperature;
- }
+ if (RET_temperature < RET_temperature_min) {RET_temperature_min = RET_temperature;}
+ if (RET_temperature > RET_temperature_max) {RET_temperature_max = RET_temperature;}
if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Temp:%.1f Min:%.1f Max:%.1f",RET_temperature,RET_temperature_min,RET_temperature_max);debug_exe();}
}
void addToExceptionString(char* value) {
if(strstr(GLOBAL_exceptionString, value) == false){
- snprintf(GLOBAL_exceptionString+strlen(GLOBAL_exceptionString),sizeof(GLOBAL_exceptionString),"%s.",value);
+ snprintf(GLOBAL_exceptionString+strlen(GLOBAL_exceptionString),sizeof(GLOBAL_exceptionString),".%s",value);
}
}
void resetTemperatures() {
@@ -305,7 +311,7 @@
RET_buttonHoldTime = (RET_buttonReleaseTime - RET_buttonPressTime);
//temporarily enable debugging and dump settings
RET_debug = true;
- RET_debug_offat = (RET_RTCunixtime + 600); //debug on for 10 mins
+ RET_debug_offat = (RET_RTCunixtime + 3600); //debug on for 1hr
}
RET_buttonReleaseTime_prev = RET_buttonReleaseTime;
}
@@ -365,11 +371,22 @@
RET_buttonPressCount = 0;
}
}
+
+ if(RET_debug && GLOBAL_LEDSequenceinProgress == false){
+ if (RET_motionState) {
+ led1 = 0;
+ } else {
+ led1 = 1;
+ }
+ }
}
-
-void resetGlobals() {
+//------------------------------------------------------------------------------
+// GLOBALS
+//------------------------------------------------------------------------------
+void resetSessionVars() {
GLOBAL_accel_healthy = false;
- GLOBAL_motionStopFlagTriggered = false;
+ RET_motionTriggeredinFrame = false;
+ RET_modemBrownOutCountInSession = 0;
memset(GLOBAL_exceptionString,0x00,sizeof(GLOBAL_exceptionString));
}
void healthCheck() {
@@ -404,69 +421,6 @@
setState(STATE_SETUP);
}
}
-void setDefaults() {
- //STATE
- RET_asleep = false;
- RET_busy = false;
- RET_haveSettings = false;
- RET_state = STATE_SETUP;
- RET_state_prev = RET_state;
- RET_RTCunixtime = 0;
- RET_SetupRunAt = 0;
- RET_SettingsGotAt = 0;
- RET_force2G = DEFAULT_FORCE2G;
- RET_watchdogfired = false;
- RET_setupInProgress = false;
- RET_receivedNewSettings = false;
- RET_GPSFailCount = 0;
- RET_NetworkFailCount = 0;
- //SETTINGS
- RET_setting_firmware = 0;
- RET_setting_minimumupdate_hrs = 0;
- RET_setting_location_mode = DEFAULT_LOCATION_MODE;
- RET_setting_location_accuracy = DEFAULT_LOCATION_ACCURACY;
- RET_setting_location_tx_interval_mins = DEFAULT_LOCATION_TX_INTERVAL_MINS;
- RET_setting_location_tx_failsafe_hrs = DEFAULT_LOCATION_TX_FAILSAFE_HRS;
- RET_setting_location_timeout = DEFAULT_LOCATION_TIMEOUT;
- RET_setting_activity_tx_interval_hrs = 0;
- RET_setting_activity_mode = 1;
- RET_setting_environmental_tx_interval_mins = 0;
- RET_setting_motion_g = DEFAULT_MOTION_G;
- RET_setting_motion_start_seconds = DEFAULT_MOTION_START_SECONDS;
- RET_setting_motion_stop_seconds = DEFAULT_MOTION_STOP_SECONDS;
- RET_setting_impact_g = 0;
- RET_setting_impact_alert = 0;
- RET_setting_connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
- RET_setting_beacon_scan = 0;
- RET_buttonPressCount = 0;
- RET_buttonPressTime = 0;
- RET_buttonReleaseTime = 0;
- RET_buttonHoldTime = 0;
- //MOTION STATE
- RET_motionTriggeredinFrame = false;
- RET_motionTriggeredInLocTXInterval = false;
- RET_motionStartTime = 0;
- RET_motionStopTime = 0;
- RET_motionPendingOnState = 0;
- RET_motionPendingOffState = 0;
- RET_motionState = 0;
- RET_motionTotalActivityHours = 0.0;
- RET_motionTotalActivityHoursSincePost = 0.0;
- RET_motionFrameStart = 0;
- memset(RET_activityData,0x00,sizeof(RET_activityData));
- //IMPACT
- RET_impactTriggered = 0;
- //EVENT HANDLING
- RET_eventTime_location_log = 0;
- RET_eventTime_location_tx = 0;
- RET_eventTime_location_failsafe_tx = 0;
- RET_eventTime_environmental_log = 0;
- RET_eventTime_environmental_tx = 0;
- RET_eventTime_activity_tx = 0;
- RET_eventTime_wakeFromDormant = 0;
- //PERIPHERAL RESET
- lis3dh_configureForSleep(DEFAULT_MOTION_G,DEFAULT_IMPACT_G);
-}
bool selfTest() {
int test_count = 0;
@@ -481,17 +435,224 @@
test_pass ++;
} else {
GLOBAL_accel_healthy = false;
- addToExceptionString("A");
+ addToExceptionString("AF");
}
//Result
if (test_count == test_pass) {
return true;
} else {
- addToExceptionString("HF");
+ //addToExceptionString("HF");
return false;
}
}
+//------------------------------------------------------------------------------
+// BLE FUNCS
+//------------------------------------------------------------------------------
+#if BLE_ENABLED
+void bleBuildData(bleData_t &bleData)
+{
+ bleData.applicationSpecificId = BLE_SERVICEID_GPSPLUS;
+ bleData.firmware = FW_VERSION;
+ //set flags
+ if (RET_motionTriggeredinFrame) {
+ set_8bit_flag(RET_bleAdv_flags, bleAdv_motionTriggeredinFrame_flag);
+ } else {
+ clr_8bit_flag(RET_bleAdv_flags, bleAdv_motionTriggeredinFrame_flag);
+ }
+ if (RET_motionState) {
+ set_8bit_flag(RET_bleAdv_flags, bleAdv_motionState_flag);
+ } else {
+ clr_8bit_flag(RET_bleAdv_flags, bleAdv_motionState_flag);
+ }
+ clr_8bit_flag(RET_bleAdv_flags, bleAdv_impact_flag);
+ bleData.flags = RET_bleAdv_flags;
+ bleData.voltage = uint16_t(RET_voltage * 100);
+ bleData.temperature = uint16_t(getTemperature() * 10);
+ bleData.humidity = 0xFF;
+ bleData.lux = 0xFF;
+ bleData.accel_x = 0xFF;
+ bleData.accel_y = 0xFF;
+ bleData.accel_z = 0xFF;
+ /*
+ bleData.id_1 = RET_pf_identifier[0]; //dont use this just stick it in the local name
+ bleData.id_2 = RET_pf_identifier[1];
+ bleData.id_3 = RET_pf_identifier[2];
+ bleData.id_4 = RET_pf_identifier[3];
+ bleData.id_5 = RET_pf_identifier[4];
+ bleData.id_6 = RET_pf_identifier[5];
+ */
+}
+void bleUpdateAndAdvertise(void)
+{
+ int AdvertisingInterval = (RET_setting_beacon_interval_seconds * 1000);
+ bleData_t bleData;
+ bleBuildData(bleData);
+ myble.gap().stopAdvertising();
+ myble.gap().setTxPower(DEFAULT_BEACON_POWER); // set tx power,valid values are -40, -20, -16, -12, -8, -4, 0, 4
+ myble.gap().accumulateAdvertisingPayloadTxPower(DEFAULT_BEACON_POWER); // (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm)
+ myble.gap().setAdvertisingInterval(AdvertisingInterval);
+ myble.gap().updateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)&bleData, sizeof(bleData_t));
+ //myble.gap().updateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&bleData, sizeof(bleData_t));
+ myble.gap().startAdvertising();
+ RET_bleBroadcasting = true;
+ if(RET_debug) {debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "BLE Adv Start");debug_exe();}
+}
+void bleSetupAdvertising(BLE::InitializationCompleteCallbackContext *params)
+{
+ if (RET_pf_identifier[0] != 0x00 && RET_pf_identifier[1] != 0x00 && RET_pf_identifier[2] != 0x00) {
+ bleData_t bleData;
+ bleBuildData(bleData);
+ char localname[6];
+ memcpy(localname,RET_pf_identifier,6);
+ myble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE );
+ myble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)localname, sizeof(localname));
+ myble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)&bleData, sizeof(bleData_t));
+ //myble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)&bleData, sizeof(bleData_t));
+ myble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
+ if(RET_debug) {debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "BLE Setup...");debug_exe();}
+ }
+}
+void bleStopAdvertising(void)
+{
+ myble.gap().stopAdvertising();
+ RET_bleBroadcasting = false;
+ if(RET_debug) {debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "BLE Adv Stop");debug_exe();}
+}
+void bleAdvertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
+ struct AdvertisingData_t {
+ uint8_t length;
+ GapAdvertisingData::DataType_t dataType;
+ uint8_t data[0];
+ } PACKED;
+ struct bleData_t {
+ uint16_t applicationSpecificId;
+ } PACKED;
+
+ //LOOKING FOR (SIAEC BETA)
+ //14f64b977c250854
+ //442ce31996801546
+
+ char beta_location_tag_0[17] = {'4','1','1','7','6','9','0','5','6','4','6','8','3','f','6','8',0x00}; //bens
+ char beta_location_tag_1[17] = {'1','4','f','6','4','b','9','7','7','c','2','5','0','8','5','4',0x00}; //singapore
+ char beta_location_tag_2[17] = {'4','4','2','c','e','3','1','9','9','6','8','0','1','5','4','6',0x00}; //singapore
+
+ //Portal demos
+ char beta_location_tag_3[17] = {'1','5','f','c','6','d','d','5','c','3','7','f','1','f','4','a',0x00};
+ char beta_location_tag_4[17] = {'b','a','a','e','c','d','6','8','b','d','7','e','e','a','6','5',0x00};
+ char beta_location_tag_5[17] = {'7','e','4','b','7','8','e','0','f','a','3','3','0','8','a','0',0x00};
+ char beta_location_tag_6[17] = {'e','1','1','3','c','d','e','a','a','e','f','f','1','4','d','9',0x00};
+ char beta_location_tag_7[17] = {'8','c','9','2','4','5','f','f','0','c','f','a','b','9','2','f',0x00};
+ char beta_location_tag_8[17] = {'0','7','e','9','9','1','d','3','b','e','b','6','4','0','4','8',0x00};
+ char beta_location_tag_9[17] = {'9','5','6','3','a','0','8','6','2','1','e','8','e','c','1','4',0x00};
+
+ //Search for the manufacturer specific data with matching application-ID
+ AdvertisingData_t *pAdvData;
+ for (size_t index = 0; index < params->advertisingDataLen; index += (pAdvData->length + 1)) {
+ pAdvData = (AdvertisingData_t *)¶ms->advertisingData[index];
+ const bleData_t *pbleData = (const bleData_t *)pAdvData->data;
+
+ //ESTIMOTE BEACON
+ //example data 020104 0303 9afe1716 9afe 22 02c887042a33f9f0 00efebc60146f8ffffffff //spaces just to show identifier
+
+ //BLE TYPE SWITCH
+ switch(pbleData->applicationSpecificId) {
+ case BLE_SERVICEID_PFBEACON1 :
+ {
+ char beacon_identifier[17];
+ snprintf(beacon_identifier, sizeof(beacon_identifier), "%02x%02x%02x%02x%02x%02x%02x%02x",
+ params->advertisingData[12],
+ params->advertisingData[13],
+ params->advertisingData[14],
+ params->advertisingData[15],
+ params->advertisingData[16],
+ params->advertisingData[17],
+ params->advertisingData[18],
+ params->advertisingData[19]);
+ //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), " Mac: [%02x%02x%02x%02x%02x%02x], rssi: %d, AType: %u, S: %04x, Id: %s",params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],params->rssi, params->type, pbleData->applicationSpecificId, beacon_identifier);debug_exe();}
+ //check to see if its one of the two location beta beacons we are looking for...
+ if (strcmp(beacon_identifier, beta_location_tag_0) == 0
+ || strcmp(beacon_identifier, beta_location_tag_1) == 0
+ || strcmp(beacon_identifier, beta_location_tag_2) == 0
+ || strcmp(beacon_identifier, beta_location_tag_3) == 0
+ || strcmp(beacon_identifier, beta_location_tag_4) == 0
+ || strcmp(beacon_identifier, beta_location_tag_5) == 0
+ || strcmp(beacon_identifier, beta_location_tag_6) == 0
+ || strcmp(beacon_identifier, beta_location_tag_7) == 0
+ || strcmp(beacon_identifier, beta_location_tag_8) == 0
+ || strcmp(beacon_identifier, beta_location_tag_9) == 0
+ ) {
+ //dump advertising data
+ //for (unsigned index = 0; index < params->advertisingDataLen; index++) { if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "%02x",params->advertisingData[index]);debug_exe(false);}}
+ //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), " MATCH");debug_exe();}
+ int tag_rssi = params->rssi * -1; //to convert to positive number
+ if (tag_rssi < RET_closestLocationTag_rssi) {
+ RET_closestLocationTag_rssi = tag_rssi;
+ memcpy(RET_closestLocationTag_id, beacon_identifier, sizeof(RET_closestLocationTag_id));
+ RET_locationTag_present = true;
+ //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Location Tag Present: %s, rssi: %d",closestLocationTag_id, closestLocationTag_rssi);debug_exe();}
+ }
+ }
+ break;
+ }
+ case BLE_SERVICEID_BT04 :
+ {
+ //nothing yet
+ break;
+ }
+ case BLE_SERVICEID_PFDETECTOR1 :
+ {
+ char ble_advdata[100];
+ snprintf(ble_advdata, sizeof(ble_advdata), "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ params->advertisingData[0],
+ params->advertisingData[1],
+ params->advertisingData[2],
+ params->advertisingData[3],
+ params->advertisingData[4],
+ params->advertisingData[5],
+ params->advertisingData[6],
+ params->advertisingData[7],
+ params->advertisingData[8],
+ params->advertisingData[9],
+ params->advertisingData[10],
+ params->advertisingData[11],
+ params->advertisingData[12],
+ params->advertisingData[13],
+ params->advertisingData[14],
+ params->advertisingData[15],
+ params->advertisingData[16],
+ params->advertisingData[17],
+ params->advertisingData[18],
+ params->advertisingData[19],
+ params->advertisingData[20]);
+ //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), " Mac: [%02x%02x%02x%02x%02x%02x], rssi: %d, AType: %u, Id: %s",params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],params->rssi, pAdvData->dataType, ble_advdata);debug_exe();}
+ //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Detector @rssi: %d",params->rssi);debug_exe();}
+ if (params->rssi >= -75) {
+ RET_detector_present = true;
+ }
+ break;
+ }
+ }
+ }
+}
+void bleConfigureScan(void)
+{
+ //configure scan
+ //myble.gap().setScanParams(60,30); //scan interval //scan window
+ myble.gap().setScanParams(100,100); //scan interval //scan window
+ myble.gap().startScan(bleAdvertisementCallback);
+}
+void bleStopScan(void)
+{
+ myble.gap().stopScan();
+}
+void bleShutdown(void)
+{
+ bleStopScan();
+ bleStopAdvertising();
+ myble.shutdown();
+}
+#endif
//------------------------------------------------------------------------------
// MOTION FUNCS
@@ -501,6 +662,9 @@
if (lis3dh_int2) {
RET_motionTriggeredinFrame = true;
GLOBAL_needToConfigureLis3dh = true; //interrupt has fire so need to clear it
+ if(RET_debug) {
+ LED1on(100);
+ }
if (!RET_motionPendingOnState) {
RET_motionPendingOnState = true;
RET_motionPendingOffState = false;
@@ -521,29 +685,35 @@
if (RET_motionPendingOnState) {
//check if above threshold
time_t inMotionForSeconds = ((RET_RTCunixtime - RET_motionStartTime) + (DEFAULT_SLEEP_FRAME / 1000)); //Plus DEFAULT_SLEEP_FRAME as it should include frame time
- if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "MOT:%u s",inMotionForSeconds);debug_exe();}
- if (inMotionForSeconds >= (RET_setting_motion_start_seconds + 15) && RET_motionState == false) {
+ if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "M:%u",inMotionForSeconds);debug_exe();}
+ if (inMotionForSeconds >= RET_setting_motion_start_seconds) {
+ //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "MotionOn");debug_exe();}
RET_motionState = true;
- RET_motionTriggeredInLocTXInterval = true;
- if (RET_setting_activity_mode == 2 && RET_setting_activity_tx_interval_hrs > 0) {
- time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60);
- sprintf(RET_activityData+strlen(RET_activityData),"1.%u!",epochOffsetMins);
+ RET_motionStateOnInLocTXInterval = true;
+ if (RET_motionState == false) { //If this is first after motionState 0
+ if (RET_setting_activity_mode == 2 && RET_setting_activity_tx_interval_hrs > 0) {
+ time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60);
+ sprintf(RET_activityData+strlen(RET_activityData),"1.%u!",epochOffsetMins);
+ }
}
}
}
if (RET_motionPendingOffState) {
time_t noMotionForSeconds = ((RET_RTCunixtime - RET_motionStopTime) + (DEFAULT_SLEEP_FRAME / 1000)); //Plus DEFAULT_SLEEP_FRAME as it should include frame time
- if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "MOTLESS:%u s",noMotionForSeconds);debug_exe();}
- if (noMotionForSeconds >= (RET_setting_motion_stop_seconds + 15) && RET_motionState == true) {
- RET_motionPendingOffState = false;
- RET_motionState = false;
- GLOBAL_motionStopFlagTriggered = true;
- if (RET_setting_activity_mode > 0 && RET_setting_activity_tx_interval_hrs > 0) {
- RET_motionTotalActivityHoursSincePost += ((float(RET_motionStopTime)-float(RET_motionStartTime)) / 3600.0f);
- RET_motionTotalActivityHours += RET_motionTotalActivityHoursSincePost;
- if (RET_setting_activity_mode == 2) {
- time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60);
- sprintf(RET_activityData+strlen(RET_activityData),"0.%u!",epochOffsetMins);
+ if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "NM:%u",noMotionForSeconds);debug_exe();}
+ if (noMotionForSeconds >= RET_setting_motion_stop_seconds) {
+ if (RET_motionState == true) {
+ RET_motionPendingOffState = false;
+ RET_motionState = false;
+ GLOBAL_motionStopFlagTriggered = true;
+ //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "MotionStop");debug_exe();}
+ if (RET_setting_activity_mode > 0 && RET_setting_activity_tx_interval_hrs > 0) {
+ RET_motionTotalActivityHoursSincePost += ((float(RET_motionStopTime)-float(RET_motionStartTime)) / 3600.0f);
+ RET_motionTotalActivityHours += RET_motionTotalActivityHoursSincePost;
+ if (RET_setting_activity_mode == 2) {
+ time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60);
+ sprintf(RET_activityData+strlen(RET_activityData),"0.%u!",epochOffsetMins);
+ }
}
}
}
@@ -595,7 +765,7 @@
if(TEMP_c != -1) { RET_setting_firmware = TEMP_c; } else { RET_setting_firmware = -1;}
if(TEMP_d != -1) { setState(TEMP_d); } else { setState(STATE_NORMAL);}
if(TEMP_e != -1) { RET_setting_location_mode = TEMP_e; }
- if(RET_setting_location_mode > 3) {RET_setting_location_mode = DEFAULT_LOCATION_MODE;}
+ if(RET_setting_location_mode > 4) {RET_setting_location_mode = DEFAULT_LOCATION_MODE;}
if(TEMP_f != -1) { RET_setting_location_accuracy = TEMP_f; }
if(RET_setting_location_accuracy > 3) {RET_setting_location_accuracy = DEFAULT_LOCATION_ACCURACY;}
if(TEMP_g != -1) { RET_setting_location_tx_interval_mins = TEMP_g; }
@@ -630,6 +800,9 @@
//Broadcast any activity data we have before fw update
event_activity_tx();
//prep for FW update
+ #if BLE_ENABLED
+ bleShutdown();
+ #endif
read_app_data_from_flash(&app_data);
clr_flag(&app_data, app_execution_flag);
clr_flag(&app_data, first_run_flag);
@@ -691,7 +864,7 @@
int timetaken = (RET_RTCunixtime - GLOBAL_wakeTime);
char bytestosend[100];
memset(bytestosend,0x00,sizeof(bytestosend));
- snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,v:%.2f,e:%d,z:%s.%s,c:1,s:0)\0",GLOBAL_defaultApi,FW_VERSION,RET_voltage,timetaken,error,GLOBAL_exceptionString);
+ snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,v:%.2f,e:%d,z:%s.%s,s:0)\0",GLOBAL_defaultApi,FW_VERSION,RET_voltage,timetaken,error,GLOBAL_exceptionString);
if (modem.on(RET_force2G)) {
if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,RET_setting_connection_timeout,RET_NetworkFailCount)) {
modem.USSDmessage(bytestosend, false, GLOBAL_defaultApi);
@@ -722,6 +895,9 @@
return;
}
void failed_broadcasts_tx() {
+ #if BLE_ENABLED
+ bleStopAdvertising();
+ #endif
//check we have something to send...
int numbertosend = 0;
for(int i = 0; i < sizeof(GLOBAL_failed_broadcast_slots); i++) {
@@ -751,6 +927,9 @@
}
}
bool event_setup(bool manualrun) {
+ #if BLE_ENABLED
+ bleStopAdvertising();
+ #endif
bool pass = false;
LED1on(0);
if (RET_NetworkFailCount > DEFAULT_MAX_FAILED_CONNECTIONS) addToExceptionString("NF");
@@ -767,7 +946,7 @@
int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
if (manualrun) addToExceptionString("MAN");
char bytestosend[160];
- snprintf(bytestosend,sizeof(bytestosend),"(%s,a:setup,f:%d,v:%.2f,t:%.1f,e:%d,y:%d,z:SETUP-%s,k:%s,m:%s,c:1,s:1)\0",GLOBAL_defaultApi,FW_VERSION,RET_voltage,RET_temperature,timetaken_total,timetaken_connection,GLOBAL_exceptionString,SKU,HW_MAJORREVISION);
+ snprintf(bytestosend,sizeof(bytestosend),"(%s,a:setup,f:%d,v:%.2f,t:%.1f,e:%d,y:%d,z:SETUP-%s,k:%s,m:%s,s:1)\0",GLOBAL_defaultApi,FW_VERSION,RET_voltage,RET_temperature,timetaken_total,timetaken_connection,GLOBAL_exceptionString,SKU,HW_MAJORREVISION);
char result[200];
snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytestosend, true, GLOBAL_defaultApi));
RET_setupInProgress = false; //this turns off the flashing led
@@ -796,10 +975,10 @@
if (pass == true) {
GLOBAL_wakeTime = RET_RTCunixtime; //lets reset this here so that the following loc and act function have sensible values for total time
//GET LOC DATA
- uint8_t previous_location_accuracy = RET_setting_location_accuracy;
- RET_setting_location_accuracy = 1; //set location mode to CL only
+ //uint8_t previous_location_accuracy = RET_setting_location_accuracy;
+ //RET_setting_location_accuracy = 1; //set location mode to CL only
event_location_tx(false);
- RET_setting_location_accuracy = previous_location_accuracy; //set location mode back to previous
+ //RET_setting_location_accuracy = previous_location_accuracy; //set location mode back to previous
//SEND ANY ACTIVITY DATA
event_activity_tx();
LED1blink(4,500); //PASS AND END
@@ -809,10 +988,14 @@
RET_SetupRunAt = RET_RTCunixtime;
RET_GPSFailCount = 0;
RET_NetworkFailCount = 0;
+ setEventTimes();
//RESULT
return pass;
}
void event_turnonofflog_tx(bool turnon) {
+ #if BLE_ENABLED
+ bleStopAdvertising();
+ #endif
RET_NetworkFailCount = 0; //reset network blocker
RET_GPSFailCount = 0;
updateBatteryV();
@@ -827,9 +1010,9 @@
int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
char bytestosend[160];
if (turnon) {
- snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,t:%.1f,v:%.2f,z:TURNON,e:%d,y:%d,x:%d,c:1,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,RET_temperature,RET_voltage,timetaken_total,timetaken_connection,timetaken_gps,locString);
+ snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,t:%.1f,v:%.2f,z:TURNON,e:%d,y:%d,x:%d,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,RET_temperature,RET_voltage,timetaken_total,timetaken_connection,timetaken_gps,locString);
} else {
- snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,t:%.1f,v:%.2f,z:TURNOFF,e:%d,y:%d,x:%d,c:1,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,RET_temperature,RET_voltage,timetaken_total,timetaken_connection,timetaken_gps,locString);
+ snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,t:%.1f,v:%.2f,z:TURNOFF,e:%d,y:%d,x:%d,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,RET_temperature,RET_voltage,timetaken_total,timetaken_connection,timetaken_gps,locString);
}
char result[180];
snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytestosend, false, GLOBAL_defaultApi));
@@ -837,57 +1020,111 @@
}
}
void event_location_tx(bool failsafe) {
+ #if BLE_ENABLED
+ bleStopAdvertising();
+ #endif
//check if we have any outstanding to send
failed_broadcasts_tx();
bool selfTestResult = selfTest();
+ bool skipTX = false;
char bytesToSend[160];
- //see if we are in range of ble detector, if so, no need to get gps and broadcast
- //Set any network or GPS fail flags
- if (RET_NetworkFailCount > DEFAULT_MAX_FAILED_CONNECTIONS) addToExceptionString("NF");
- if (RET_GPSFailCount > DEFAULT_MAX_FAILED_GPS) addToExceptionString("GF");
- //lets check to see if we've had repeated comms failings in this location, if so dont bother trying. reset by movment and timeout
- if (RET_NetworkFailCount <= DEFAULT_MAX_FAILED_CONNECTIONS) {
- if (RET_receivedNewSettings) {RET_receivedNewSettings = false; addToExceptionString("SR"); }
- if (modem.on(RET_force2G)) {
- char locString[70];
- int gpsStartTime = RET_RTCunixtime;
- memcpy(locString, modem.getLocation(RET_setting_location_accuracy, RET_setting_location_timeout, RET_GPSFailCount, RET_NetworkFailCount), sizeof(locString));
- int timetaken_gps = (RET_RTCunixtime - gpsStartTime);
-
- //SEND DATA
- int connectionStartTime = RET_RTCunixtime;
- if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,RET_setting_connection_timeout,RET_NetworkFailCount)) {
- int timetaken_total = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for avg ussd response time.
- int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
- //Check if we should wait for settings back
- bool getSettings = true;
- //work out if we need to get settings back
- if ( ((RET_RTCunixtime - RET_SettingsGotAt)/3600) < RET_setting_minimumupdate_hrs ) { getSettings = false; timetaken_total -= 10;} //remove the extra 10 seconds from times
- snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:loc,f:%d,t:%.1f,v:%.2f,z:LOC-%s,e:%d,y:%d,x:%d,j:%d,c:1,s:%d%s)\0",GLOBAL_defaultApi,FW_VERSION,RET_temperature,RET_voltage,GLOBAL_exceptionString,timetaken_total,timetaken_connection,timetaken_gps,RET_motionTriggeredInLocTXInterval,getSettings,locString);
- char result[180];
- snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getSettings, GLOBAL_defaultApi));
- if (getSettings == true && strcmp(result, "sendokrecfail") == 0) {
- //send ok but receive fail
- if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"USSD Send Ok but Rec fail");debug_exe();}
- sendErrorLog("ERR-LOC-NR");
- } else if (strcmp(result, "sendok") == 0) {
- //do nothing
- } else if (strcmp(result, "sendfail") == 0) {
- if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"USSD Send Fail");debug_exe();}
- //need to log for retry
+
+ //Check for Nearby Location Beacons
+ #if BLE_ENABLED
+ memset(RET_closestLocationTag_id, 0x00, sizeof(RET_closestLocationTag_id));
+ RET_closestLocationTag_rssi = 999;
+ RET_locationTag_present = false;
+ RET_detector_present = false;
+ if (RET_setting_beacon_scan == 1 && RET_setting_location_mode != LOCATION_MODE_REALTIME) {
+ LowPowerTimer bleScan_t;
+ bleScan_t.start();
+ uint32_t bleScan_startmillis = bleScan_t.read_ms(); uint32_t bleScan_runtime = 0;
+ if (!myble.hasInitialized()) {
+ myble.init();
+ while (!myble.hasInitialized() && bleScan_runtime < 1000) {
+ bleScan_runtime = (bleScan_t.read_ms() - bleScan_startmillis);
+ }
+ }
+ if (myble.hasInitialized()) {
+ //Scan for 10 seconds
+ bleConfigureScan();
+ bleScan_startmillis = bleScan_t.read_ms();
+ while (bleScan_runtime < 10000 && RET_detector_present == false) {
+ bleScan_runtime = (bleScan_t.read_ms() - bleScan_startmillis);
+ myble.waitForEvent(); // low power wait for event
+ }
+ //if (LocationTag_preset) if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "LocationTag: %s, rssi: %d",closestLocationTag_id, closestLocationTag_rssi);debug_exe();}
+ }
+ bleScan_t.stop();
+ myble.gap().stopScan();
+ }
+ //see if we are in range of ble detector, if so, no need to get gps and broadcast
+ if (RET_detector_present == true && RET_setting_beacon_interval_seconds > 0) {
+ skipTX = true;
+ }
+ #endif
+
+
+ if (skipTX == false || failsafe == true) {
+ //Set any network or GPS fail flags
+ if (RET_NetworkFailCount > DEFAULT_MAX_FAILED_CONNECTIONS) addToExceptionString("NF");
+ if (RET_GPSFailCount > DEFAULT_MAX_FAILED_GPS) addToExceptionString("GF");
+ //lets check to see if we've had repeated comms failings in this location, if so dont bother trying. reset by movment and timeout
+ if (RET_NetworkFailCount <= DEFAULT_MAX_FAILED_CONNECTIONS) {
+ if (RET_receivedNewSettings) {RET_receivedNewSettings = false; addToExceptionString("SR"); }
+ if (modem.on(RET_force2G)) {
+ char locString[70];
+ int gpsStartTime = RET_RTCunixtime;
+
+ //check if we have moved since last post, if not use same valid gps fix if exists
+ if (RET_motionStateOnInLocTXInterval == false && GLOBAL_have_GPSlocString_prev == true) {
+ memcpy(locString, GLOBAL_GPSlocString_prev, sizeof(locString));
+ addToExceptionString("P");
} else {
- if (getSettings) {
- if (saveSettings(result) == false){sendErrorLog("ERR-LOC-IR");}
+ memcpy(locString, modem.getLocation(RET_setting_location_accuracy, RET_setting_location_timeout, RET_GPSFailCount, RET_NetworkFailCount), sizeof(locString));
+ }
+
+ int timetaken_gps = (RET_RTCunixtime - gpsStartTime);
+
+ //SEND DATA
+ int connectionStartTime = RET_RTCunixtime;
+ if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,RET_setting_connection_timeout,RET_NetworkFailCount)) {
+ int timetaken_total = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for avg ussd response time.
+ int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
+ //Check if we should wait for settings back
+ bool getSettings = true;
+ //work out if we need to get settings back
+ if ( ((RET_RTCunixtime - RET_SettingsGotAt)/3600) < RET_setting_minimumupdate_hrs ) { getSettings = false; timetaken_total -= 10;} //remove the extra 10 seconds from times
+ snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:loc,f:%d,t:%.0f,n:%.0f,q:%.0f,v:%.1f,z:L%s,e:%d,y:%d,x:%d,j:%d,s:%d%s)\0",GLOBAL_defaultApi,FW_VERSION,RET_temperature,RET_temperature_min,RET_temperature_max,RET_voltage,GLOBAL_exceptionString,timetaken_total,timetaken_connection,timetaken_gps,RET_motionStateOnInLocTXInterval,getSettings,locString);
+ //snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:loc,f:%d,t:%.0f,v:%.1f,z:L-%s,e:%d,y:%d,x:%d,j:%d,s:%d%s)\0",GLOBAL_defaultApi,FW_VERSION,RET_temperature,RET_voltage,GLOBAL_exceptionString,timetaken_total,timetaken_connection,timetaken_gps,RET_motionStateOnInLocTXInterval,getSettings,locString);
+ char result[180];
+ snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getSettings, GLOBAL_defaultApi));
+ if (getSettings == true && strcmp(result, "sendokrecfail") == 0) {
+ //send ok but receive fail
+ if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"USSD Send Ok but Rec fail");debug_exe();}
+ //sendErrorLog("ERR-LOC-NR");
+ } else if (strcmp(result, "sendok") == 0) {
+ //do nothing
+ } else if (strcmp(result, "sendfail") == 0) {
+ if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"USSD Send Fail");debug_exe();}
+ //need to log for retry
+ } else {
+ if (getSettings) {
+ if (saveSettings(result) == false){sendErrorLog("ERR-LOC-IR");}
+ }
}
}
}
}
}
//RESETS
- RET_motionTriggeredInLocTXInterval = false;
+ RET_motionStateOnInLocTXInterval = false;
setEventTime_Location();
}
void event_activity_tx() {
+ #if BLE_ENABLED
+ bleStopAdvertising();
+ #endif
//check if we have any outstanding to send
failed_broadcasts_tx();
//check we have something to send...
@@ -896,9 +1133,9 @@
//Build data to send
char bytesToSend[160];
if (RET_setting_activity_mode == 1) {
- snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,t:%u,r:%.2f,h:%.2f,c:1)\0",GLOBAL_defaultApi,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost,RET_motionTotalActivityHours);
+ snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,t:%u,r:%.2f,h:%.2f)\0",GLOBAL_defaultApi,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost,RET_motionTotalActivityHours);
} else if (RET_setting_activity_mode == 2) {
- snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,e:%s,t:%u,r:%.2f,c:1)\0",GLOBAL_defaultApi,RET_activityData,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost);
+ snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,e:%s,t:%u,r:%.2f)\0",GLOBAL_defaultApi,RET_activityData,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost);
}
if (RET_NetworkFailCount <= DEFAULT_MAX_FAILED_CONNECTIONS) {
if (modem.on(RET_force2G)) {
@@ -937,48 +1174,6 @@
memset(RET_activityData,0x00,sizeof(RET_activityData));
setEventTime_Activity();
}
-/*
-void event_activity_tx() {
- bool sendok = false;
- //check if we have any outstanding to send
- failed_broadcasts_tx();
-
- //check we have something to send...
- if (RET_motionTotalActivityHoursSincePost > 0.0f && RET_setting_activity_mode > 0) {
- //Build data to send
- char bytesToSend[160];
- if (RET_setting_activity_mode == 1) {
- snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,t:%u,r:%.2f,h:%.2f,c:1)\0",GLOBAL_defaultApi,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost,RET_motionTotalActivityHours);
- } else if (RET_setting_activity_mode == 2) {
- snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,e:%s,t:%u,r:%.2f,c:1)\0",GLOBAL_defaultApi,RET_activityData,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost);
- }
- if (RET_NetworkFailCount <= DEFAULT_MAX_FAILED_CONNECTIONS) {
- if (modem.on(RET_force2G)) {
- //SEND DATA
- if (modem.registerOnNetwork(2,RET_setting_connection_timeout,RET_NetworkFailCount)) {
- char result[100];
- bool getResponse = false;
- snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getResponse, GLOBAL_defaultApi));
- if (strcmp(result, "sendok") == 0) {
- //sendok = true;
- if(!RET_debug) {sendok = true;}
- }
- }
- }
- modem.off(true);
- }
- //If send failed then log it for retry
- if (sendok == false) {
- failed_broadcast_log(bytesToSend);
- }
- }
- //RESETS
- RET_motionTotalActivityHoursSincePost = 0.0f;
- memset(RET_activityData,0x00,sizeof(RET_activityData));
- if (RET_haveSettings) { RET_motionFrameStart = RET_RTCunixtime; } //this is now safe to do as we are logging the fails
- setEventTime_Activity();
-}
-*/
//------------------------------------------------------------------------------
// STATE ENGINE
@@ -1018,27 +1213,27 @@
break;
case 2: //INTERVAL POST WITH MOTION CHECK
if(RET_RTCunixtime >= RET_eventTime_location_tx && RET_eventTime_location_tx > 0) {
- if (RET_motionTriggeredInLocTXInterval == true) {
+ if (RET_motionStateOnInLocTXInterval == true || RET_motionState == true) {
run_location_tx = true;
} else {
- if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Skip TX no mot\n");debug_exe();}
+ if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Skip TX no mot\n");debug_exe();}
}
}
break;
case 3: //POST ON STOP MOTION
- if (GLOBAL_motionStopFlagTriggered) { run_location_tx = true; GLOBAL_motionStopFlagTriggered = false; }
+ if (GLOBAL_motionStopFlagTriggered) { GLOBAL_motionStopFlagTriggered = false; run_location_tx = true; }
break;
}
if(RET_RTCunixtime >= RET_eventTime_location_failsafe_tx && RET_eventTime_location_failsafe_tx > 0) {
RET_NetworkFailCount = 0; //reset to ensure connection
RET_GPSFailCount = 0; // reset to ensure gps try
+ addToExceptionString("FS");
updateBatteryV();
event_location_tx(true);
} else {
if (run_location_tx) { updateBatteryV(); event_location_tx(false); }
}
-
//ACTIVITY EVENT
bool run_activity_tx = false;
if(RET_RTCunixtime >= RET_eventTime_activity_tx && RET_eventTime_activity_tx > 0) {
@@ -1179,7 +1374,7 @@
//INIT
LED1off();
ThisThread::sleep_for(2000); //Initial pause, this is needed for softdevice to init, dont remove!! If we dont have this we get crashes
- watchdog.configure(300.0); //5 mins
+ watchdog.configure(300.0); //5 mins //Do not set to less than 4500ms or can cause issues with softdevice
modem.off(false);
RTCticker.attach(&RTCtick, 1.0);
LPtimer.start();
@@ -1194,54 +1389,42 @@
RET_coldBoot = 1;
switch(NRF_POWER->RESETREAS) {
case 0x00000001 :
- //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:HW\n");debug_exe();}
+ if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:HW\n");debug_exe();}
break;
case 0x00000002 :
- //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:WD\n");debug_exe();}
+ if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:WD\n");debug_exe();}
break;
case 0x00000004 :
- //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:SW\n");debug_exe();}
+ if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:SW\n");debug_exe();}
break;
case 0x00000008 :
- //if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:LU\n");debug_exe();}
+ if(RET_debug){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer),"RR:LU\n");debug_exe();}
break;
}
NRF_POWER->RESETREAS = 0xffffffff;
- } else {
- //if its not one of these reasons then its a power-on or a brown-out
- //if(get_flag(&app_data, app_execution_flag) == false) {
- //THIS is a unexpected reset / brownout???
- //}
}
//CHECK FOR FIRST BOOT
- if (RET_coldBoot == 1) {
- setDefaults();
- //check battery
+ if (RET_coldBoot == 1) {
+ memset(RET_activityData,0x00,sizeof(RET_activityData));
+ lis3dh_configureForSleep(DEFAULT_MOTION_G,DEFAULT_IMPACT_G);
updateBatteryV();
- if (RET_voltage < 2.5f) {
- //battery low
- LED1errorCode(10,2);
- }
+ if (RET_voltage < 2.5f) { LED1errorCode(10,2);}
addToExceptionString("FR");
}
//MAIN LOOP
- while(true) {
- //WATCHDOG
- watchdogKick();
+ while(true) {
RET_asleep = false;
+ watchdogKick();
updateTemperatures();
-
- //INIT
- resetGlobals();
+ resetSessionVars();
healthCheck(); //this must be after resetGlobals
GLOBAL_wakeTime = RET_RTCunixtime;
//check and log motion
if (RET_state == STATE_NORMAL || RET_state == STATE_SETUP) {
- if (checkMotion() == true) {
- //if motionstate is true, then reset network and gps fail counts, so that they are not skipped
+ if (checkMotion() == true) { //if motionstate is true, then reset network and gps fail counts, so that they are not skipped
RET_NetworkFailCount = 0;
RET_GPSFailCount = 0;
}
@@ -1250,7 +1433,7 @@
//MAIN LOGIC
if(RET_debug){
if (RET_state != 99) {
- debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "F:%d, S:%d, SET:%d, MF:%d, MS:%d, MTX:%d, %u, L:%u, LFS:%u, A:%u", FW_VERSION, RET_state, RET_haveSettings, RET_motionTriggeredinFrame, RET_motionState, RET_motionTriggeredInLocTXInterval, RET_RTCunixtime,RET_eventTime_location_tx,RET_eventTime_location_failsafe_tx,RET_eventTime_activity_tx);debug_exe();
+ debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "F:%d, S:%d, SET:%d, MF:%d, MS:%d, MTX:%d, %u, L:%u, LFS:%u, A:%u", FW_VERSION, RET_state, RET_haveSettings, RET_motionTriggeredinFrame, RET_motionState, RET_motionStateOnInLocTXInterval, RET_RTCunixtime,RET_eventTime_location_tx,RET_eventTime_location_failsafe_tx,RET_eventTime_activity_tx);debug_exe();
debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "ACT M:%d, HsP:%.2f, Ht:%.2f, D:%s",RET_setting_activity_mode,RET_motionTotalActivityHoursSincePost,RET_motionTotalActivityHours,RET_activityData);debug_exe();
} else {
debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "F:%d, S:%d, WAKE@:%u\n", FW_VERSION, RET_state, RET_eventTime_wakeFromDormant);debug_exe();
@@ -1270,19 +1453,35 @@
RET_coldBoot = 0;
}
+ //CONFIGURE BLE BEACON BROADCAST
+ #if BLE_ENABLED
+ //see if we are in range of ble detector, if so, no need to get gps and broadcast
+ if (RET_setting_beacon_interval_seconds > 0 && RET_pf_identifier[0] != 0x00 && RET_pf_identifier[1] != 0x00 && RET_pf_identifier[2] != 0x00) {
+ if (RET_bleBroadcasting == false) {
+ if(RET_debug) {debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "BLE init...");debug_exe();}
+ myble.init(bleSetupAdvertising);
+ if (myble.hasInitialized()) {
+ if(RET_debug) {debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "OK");debug_exe();}
+ bleUpdateAndAdvertise();
+ } else {
+ if(RET_debug) {debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "FAIL");debug_exe();}
+ }
+ } else {
+ if(RET_debug) {debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "BLE update");debug_exe();}
+ bleUpdateAndAdvertise();
+ }
+ } else {
+ if (RET_bleBroadcasting == true) bleStopAdvertising();
+ }
+ #endif
+
//PRE-SLEEP ACTIONS
LED1off();
- if (GLOBAL_modemOn) {
- modem.off(true); //SOFT SHUT DOWN - THIS IS THE ONLY MODEM OFF, DONT REMOVE
- } else {
- modem.off(false); //HARD SHUT DOWN - THIS IS THE ONLY MODEM OFF, DONT REMOVE
- }
- RET_motionTriggeredinFrame = false;
+ modem.off(GLOBAL_modemOn); //HARD OR SOFT SHUT DOWN - DEPENDING ON modemOn state
if (GLOBAL_needToConfigureLis3dh) { lis3dh_configureForSleep(RET_setting_motion_g,RET_setting_impact_g); }
nrf_configureForSleep();
NRFuart_uninit();
watchdogKick();
-
//SLEEP
RET_asleep = true;
mainthread.wait(DEFAULT_SLEEP_FRAME);