enter deep sleep as soon as we send one packet
This commit is contained in:
parent
a35c6dcbe9
commit
8863cb7d5c
186
main/main.ino
186
main/main.ino
@ -36,6 +36,8 @@ String baChStatus = "No charging";
|
|||||||
bool ssd1306_found = false;
|
bool ssd1306_found = false;
|
||||||
bool axp192_found = false;
|
bool axp192_found = false;
|
||||||
|
|
||||||
|
bool packetSent, packetQueued;
|
||||||
|
|
||||||
#if defined(PAYLOAD_USE_FULL)
|
#if defined(PAYLOAD_USE_FULL)
|
||||||
// includes number of satellites and accuracy
|
// includes number of satellites and accuracy
|
||||||
static uint8_t txBuffer[10];
|
static uint8_t txBuffer[10];
|
||||||
@ -54,24 +56,37 @@ esp_sleep_source_t wakeCause; // the reason we booted this time
|
|||||||
|
|
||||||
void buildPacket(uint8_t txBuffer[]); // needed for platformio
|
void buildPacket(uint8_t txBuffer[]); // needed for platformio
|
||||||
|
|
||||||
void send() {
|
/**
|
||||||
char buffer[40];
|
* If we have a valid position send it to the server.
|
||||||
snprintf(buffer, sizeof(buffer), "Latitude: %10.6f\n", gps_latitude());
|
* @return true if we decided to send.
|
||||||
screen_print(buffer);
|
*/
|
||||||
snprintf(buffer, sizeof(buffer), "Longitude: %10.6f\n", gps_longitude());
|
bool trySend() {
|
||||||
screen_print(buffer);
|
packetSent = false;
|
||||||
snprintf(buffer, sizeof(buffer), "Error: %4.2fm\n", gps_hdop());
|
if (0 < gps_hdop() && gps_hdop() < 50 && gps_latitude() != 0 && gps_longitude() != 0)
|
||||||
screen_print(buffer);
|
{
|
||||||
|
char buffer[40];
|
||||||
|
snprintf(buffer, sizeof(buffer), "Latitude: %10.6f\n", gps_latitude());
|
||||||
|
screen_print(buffer);
|
||||||
|
snprintf(buffer, sizeof(buffer), "Longitude: %10.6f\n", gps_longitude());
|
||||||
|
screen_print(buffer);
|
||||||
|
snprintf(buffer, sizeof(buffer), "Error: %4.2fm\n", gps_hdop());
|
||||||
|
screen_print(buffer);
|
||||||
|
|
||||||
buildPacket(txBuffer);
|
buildPacket(txBuffer);
|
||||||
|
|
||||||
#if LORAWAN_CONFIRMED_EVERY > 0
|
#if LORAWAN_CONFIRMED_EVERY > 0
|
||||||
bool confirmed = (count % LORAWAN_CONFIRMED_EVERY == 0);
|
bool confirmed = (count % LORAWAN_CONFIRMED_EVERY == 0);
|
||||||
#else
|
#else
|
||||||
bool confirmed = false;
|
bool confirmed = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ttn_send(txBuffer, sizeof(txBuffer), LORAWAN_PORT, confirmed);
|
packetQueued = true;
|
||||||
|
ttn_send(txBuffer, sizeof(txBuffer), LORAWAN_PORT, confirmed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep() {
|
void sleep() {
|
||||||
@ -115,9 +130,11 @@ void callback(uint8_t message) {
|
|||||||
if (EV_PENDING == message) screen_print("Message discarded\n");
|
if (EV_PENDING == message) screen_print("Message discarded\n");
|
||||||
if (EV_QUEUED == message) screen_print("Message queued\n");
|
if (EV_QUEUED == message) screen_print("Message queued\n");
|
||||||
|
|
||||||
if (EV_TXCOMPLETE == message) {
|
// We only want to say 'packetSent' for our packets (not packets needed for joining)
|
||||||
|
if (EV_TXCOMPLETE == message && packetQueued) {
|
||||||
screen_print("Message sent\n");
|
screen_print("Message sent\n");
|
||||||
sleep();
|
packetQueued = false;
|
||||||
|
packetSent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EV_RESPONSE == message) {
|
if (EV_RESPONSE == message) {
|
||||||
@ -234,41 +251,6 @@ void axp192Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void doDeepSleep()
|
|
||||||
{
|
|
||||||
#if DEEPSLEEP_INTERVAL
|
|
||||||
uint64_t msecToWake = DEEPSLEEP_INTERVAL;
|
|
||||||
Serial.printf("Entering deep sleep %llu\n", msecToWake);
|
|
||||||
|
|
||||||
// not using wifi yet, but once we are this is needed to shutoff the radio hw
|
|
||||||
// esp_wifi_stop();
|
|
||||||
|
|
||||||
screen_off(); // datasheet says this will draw only 10ua
|
|
||||||
LMIC_shutdown(); // cleanly shutdown the radio
|
|
||||||
|
|
||||||
if(axp192_found) {
|
|
||||||
// turn on after initial testing with real hardware
|
|
||||||
// axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // LORA radio
|
|
||||||
// axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // GPS main power
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME - use an external 10k pulldown so we can leave the RTC peripherals powered off
|
|
||||||
// until then we need the following lines
|
|
||||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
|
||||||
|
|
||||||
// Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39.
|
|
||||||
uint64_t gpioMask = (1ULL << BUTTON_PIN);
|
|
||||||
|
|
||||||
// FIXME change polarity so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of just the first)
|
|
||||||
gpio_pullup_en((gpio_num_t) BUTTON_PIN);
|
|
||||||
|
|
||||||
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
|
|
||||||
|
|
||||||
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
|
|
||||||
esp_deep_sleep_start(); // TBD mA sleep current (battery)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform power on init that we do on each wake from deep sleep
|
// Perform power on init that we do on each wake from deep sleep
|
||||||
void initDeepSleep() {
|
void initDeepSleep() {
|
||||||
bootCount++;
|
bootCount++;
|
||||||
@ -313,7 +295,10 @@ void setup() {
|
|||||||
DEBUG_MSG(APP_NAME " " APP_VERSION "\n");
|
DEBUG_MSG(APP_NAME " " APP_VERSION "\n");
|
||||||
|
|
||||||
// Don't init display if we don't have one or we are waking headless due to a timer event
|
// Don't init display if we don't have one or we are waking headless due to a timer event
|
||||||
if(ssd1306_found && wakeCause != ESP_SLEEP_WAKEUP_TIMER)
|
if(wakeCause == ESP_SLEEP_WAKEUP_TIMER)
|
||||||
|
ssd1306_found = false; // forget we even have the hardware
|
||||||
|
|
||||||
|
if(ssd1306_found)
|
||||||
screen_setup();
|
screen_setup();
|
||||||
|
|
||||||
// Init GPS
|
// Init GPS
|
||||||
@ -340,20 +325,92 @@ void setup() {
|
|||||||
ttn_adr(LORAWAN_ADR);
|
ttn_adr(LORAWAN_ADR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
#ifdef DEEPSLEEP_INTERVAL
|
||||||
gps_loop();
|
|
||||||
ttn_loop();
|
void doDeepSleep()
|
||||||
screen_loop();
|
{
|
||||||
|
uint64_t msecToWake = DEEPSLEEP_INTERVAL;
|
||||||
|
Serial.printf("Entering deep sleep %llu\n", msecToWake);
|
||||||
|
|
||||||
|
// not using wifi yet, but once we are this is needed to shutoff the radio hw
|
||||||
|
// esp_wifi_stop();
|
||||||
|
|
||||||
|
screen_off(); // datasheet says this will draw only 10ua
|
||||||
|
LMIC_shutdown(); // cleanly shutdown the radio
|
||||||
|
|
||||||
|
if(axp192_found) {
|
||||||
|
// turn on after initial testing with real hardware
|
||||||
|
// axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // LORA radio
|
||||||
|
// axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // GPS main power
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME - use an external 10k pulldown so we can leave the RTC peripherals powered off
|
||||||
|
// until then we need the following lines
|
||||||
|
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||||
|
|
||||||
|
// Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39.
|
||||||
|
uint64_t gpioMask = (1ULL << BUTTON_PIN);
|
||||||
|
|
||||||
|
// FIXME change polarity so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of just the first)
|
||||||
|
gpio_pullup_en((gpio_num_t) BUTTON_PIN);
|
||||||
|
|
||||||
|
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
|
||||||
|
|
||||||
|
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
|
||||||
|
esp_deep_sleep_start(); // TBD mA sleep current (battery)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// send ONE packet (or timeout waiting for GPS/LORA) and then enter deep sleep. If screen is on let the user have a few seconds to
|
||||||
|
/// see the results
|
||||||
|
void deepSleepLoop() {
|
||||||
|
// Send every SEND_INTERVAL millis
|
||||||
|
static uint32_t last = 0, timeToSleep = 0;
|
||||||
|
static bool first = true;
|
||||||
|
|
||||||
|
uint32_t now = millis();
|
||||||
|
|
||||||
|
if(packetSent) { // we've sent at least one packet to the server
|
||||||
|
timeToSleep = ssd1306_found ? now + 5000 : now; // If the display is on allow the user a few seconds to see it, otherwise go to sleep ASAP
|
||||||
|
}
|
||||||
|
|
||||||
|
if(timeToSleep && now >= timeToSleep) // if a sleep was queued, possibly do it
|
||||||
|
doDeepSleep();
|
||||||
|
|
||||||
|
if (0 == last || now - last > SEND_INTERVAL) {
|
||||||
|
if (trySend()) {
|
||||||
|
last = millis();
|
||||||
|
first = false;
|
||||||
|
Serial.println("TRANSMITTED");
|
||||||
|
} else {
|
||||||
|
if (first) {
|
||||||
|
screen_print("Waiting GPS lock\n");
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
if (millis() > GPS_WAIT_FOR_LOCK) { // we never found a GPS lock, just go back to sleep
|
||||||
|
doDeepSleep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/// loop endlessly, sending a packet every SEND_INTERVAL
|
||||||
|
void nonDeepSleepLoop() {
|
||||||
|
if(packetSent) {
|
||||||
|
packetSent = false;
|
||||||
|
sleep();
|
||||||
|
}
|
||||||
|
|
||||||
// Send every SEND_INTERVAL millis
|
// Send every SEND_INTERVAL millis
|
||||||
static uint32_t last = 0;
|
static uint32_t last = 0;
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
if (0 == last || millis() - last > SEND_INTERVAL) {
|
if (0 == last || millis() - last > SEND_INTERVAL) {
|
||||||
if (0 < gps_hdop() && gps_hdop() < 50 && gps_latitude() != 0 && gps_longitude() != 0) {
|
if (trySend()) {
|
||||||
last = millis();
|
last = millis();
|
||||||
first = false;
|
first = false;
|
||||||
Serial.println("TRANSMITTING");
|
Serial.println("TRANSMITTED");
|
||||||
send();
|
|
||||||
} else {
|
} else {
|
||||||
if (first) {
|
if (first) {
|
||||||
screen_print("Waiting GPS lock\n");
|
screen_print("Waiting GPS lock\n");
|
||||||
@ -365,3 +422,18 @@ void loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
gps_loop();
|
||||||
|
ttn_loop();
|
||||||
|
screen_loop();
|
||||||
|
|
||||||
|
#ifdef DEEPSLEEP_INTERVAL
|
||||||
|
deepSleepLoop();
|
||||||
|
#else
|
||||||
|
nonDeepSleepLoop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user