From 0c58e83e2ffbdf2233ec67d1008547d87be732fb Mon Sep 17 00:00:00 2001 From: foorschtbar Date: Mon, 14 Feb 2022 14:30:19 +0100 Subject: [PATCH 1/3] Fixed MCU deepsleep inaccuracy --- src/main.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c20d379..9818485 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -673,26 +673,25 @@ void lmicStartup() void do_sleep(uint16_t sleepTime) { - uint16_t sleepTimeLeft = sleepTime; boolean breaksleep = false; if (LOG_DEBUG_ENABLED) { Serial.print(F("Sleep ")); - if (sleepTimeLeft <= 0) + if (sleepTime <= 0) { Serial.println(F("FOREVER\n")); } else { - Serial.print(sleepTimeLeft); + Serial.print(sleepTime); Serial.println(F("s\n")); } Serial.flush(); } // sleep logic using LowPower library - if (sleepTimeLeft <= 0) + if (sleepTime <= 0) { LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); } @@ -701,7 +700,11 @@ void do_sleep(uint16_t sleepTime) // Add LORA_MAX_RANDOM_SEND_DELAY of randomness to avoid overlapping of different // nodes with exactly the same sende interval - sleepTimeLeft += (rand() % LORA_MAX_RANDOM_SEND_DELAY); + sleepTime += (rand() % LORA_MAX_RANDOM_SEND_DELAY); + + // Measurements show that the timer is off by about 12 percent, + // so the sleep time is shortened by this value. + sleepTime *= 0.88; // sleep logic using LowPower library uint16_t delays[] = {8, 4, 2, 1}; @@ -710,12 +713,12 @@ void do_sleep(uint16_t sleepTime) for (uint8_t i = 0; (i <= 3 && !breaksleep); i++) { - for (uint16_t x = sleepTimeLeft; (x >= delays[i] && !breaksleep); x -= delays[i]) + for (uint16_t x = sleepTime; (x >= delays[i] && !breaksleep); x -= delays[i]) { // Serial.print("i: "); // Serial.print(i); // Serial.print(" TL: "); - // Serial.print(sleepTimeLeft); + // Serial.print(sleepTime); // Serial.print(" S: "); // Serial.println(delays[i]); // Serial.flush(); @@ -726,7 +729,7 @@ void do_sleep(uint16_t sleepTime) } else { - sleepTimeLeft -= delays[i]; + sleepTime -= delays[i]; } } } @@ -773,11 +776,11 @@ void onEvent(ev_t ev) break; case EV_JOIN_FAILED: log_d_ln(F("Join failed")); - lmicStartup(); //Reset LMIC and retry + lmicStartup(); // Reset LMIC and retry break; case EV_REJOIN_FAILED: log_d_ln(F("Rejoin failed")); - lmicStartup(); //Reset LMIC and retry + lmicStartup(); // Reset LMIC and retry break; case EV_TXSTART: From 3f16b114f1910f73dcfb33001647358bfe7933c1 Mon Sep 17 00:00:00 2001 From: foorschtbar Date: Tue, 15 Feb 2022 11:46:09 +0100 Subject: [PATCH 2/3] Fixed problem with duty cycle limitation --- platformio.ini | 2 +- src/main.cpp | 53 +++++++++++++++++++++++++++----------------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/platformio.ini b/platformio.ini index a5646b8..16ad9fc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,7 +32,7 @@ build_flags = -D USE_IDEETRON_AES -D MIC_ENABLE_arbitrary_clock_error -D VERSION_MAJOR=2 - -D VERSION_MINOR=4 + -D VERSION_MINOR=5 [env:config] build_flags = diff --git a/src/main.cpp b/src/main.cpp index 9818485..f541e02 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -145,7 +145,7 @@ configData_t cfg; // Instance 'cfg' is a global variable with 'configData_t' str volatile boolean wakedFromISR0 = false; volatile boolean wakedFromISR1 = false; unsigned long lastPrintTime = 0; -unsigned long prepareCount = 0; +// unsigned long prepareCount = 0; boolean TXCompleted = false; boolean foundBME = false; // BME Sensor found. To skip reading if no sensor is attached boolean foundDS = false; // DS19x Sensor found. To skip reading if no sensor is attached @@ -550,8 +550,8 @@ void do_send(osjob_t *j) buffer[10] = temp2 >> 8; buffer[11] = temp2; - log_d("Prepare package #"); - log_d_ln(++prepareCount); + log_d_ln("Prepare pck"); + // log_d_ln(++prepareCount); // log_d(F("> FW: v")); // log_d(VERSION_MAJOR); // log_d(F(".")); @@ -579,7 +579,7 @@ void do_send(osjob_t *j) // Prepare upstream data transmission at the next possible time. LMIC_setTxData2(1, buffer, sizeof(buffer), cfg.CONFIRMED_DATA_UP); - log_d_ln(F("Packet queued")); + log_d_ln(F("Pck queued")); } } @@ -654,6 +654,8 @@ void lmicStartup() // Disable link check validation LMIC_setLinkCheckMode(0); + // Disable ADR + LMIC_setAdrMode(0); // TTN uses SF9 for its RX2 window. LMIC.dn2Dr = DR_SF9; @@ -670,6 +672,7 @@ void lmicStartup() // #endif } +extern volatile unsigned long timer0_overflow_count; void do_sleep(uint16_t sleepTime) { @@ -734,6 +737,13 @@ void do_sleep(uint16_t sleepTime) } } } + + // LMIC does not get that the MCU is sleeping and the + // duty cycle limitation then provides a delay. A manual + // overflow of timer0_overflow_count (wiring.c from the arduino core) + // which is used for micros() fix that. + // https://www.thethingsnetwork.org/forum/t/adafruit-feather-32u4-lora-long-transmission-time-after-deep-sleep/11678/11 + timer0_overflow_count += 3E6; } void onEvent(ev_t ev) @@ -787,12 +797,12 @@ void onEvent(ev_t ev) // log_d_ln(F("EV_TXSTART")); break; case EV_TXCOMPLETE: - log_d(F("TX complete #")); // (includes waiting for RX windows) + log_d(F("TX done #")); // (includes waiting for RX windows) log_d_ln(LMIC.seqnoUp); if (LMIC.txrxFlags & TXRX_ACK) - log_d_ln(F("> Received ack")); + log_d_ln(F("> Got ack")); if (LMIC.txrxFlags & TXRX_NACK) - log_d_ln(F("> Received NO ack")); + log_d_ln(F("> Got NO ack")); // if (LMIC.dataLen) // { @@ -900,11 +910,11 @@ void setup() delay(100); // per sample code on RF_95 test } - log_d(F("\n=== Starting LoRaProMini v")); + log_d(F("\n= Starting LoRaProMini v")); log_d(VERSION_MAJOR); log_d(F(".")); log_d(VERSION_MINOR); - log_d_ln(F(" ===")); + log_d_ln(F(" =")); readConfig(); @@ -924,13 +934,13 @@ void setup() } } - log_d(F("Search DS18x...")); + log_d(F("Srch DS18x...")); ds.begin(); ds.requestTemperatures(); log_d(ds.getDeviceCount(), DEC); - log_d_ln(F(" found")); + log_d_ln(F(" fnd")); for (uint8_t i = 0; i < ds.getDeviceCount(); i++) { @@ -967,11 +977,11 @@ void setup() } // BME280 forced mode, 1x temperature / 1x humidity / 1x pressure oversampling, filter off - log_d(F("Search BME280...")); + log_d(F("Srch BME...")); if (bme.begin(I2C_ADR_BME)) { foundBME = true; - log_d_ln(F("1 found")); + log_d_ln(F("1 fnd")); if (CONFIG_MODE_ENABLED) { bme.takeForcedMeasurement(); @@ -988,7 +998,7 @@ void setup() } else { - log_d_ln(F("not found")); + log_d_ln(F("0 fnd")); } // Allow wake up pin to trigger interrupt on low. @@ -1010,7 +1020,7 @@ void setup() // Reset the MAC state. Session and pending data transfers will be discarded. lmicStartup(); - Serial.print(F("Join Mode: ")); + Serial.print(F("Join mode ")); // ABP Mode if (cfg.ACTIVATION_METHOD == ABP) @@ -1028,10 +1038,6 @@ void setup() // Join the network, sending will be started after the event "Joined" LMIC_startJoining(); } - else - { - Serial.println(F("?")); - } } } @@ -1061,7 +1067,7 @@ void loop() } else { - log_d_ln(F("Batt V to low!")); + log_d_ln(F("Bat to low!")); } } @@ -1070,10 +1076,9 @@ void loop() // sleep ended. do next transmission doSend = true; } - else if (lastPrintTime == 0 || lastPrintTime + 5000 < millis()) + if (lastPrintTime == 0 || lastPrintTime + 5000 < millis()) { - log_d(F("Can't sleep. txCnt=")); - log_d_ln(LMIC.txCnt); + log_d_ln(F("> Cant sleep")); lastPrintTime = millis(); } @@ -1085,4 +1090,4 @@ void loop() do_send(&sendjob); } } -} \ No newline at end of file +} From 10f7bdddd0f791e0136df2ae37ebde57f58af99a Mon Sep 17 00:00:00 2001 From: foorschtbar Date: Tue, 15 Feb 2022 17:35:56 +0100 Subject: [PATCH 3/3] Update README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 315b68b..f80c11e 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,10 @@ avrdude -F -v -c arduino -p atmega328p -P COM4 -b 57600 -D -U flash:w:firmware_1 ## Firmware Changelog +### Version 2.5 + +- Fixed problem with duty cycle limitation +- Fixed MCU deepsleep inaccuracy ### Version 2.4 - An external interrupt during a transmission terminates the transmission and starts a new transmission.