init
Dependencies: aconno_I2C Lis2dh12 WatchdogTimer
Diff: main.cpp
- Revision:
- 9:b0a1535b8ef2
- Parent:
- 8:7351f8c4cd60
- Child:
- 10:c8798fd9773b
--- a/main.cpp Tue Dec 11 22:38:25 2018 +0000
+++ b/main.cpp Sat Dec 15 13:45:28 2018 +0000
@@ -10,23 +10,26 @@
static void buttonRelease(void);
//------------------------------------------------------------------------------
-//GLOBAL VARS
+//GLOBAL VARS / CLEARED ON SLEEP (IF USING SOFT REBOOT HACK)
//------------------------------------------------------------------------------
bool accel_healthy = false;
-bool firstBoot = false;
bool requireSoftReset = false;
bool motionFlagTriggered = false;
+bool debugLED = false;
//------------------------------------------------------------------------------
//RETAINED NOINIT RAM VARS
//------------------------------------------------------------------------------
#if defined ( __CC_ARM ) /** THIS IS THE MBED ONLINE COMPILER TOOLCHAIN*/
+static uint8_t RET_coldBoot __attribute__((section("noinit"),zero_init));
static uint8_t RET_mode __attribute__((section("noinit"),zero_init));
-
-static uint8_t RET_buttonReleaseCount __attribute__((section("noinit"),zero_init));
-static uint32_t RET_buttonPressTime __attribute__((section("noinit"),zero_init));
-static uint32_t RET_buttonReleaseTime __attribute__((section("noinit"),zero_init));
-static uint32_t RET_unixtime_backup __attribute__((section("noinit"),zero_init));
+static uint8_t RET_mode_prev __attribute__((section("noinit"),zero_init));
+static uint8_t RET_buttonPressCount __attribute__((section("noinit"),zero_init));
+static time_t RET_buttonPressTime __attribute__((section("noinit"),zero_init));
+static time_t RET_buttonReleaseTime __attribute__((section("noinit"),zero_init));
+static time_t RET_buttonHoldTime __attribute__((section("noinit"),zero_init));
+static time_t RET_RTCunixtime __attribute__((section("noinit"),zero_init));
+static long RET_RTCmicros __attribute__((section("noinit"),zero_init));
static bool RET_requireImpactFlag __attribute__((section("noinit"),zero_init));
static char RET_buffer[64] __attribute__((section("noinit"),zero_init));
@@ -34,62 +37,117 @@
static bool RET_motionTriggered __attribute__((section("noinit"),zero_init));
static time_t RET_motionStartTime __attribute__((section("noinit"),zero_init));
static time_t RET_motionStopTime __attribute__((section("noinit"),zero_init));
-static uint32_t RET_motionStartThreshold_seconds __attribute__((section("noinit"),zero_init));
-static uint32_t RET_motionStopThreshold_seconds __attribute__((section("noinit"),zero_init));
+static time_t RET_motionStartThreshold_seconds __attribute__((section("noinit"),zero_init));
+static time_t RET_motionStopThreshold_seconds __attribute__((section("noinit"),zero_init));
static bool RET_motionPendingOnState __attribute__((section("noinit"),zero_init));
static bool RET_motionPendingOffState __attribute__((section("noinit"),zero_init));
static bool RET_motionState __attribute__((section("noinit"),zero_init));
+static float RET_motionTotalActivityHours __attribute__((section("noinit"),zero_init));
+static char RET_motionData[100] __attribute__((section("noinit"),zero_init));
//EVENT HANDLING
-static uint32_t RET_eventTime_location __attribute__((section("noinit"),zero_init));
-static uint32_t RET_eventTime_environmental __attribute__((section("noinit"),zero_init));
-static uint32_t RET_eventTime_activity __attribute__((section("noinit"),zero_init));
+static time_t RET_eventTime_location_log __attribute__((section("noinit"),zero_init));
+static time_t RET_eventTime_location_bc __attribute__((section("noinit"),zero_init));
+static time_t RET_eventTime_environmental_log __attribute__((section("noinit"),zero_init));
+static time_t RET_eventTime_environmental_bc __attribute__((section("noinit"),zero_init));
+static time_t RET_eventTime_activity_bc __attribute__((section("noinit"),zero_init));
+static time_t RET_eventTime_wakeFromDormant __attribute__((section("noinit"),zero_init));
#elif defined ( __GNUC__ )
#elif defined ( __ICCARM__ )
#endif
//------------------------------------------------------------------------------
+//GPIO
+//------------------------------------------------------------------------------
+InterruptIn button(PN_IN_BUTTON); //This causes wake from sleep
+
+//------------------------------------------------------------------------------
//PERIPHERALS
//------------------------------------------------------------------------------
//BLE myble;
WatchdogTimer watchdog(65.0); //Do not set to less than 4500ms or can cause issues with softdevice
-InterruptIn button(PN_IN_BUTTON); //This causes wake from sleep
#if NEED_CONSOLE_OUTPUT
Serial uart(PN_UART_TX, PN_UART_RX, 115200);
#endif
//------------------------------------------------------------------------------
+//TIMERS
+//------------------------------------------------------------------------------
+LowPowerTicker RTCticker; //no impact on power consumption
+
+//------------------------------------------------------------------------------
+//THREAD SEMAPHORES
+//------------------------------------------------------------------------------
+Semaphore mainthread;
+
+//------------------------------------------------------------------------------
//SINGLETONS
//------------------------------------------------------------------------------
//NVStore &nvstore = NVStore::get_instance();
-
//------------------------------------------------------------------------------
-// LOW LEVEL CRITICAL FUNCS
+// LOW LEVEL FUNCS
//------------------------------------------------------------------------------
+void turnOffEverything() {
+ //vreg_en = 0;
+ LED1off();
+}
void gotoSleep(long sleep_milliseconds) {
-
+ turnOffEverything();
+ watchdog.kick();
if (requireSoftReset) { //dont need to clear this var as reset changes it back to false
- RET_unixtime_backup = time(NULL); //save unixtime for reset
system_reset();
}
-
- //button.fall(&buttonPress);
- //button.rise(&buttonRelease);
-
- ThisThread::sleep_for(sleep_milliseconds);
+ mainthread.wait(sleep_milliseconds);
}
-
+void RTCtick() {
+ //RET_unixtime ++;
+ RET_RTCmicros += 100;
+ RET_RTCunixtime = (RET_RTCmicros / 1000);
+ //button logic - check for hold
+ if (RET_buttonHoldTime > 4000) {
+ RET_buttonHoldTime = 0;
+ RET_buttonPressCount = 0;
+ RET_mode_prev = RET_mode;
+ RET_mode = MODE_BUTTONHOLD;
+ mainthread.release();
+ } else {
+ if((RET_RTCmicros - RET_buttonPressTime) > 500) {
+ switch (RET_buttonPressCount) {
+ case 1 :
+ RET_mode_prev = RET_mode;
+ RET_mode = MODE_BUTTONPRESS1;
+ mainthread.release();
+ break;
+ case 2 :
+ RET_mode_prev = RET_mode;
+ RET_mode = MODE_BUTTONPRESS2;
+ mainthread.release();
+ break;
+ default :
+ //do nothing
+ break;
+ }
+ RET_buttonPressCount = 0;
+ }
+ }
+}
void factoryReset() {
- firstBoot = true;
+ //firstBoot = true;
+ requireSoftReset = false;
- //RESET VARS
- RET_mode = 0;
- RET_unixtime_backup = 0;
- RET_buttonReleaseCount = 0;
- RET_eventTime_location = 0;
- RET_eventTime_environmental = 0;
- RET_eventTime_activity = 0;
+ //RESET RETAINED VARS
+ RET_coldBoot = 1;
+ RET_mode = MODE_NORMAL;
+ RET_mode_prev = RET_mode;
+ RET_RTCunixtime = 0;
+ RET_RTCmicros = 0;
+ RET_eventTime_location_log = 0;
+ RET_eventTime_location_bc = 0;
+ RET_eventTime_environmental_log = 0;
+ RET_eventTime_environmental_bc = 0;
+ RET_eventTime_activity_bc = 0;
+ RET_eventTime_wakeFromDormant = 0;
RET_motionPendingOffState = 0;
RET_motionPendingOnState = 0;
RET_motionState = 0;
@@ -97,127 +155,133 @@
RET_motionStopTime = 0;
RET_motionStartThreshold_seconds = 60;
RET_motionStopThreshold_seconds = 60;
- set_time(RET_unixtime_backup);
+ RET_motionTotalActivityHours = 0.0;
+ RET_buttonPressTime = 0;
+ RET_buttonPressCount = 0;
+ RET_buttonHoldTime = 0;
//SET IDENTIFIER
//uint32_t nv_value = 12345678;
//int rc = nvstore.set(NV_IDENTIFIER, sizeof(nv_value), &nv_value);
}
-
-void turnOffEverything() {
- //vreg_en = 0;
- led1 = 1;
-}
-
-//------------------------------------------------------------------------------
-// USER BUTTON
-//------------------------------------------------------------------------------
-void buttonPress() {
- led1 = 0;
-
- //while(RET_buttonReleaseCount < 1){
- //wait
- //}
-
- //led1 = 1;
- /*
- //RET_buttonPressTime = time(NULL);
- RET_buttonReleaseCount ++;
- led1 = 0;
- for (int i = 0; i < RET_buttonReleaseCount; i++) {
- led1 = 0;
- wait_ms(100);
- led1 = 1;
- wait_ms(100);
- */
-}
-void buttonRelease() {
- led1 = 1;
- //RET_buttonReleaseCount ++;
- /*RET_buttonReleaseCount ++;
- led1 = 0;
- for (int i = 0; i < RET_buttonReleaseCount; i++) {
- led1 = 0;
- wait_ms(100);
- led1 = 1;
- wait_ms(100);
- }*/
-}
-
-bool selfTest() {
+void selfTest() {
//Accelerometer
LIS3DH lis3dh(PN_SPI_MOSI, PN_SPI_MISO, PN_SPI_CS0, PN_SPI_CLK);
uint8_t lis3dh_id;
lis3dh.LIS3DH_GetWHO_AM_I(&lis3dh_id);
- if (asdf == 51) {
- LED1blink(10,100);
- }
+ if (lis3dh_id == 51) {
+ LED1blink(10,50);
+ }
+}
+
+//------------------------------------------------------------------------------
+// USER BUTTON HANDLING
+//------------------------------------------------------------------------------
+void buttonPress() {
+ RET_buttonPressTime = RET_RTCmicros;
+}
+void buttonRelease() {
+ RET_buttonHoldTime = (RET_RTCmicros - RET_buttonPressTime);
+ //debounce catch
+ if((RET_RTCmicros - RET_buttonPressTime) >= 100) {
+ RET_buttonPressCount ++;
+ }
+}
+
+//------------------------------------------------------------------------------
+// MOTION FUNCS
+//------------------------------------------------------------------------------
+void checkMotion() {
+ if (lis3dh_int2) {
+ if (debugLED) LED1blink(2,100);
+ RET_motionTriggered = true;
+ if (!RET_motionPendingOnState) {
+ RET_motionPendingOnState = true;
+ RET_motionPendingOffState = false;
+ // Log start motion time
+ RET_motionStartTime = time(NULL);
+ }
+ } else {
+ if (debugLED) LED1blink(2,500);
+ RET_motionTriggered = false;
+ RET_motionPendingOnState = false;
+ if (!RET_motionPendingOffState) {
+ RET_motionPendingOffState = true;
+ //log stop motion time
+ RET_motionStopTime = time(NULL);
+ }
+ }
+ //calculate motion state
+ if (RET_motionPendingOnState) {
+ //check if above threshold
+ time_t inMotionForSeconds = (time(NULL) - RET_motionStartTime);
+ if (inMotionForSeconds >= RET_motionStartThreshold_seconds) {
+ RET_motionState = true;
+ if (debugLED) LED1blink(10,100);
+ }
+ }
+ if (RET_motionPendingOffState) {
+ time_t noMotionForSeconds = (time(NULL) - RET_motionStopTime);
+ if (noMotionForSeconds >= RET_motionStartThreshold_seconds) {
+ RET_motionState = false;
+ RET_motionTotalActivityHours += (float(RET_motionStopTime - RET_motionStartTime) / 3600.0);
+ if (debugLED) LED1blink(5,500);
+ }
+ }
}
//------------------------------------------------------------------------------
// STATE ENGINE
//------------------------------------------------------------------------------
-
void mainStateEngine() {
-
- RET_mode = MODE_NORMAL;
-
switch(RET_mode) {
case MODE_SETUP :
factoryReset();
//selftest();
break;
-
case MODE_NORMAL :
//check and log motion
- if (lis3dh_int1) {
- LED1blink(2,100);
- RET_motionTriggered = true;
- if (!RET_motionPendingOnState) {
- RET_motionPendingOnState = true;
- RET_motionPendingOffState = false;
- // Log start motion time
- RET_motionStartTime = time(NULL);
- RET_motionStopTime = 0;
- }
- } else {
- LED1blink(2,500);
- RET_motionTriggered = false;
- RET_motionPendingOnState = false;
- if (!RET_motionPendingOffState) {
- RET_motionPendingOffState = true;
- //log stop motion time
- RET_motionStopTime = time(NULL);
- RET_motionStartTime = 0;
- }
+ checkMotion();
+
+ //EVENTS
+ //Location
+ if(time(NULL) > RET_eventTime_location_log && RET_eventTime_location_log > 0) {
+ //getdata_environmental();
+ //event_location_log();
+ }
+ if(time(NULL) > RET_eventTime_location_bc && RET_eventTime_location_bc > 0) {
+ //getdata_battery();
+ //event_location_broadcast();
+ }
+ //Environmental
+ if(time(NULL) > RET_eventTime_environmental_log && RET_eventTime_environmental_log > 0) {
+ //event_environmental_log();
+ }
+ if(time(NULL) > RET_eventTime_environmental_bc && RET_eventTime_environmental_bc > 0) {
+ //event_environmental_bc();
}
- //calculate motion state
- if (RET_motionPendingOnState) {
- //check if above threshold
- time_t inMotionForSeconds = (time(NULL) - RET_motionStartTime);
- if (inMotionForSeconds >= RET_motionStartThreshold_seconds) {
- RET_motionState = true;
- LED1blink(10,100);
- }
+ //Activity
+ if(time(NULL) > RET_eventTime_activity_bc && RET_eventTime_activity_bc > 0) {
+ //event_activity_bc();
+ }
+ break;
+ case MODE_DORMANT :
+ if (time(NULL) > RET_eventTime_wakeFromDormant) {
+ RET_mode = MODE_NORMAL;
}
- if (RET_motionPendingOffState) {
- time_t noMotionForSeconds = (time(NULL) - RET_motionStopTime);
- if (noMotionForSeconds >= RET_motionStartThreshold_seconds) {
- RET_motionState = false;
- LED1blink(5,500);
- }
- }
-
+ break;
+ case MODE_BUTTONPRESS1 :
+ LED1blink(2,300);
+ RET_mode = RET_mode_prev;
+ break;
+ case MODE_BUTTONPRESS2 :
+ LED1blink(4,300);
+ RET_mode = RET_mode_prev;
+ break;
+ case MODE_BUTTONHOLD :
+ LED1blink(10,300);
+ RET_mode = RET_mode_prev;
break;
-
- case MODE_DORMANT :
- //LIS3DH lis3dh(PN_SPI_MOSI, PN_SPI_MISO, PN_SPI_CS0, PN_SPI_CLK);
- break;
-
- case MODE_OFF_48HRS :
-
- break;
-
default :
RET_mode = MODE_SETUP;
}
@@ -229,7 +293,12 @@
//------------------------------------------------------------------------------
int main() {
+ RTCticker.attach(&RTCtick, 0.1);
+ turnOffEverything();
+ button.fall(&buttonPress); //does this affect power?
+ button.rise(&buttonRelease);
+
//CHECK IF THIS IS RESET
//0x00000004 == soft reset //0x00000002 == watchdog //0x00000001 == button/hardreset
if (NRF_POWER->RESETREAS != 0xffffffff) {
@@ -240,30 +309,41 @@
break;
case 0x00000002 :
DEBUG("reset_reason: 0x%08x. - Watchdog\n",NRF_POWER->RESETREAS);
- set_time(RET_unixtime_backup);
break;
case 0x00000004 :
DEBUG("reset_reason: 0x%08x. - Soft reset\n",NRF_POWER->RESETREAS);
- set_time(RET_unixtime_backup);
break;
}
NRF_POWER->RESETREAS = 0xffffffff;
}
-
+ //CHECK FOR FIRST BOOT
+ if (RET_coldBoot != 0) factoryReset();
+
while(true) {
- turnOffEverything();
+ //SLEEP
+ if (RET_coldBoot != 1) gotoSleep(30000); //THIS HAS TO BE THE FIRST ITEM IN THE MAIN LOOP
watchdog.kick();
+
+ //MAIN LOGIC
+ DEBUG("mode: %i time: %i, %i, %i, %i \n", RET_mode, RET_RTCmicros, RET_RTCunixtime, RET_buttonHoldTime, RET_buttonPressCount);
+ mainStateEngine();
+
+ //PRE-SLEEP ACTIONS
+ lis3dh_configureForSleep(10,127);
+ RET_coldBoot = 0;
+
+
+ /*
firstBoot = false; //temp
if (!firstBoot) gotoSleep(10000);
//INIT
- Modem modem(PN_UART_TX, PN_UART_RX, PN_UART_CTS, PN_UART_RTS, PN_GSM_PWR_KEY, PN_VREG_EN);
+ //Modem modem(PN_UART_TX, PN_UART_RX, PN_UART_CTS, PN_UART_RTS, PN_GSM_PWR_KEY, PN_VREG_EN);
//MAIN STATE ENGINE
- //LED1blink(1,100);
- mainStateEngine();
//Configure for sleep
- lis3dh_configureForSleep(10);
+ lis3dh_configureForSleep(10,127);
+ */
}
}
\ No newline at end of file