From 433a2215a5216ff09b1c4c564501fda3479f7885 Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 4 Apr 2018 17:55:41 +0200 Subject: [PATCH 1/2] Fixed LoRa module not waked from sleep by autoBaud sometimes (#231) * fixed RN2xxx not waked from sleep by autoBaud sometimes * changes requested by johan * changes requested by johan * johan request * cosmetic * HAL abstration of modemStream * Ability to use AltSoftSerial Library * Code optimization, added ~700 bytes flash for sketch * HardwareSerial only used on TheThings Node and Uno * Applied changes requested by johan * Fixed dual check * cosmetic * Added Hardware Serial only for the things node --- src/TheThingsNetwork.cpp | 180 +++++++++++++++------------------------ src/TheThingsNetwork.h | 16 +++- 2 files changed, 85 insertions(+), 111 deletions(-) diff --git a/src/TheThingsNetwork.cpp b/src/TheThingsNetwork.cpp index 7270cd2e..cb86a2a9 100755 --- a/src/TheThingsNetwork.cpp +++ b/src/TheThingsNetwork.cpp @@ -287,7 +287,7 @@ uint8_t receivedPort(const char *s) return port; } -TheThingsNetwork::TheThingsNetwork(Stream &modemStream, Stream &debugStream, ttn_fp_t fp, uint8_t sf, uint8_t fsb) +TheThingsNetwork::TheThingsNetwork(SerialType &modemStream, Stream &debugStream, ttn_fp_t fp, uint8_t sf, uint8_t fsb) { this->debugStream = &debugStream; this->modemStream = &modemStream; @@ -387,6 +387,12 @@ size_t TheThingsNetwork::readResponse(uint8_t prefixTable, uint8_t indexTable, u return readLine(buffer, size); } +size_t TheThingsNetwork::checkModuleAvailable() +{ + // Send sys get ver check we have an answer + return readResponse(SYS_TABLE, SYS_TABLE, SYS_GET_VER, buffer, sizeof(buffer)); +} + void TheThingsNetwork::autoBaud() { // Courtesy of @jpmeijers @@ -396,19 +402,51 @@ void TheThingsNetwork::autoBaud() while (attempts-- && length == 0) { delay(100); + // Send break + Autobaud modemStream->write((byte)0x00); modemStream->write(0x55); modemStream->write(SEND_MSG); - sendCommand(SYS_TABLE, 0, true, false); - sendCommand(SYS_TABLE, SYS_GET, true, false); - sendCommand(SYS_TABLE, SYS_GET_VER, false, false); - modemStream->write(SEND_MSG); - length = modemStream->readBytesUntil('\n', buffer, sizeof(buffer)); + // check we can talk + length = checkModuleAvailable(); + + // We succeeded talking to the module ? + baudDetermined = (length > 0) ; } delay(100); clearReadBuffer(); modemStream->setTimeout(10000); - baudDetermined = true; +} + +bool TheThingsNetwork::isSleeping() +{ + return !baudDetermined; +} + +void TheThingsNetwork::wake() +{ + // If sleeping + if (isSleeping()) + { + // Send a 0 at lower speed to be sure always received + // as a character a 57600 baud rate + modemStream->flush(); +#ifdef HARDWARE_UART + modemStream->begin(2400); +#endif + modemStream->write((uint8_t) 0x00); + modemStream->flush(); + delay(20); + // set baudrate back to normal and send autobaud +#ifdef HARDWARE_UART + modemStream->begin(57600); +#endif + modemStream->write((uint8_t)0x55); + modemStream->flush(); + modemStream->write(SEND_MSG); + if (checkModuleAvailable() > 0) { + baudDetermined = true; + } + } } void TheThingsNetwork::reset(bool adr) @@ -612,18 +650,16 @@ void TheThingsNetwork::showStatus() debugPrintIndex(SHOW_RX_DELAY_2, buffer); } -void TheThingsNetwork::configureEU868() +// Puting this common function saves 238 bytes of flash +void TheThingsNetwork::configureChannelsFreq(uint32_t freq, uint8_t first, uint8_t last, uint8_t first_dr) { - sendMacSet(MAC_RX2, "3 869525000"); - sendChSet(MAC_CHANNEL_DRRANGE, 1, "0 6"); - - char buf[10]; - uint32_t freq = 867100000; uint8_t ch; - for (ch = 0; ch < 8; ch++) + char buf[10]; + + for (ch = first; ch <= last; ch++) { sendChSet(MAC_CHANNEL_DCYCLE, ch, "799"); - if (ch > 2) + if (ch > first_dr) { sprintf(buf, "%lu", freq); sendChSet(MAC_CHANNEL_FREQ, ch, buf); @@ -632,6 +668,13 @@ void TheThingsNetwork::configureEU868() freq = freq + 200000; } } +} + +void TheThingsNetwork::configureEU868() +{ + sendMacSet(MAC_RX2, "3 869525000"); + sendChSet(MAC_CHANNEL_DRRANGE, 1, "0 6"); + configureChannelsFreq(867100000, 0, 8, 2); sendMacSet(MAC_PWRIDX, TTN_PWRIDX_EU868); } @@ -665,24 +708,9 @@ void TheThingsNetwork::configureAS920_923() * CH0 = 923.2MHz * CH1 = 923.4MHz */ - sendMacSet(MAC_ADR, "off"); // TODO: remove when ADR is implemented for this plan sendMacSet(MAC_RX2, "2 923200000"); - char buf[10]; - uint32_t freq = 922000000; - uint8_t ch; - for (ch = 0; ch < 8; ch++) - { - sendChSet(MAC_CHANNEL_DCYCLE, ch, "799"); - if (ch > 1) - { - sprintf(buf, "%lu", freq); - sendChSet(MAC_CHANNEL_FREQ, ch, buf); - sendChSet(MAC_CHANNEL_DRRANGE, ch, "0 5"); - sendChSet(MAC_CHANNEL_STATUS, ch, "on"); - freq = freq + 200000; - } - } + configureChannelsFreq(922000000, 0, 8, 1); // TODO: SF7BW250/DR6 channel, not properly supported by RN2903AS yet //sendChSet(MAC_CHANNEL_DCYCLE, 8, "799"); //sendChSet(MAC_CHANNEL_FREQ, 8, "922100000"); @@ -701,21 +729,7 @@ void TheThingsNetwork::configureAS923_925() sendMacSet(MAC_ADR, "off"); // TODO: remove when ADR is implemented for this plan sendMacSet(MAC_RX2, "2 923200000"); - char buf[10]; - uint32_t freq = 923600000; - uint8_t ch; - for (ch = 0; ch < 8; ch++) - { - sendChSet(MAC_CHANNEL_DCYCLE, ch, "799"); - if (ch > 1) - { - sprintf(buf, "%lu", freq); - sendChSet(MAC_CHANNEL_FREQ, ch, buf); - sendChSet(MAC_CHANNEL_DRRANGE, ch, "0 5"); - sendChSet(MAC_CHANNEL_STATUS, ch, "on"); - freq = freq + 200000; - } - } + configureChannelsFreq(923600000, 0, 8, 1); // TODO: SF7BW250/DR6 channel, not properly supported by RN2903AS yet //sendChSet(MAC_CHANNEL_DCYCLE, 8, "799"); //sendChSet(MAC_CHANNEL_FREQ, 8, "924500000"); @@ -734,18 +748,7 @@ void TheThingsNetwork::configureKR920_923() sendChSet(MAC_CHANNEL_STATUS, 0, "off"); sendChSet(MAC_CHANNEL_STATUS, 1, "off"); - char buf[10]; - uint32_t freq = 922100000; - uint8_t ch; - for (ch = 2; ch < 9; ch++) - { - sendChSet(MAC_CHANNEL_DCYCLE, ch, "799"); - sprintf(buf, "%lu", freq); - sendChSet(MAC_CHANNEL_FREQ, ch, buf); - sendChSet(MAC_CHANNEL_DRRANGE, ch, "0 5"); - sendChSet(MAC_CHANNEL_STATUS, ch, "on"); - freq = freq + 200000; - } + configureChannelsFreq(922100000, 2, 9, 0); sendMacSet(MAC_PWRIDX, TTN_PWRIDX_KR920_923); } @@ -865,24 +868,13 @@ bool TheThingsNetwork::sendChSet(uint8_t index, uint8_t channel, const char *val { clearReadBuffer(); char ch[5]; - if (channel > 9) - { - ch[0] = ((channel - (channel % 10)) / 10) + 48; - ch[1] = (channel % 10) + 48; - ch[2] = '\0'; - } - else - { - ch[0] = channel + 48; - ch[1] = '\0'; - } + sprintf(ch, "%d ", channel); debugPrint(F(SENDING)); sendCommand(MAC_TABLE, MAC_PREFIX, true); sendCommand(MAC_TABLE, MAC_SET, true); sendCommand(MAC_GET_SET_TABLE, MAC_CH, true); sendCommand(MAC_CH_TABLE, index, true); modemStream->write(ch); - modemStream->write(" "); modemStream->write(value); modemStream->write(SEND_MSG); debugPrint(channel); @@ -910,44 +902,16 @@ bool TheThingsNetwork::sendPayload(uint8_t mode, uint8_t port, uint8_t *payload, sendCommand(MAC_TABLE, MAC_PREFIX, true); sendCommand(MAC_TABLE, MAC_TX, true); sendCommand(MAC_TX_TABLE, mode, true); - char sport[4]; - if (port > 99) - { - sport[0] = ((port - (port % 100)) / 100) + 48; - sport[1] = (((port % 100) - (port % 10)) / 10) + 48; - sport[2] = (port % 10) + 48; - sport[3] = '\0'; - } - else if (port > 9) - { - sport[0] = ((port - (port % 10)) / 10) + 48; - sport[1] = (port % 10) + 48; - sport[2] = '\0'; - } - else - { - sport[0] = port + 48; - sport[1] = '\0'; - } - modemStream->write(sport); - modemStream->print(" "); - debugPrint(sport); - debugPrint(F(" ")); + char buf[5]; + sprintf(buf, "%d ", port); + modemStream->write(buf); + debugPrint(buf); uint8_t i = 0; for (i = 0; i < length; i++) { - if (payload[i] < 16) - { - modemStream->print("0"); - modemStream->print(payload[i], HEX); - debugPrint(F("0")); - debugPrint(payload[i], HEX); - } - else - { - modemStream->print(payload[i], HEX); - debugPrint(payload[i], HEX); - } + sprintf(buf, "%02X", payload[i] ); + modemStream->print(buf); + debugPrint(buf); } modemStream->write(SEND_MSG); debugPrintLn(); @@ -969,11 +933,9 @@ void TheThingsNetwork::sleep(uint32_t mseconds) modemStream->write(buffer); modemStream->write(SEND_MSG); debugPrintLn(buffer); -} -void TheThingsNetwork::wake() -{ - autoBaud(); + // to be determined back on wake up + baudDetermined = false; } void TheThingsNetwork::linkCheck(uint16_t seconds) diff --git a/src/TheThingsNetwork.h b/src/TheThingsNetwork.h index 6060cf66..9ed3eb07 100755 --- a/src/TheThingsNetwork.h +++ b/src/TheThingsNetwork.h @@ -20,6 +20,15 @@ #define TTN_BUFFER_SIZE 300 +// The Things Products devices +// Things Node only need this, we won't impact Things Uno user +#if defined(ARDUINO_THINGS_NODE) +typedef HardwareSerial SerialType; +#define HARDWARE_UART +#else +typedef Stream SerialType; +#endif + typedef uint8_t port_t; enum ttn_response_t @@ -42,7 +51,7 @@ enum ttn_fp_t class TheThingsNetwork { private: - Stream *modemStream; + SerialType *modemStream; Stream *debugStream; ttn_fp_t fp; uint8_t sf; @@ -60,7 +69,9 @@ class TheThingsNetwork void debugPrintIndex(uint8_t index, const char *value = NULL); void debugPrintMessage(uint8_t type, uint8_t index, const char *value = NULL); + size_t checkModuleAvailable(); void autoBaud(); + void configureChannelsFreq(uint32_t freq, uint8_t first, uint8_t last, uint8_t first_dr); void configureEU868(); void configureUS915(uint8_t fsb); void configureAS920_923(); @@ -78,7 +89,7 @@ class TheThingsNetwork void sendGetValue(uint8_t table, uint8_t prefix, uint8_t index); public: - TheThingsNetwork(Stream &modemStream, Stream &debugStream, ttn_fp_t fp, uint8_t sf = TTN_DEFAULT_SF, uint8_t fsb = TTN_DEFAULT_FSB); + TheThingsNetwork(SerialType &modemStream, Stream &debugStream, ttn_fp_t fp, uint8_t sf = TTN_DEFAULT_SF, uint8_t fsb = TTN_DEFAULT_FSB); void reset(bool adr = true); void showStatus(); size_t getHardwareEui(char *buffer, size_t size); @@ -93,6 +104,7 @@ class TheThingsNetwork ttn_response_t sendBytes(const uint8_t *payload, size_t length, port_t port = 1, bool confirm = false, uint8_t sf = 0); ttn_response_t poll(port_t port = 1, bool confirm = false); void sleep(uint32_t mseconds); + bool isSleeping(); void wake(); void saveState(); void linkCheck(uint16_t seconds); From 27a76a80ae12dafdb0948e4c33ec32e8b376855e Mon Sep 17 00:00:00 2001 From: JP Meijers Date: Wed, 4 Apr 2018 22:06:26 +0200 Subject: [PATCH 2/2] Clean up branch to only contain autobaud/wake code. --- src/TheThingsNetwork.cpp | 122 +++++++++++++++++++++++++++++++-------- src/TheThingsNetwork.h | 1 - 2 files changed, 98 insertions(+), 25 deletions(-) diff --git a/src/TheThingsNetwork.cpp b/src/TheThingsNetwork.cpp index cb86a2a9..24ac556c 100755 --- a/src/TheThingsNetwork.cpp +++ b/src/TheThingsNetwork.cpp @@ -650,16 +650,18 @@ void TheThingsNetwork::showStatus() debugPrintIndex(SHOW_RX_DELAY_2, buffer); } -// Puting this common function saves 238 bytes of flash -void TheThingsNetwork::configureChannelsFreq(uint32_t freq, uint8_t first, uint8_t last, uint8_t first_dr) +void TheThingsNetwork::configureEU868() { - uint8_t ch; - char buf[10]; + sendMacSet(MAC_RX2, "3 869525000"); + sendChSet(MAC_CHANNEL_DRRANGE, 1, "0 6"); - for (ch = first; ch <= last; ch++) + char buf[10]; + uint32_t freq = 867100000; + uint8_t ch; + for (ch = 0; ch < 8; ch++) { sendChSet(MAC_CHANNEL_DCYCLE, ch, "799"); - if (ch > first_dr) + if (ch > 2) { sprintf(buf, "%lu", freq); sendChSet(MAC_CHANNEL_FREQ, ch, buf); @@ -668,13 +670,6 @@ void TheThingsNetwork::configureChannelsFreq(uint32_t freq, uint8_t first, uint8 freq = freq + 200000; } } -} - -void TheThingsNetwork::configureEU868() -{ - sendMacSet(MAC_RX2, "3 869525000"); - sendChSet(MAC_CHANNEL_DRRANGE, 1, "0 6"); - configureChannelsFreq(867100000, 0, 8, 2); sendMacSet(MAC_PWRIDX, TTN_PWRIDX_EU868); } @@ -708,9 +703,24 @@ void TheThingsNetwork::configureAS920_923() * CH0 = 923.2MHz * CH1 = 923.4MHz */ + sendMacSet(MAC_ADR, "off"); // TODO: remove when ADR is implemented for this plan sendMacSet(MAC_RX2, "2 923200000"); - configureChannelsFreq(922000000, 0, 8, 1); + char buf[10]; + uint32_t freq = 922000000; + uint8_t ch; + for (ch = 0; ch < 8; ch++) + { + sendChSet(MAC_CHANNEL_DCYCLE, ch, "799"); + if (ch > 1) + { + sprintf(buf, "%lu", freq); + sendChSet(MAC_CHANNEL_FREQ, ch, buf); + sendChSet(MAC_CHANNEL_DRRANGE, ch, "0 5"); + sendChSet(MAC_CHANNEL_STATUS, ch, "on"); + freq = freq + 200000; + } + } // TODO: SF7BW250/DR6 channel, not properly supported by RN2903AS yet //sendChSet(MAC_CHANNEL_DCYCLE, 8, "799"); //sendChSet(MAC_CHANNEL_FREQ, 8, "922100000"); @@ -729,7 +739,21 @@ void TheThingsNetwork::configureAS923_925() sendMacSet(MAC_ADR, "off"); // TODO: remove when ADR is implemented for this plan sendMacSet(MAC_RX2, "2 923200000"); - configureChannelsFreq(923600000, 0, 8, 1); + char buf[10]; + uint32_t freq = 923600000; + uint8_t ch; + for (ch = 0; ch < 8; ch++) + { + sendChSet(MAC_CHANNEL_DCYCLE, ch, "799"); + if (ch > 1) + { + sprintf(buf, "%lu", freq); + sendChSet(MAC_CHANNEL_FREQ, ch, buf); + sendChSet(MAC_CHANNEL_DRRANGE, ch, "0 5"); + sendChSet(MAC_CHANNEL_STATUS, ch, "on"); + freq = freq + 200000; + } + } // TODO: SF7BW250/DR6 channel, not properly supported by RN2903AS yet //sendChSet(MAC_CHANNEL_DCYCLE, 8, "799"); //sendChSet(MAC_CHANNEL_FREQ, 8, "924500000"); @@ -748,7 +772,18 @@ void TheThingsNetwork::configureKR920_923() sendChSet(MAC_CHANNEL_STATUS, 0, "off"); sendChSet(MAC_CHANNEL_STATUS, 1, "off"); - configureChannelsFreq(922100000, 2, 9, 0); + char buf[10]; + uint32_t freq = 922100000; + uint8_t ch; + for (ch = 2; ch < 9; ch++) + { + sendChSet(MAC_CHANNEL_DCYCLE, ch, "799"); + sprintf(buf, "%lu", freq); + sendChSet(MAC_CHANNEL_FREQ, ch, buf); + sendChSet(MAC_CHANNEL_DRRANGE, ch, "0 5"); + sendChSet(MAC_CHANNEL_STATUS, ch, "on"); + freq = freq + 200000; + } sendMacSet(MAC_PWRIDX, TTN_PWRIDX_KR920_923); } @@ -868,13 +903,24 @@ bool TheThingsNetwork::sendChSet(uint8_t index, uint8_t channel, const char *val { clearReadBuffer(); char ch[5]; - sprintf(ch, "%d ", channel); + if (channel > 9) + { + ch[0] = ((channel - (channel % 10)) / 10) + 48; + ch[1] = (channel % 10) + 48; + ch[2] = '\0'; + } + else + { + ch[0] = channel + 48; + ch[1] = '\0'; + } debugPrint(F(SENDING)); sendCommand(MAC_TABLE, MAC_PREFIX, true); sendCommand(MAC_TABLE, MAC_SET, true); sendCommand(MAC_GET_SET_TABLE, MAC_CH, true); sendCommand(MAC_CH_TABLE, index, true); modemStream->write(ch); + modemStream->write(" "); modemStream->write(value); modemStream->write(SEND_MSG); debugPrint(channel); @@ -902,16 +948,44 @@ bool TheThingsNetwork::sendPayload(uint8_t mode, uint8_t port, uint8_t *payload, sendCommand(MAC_TABLE, MAC_PREFIX, true); sendCommand(MAC_TABLE, MAC_TX, true); sendCommand(MAC_TX_TABLE, mode, true); - char buf[5]; - sprintf(buf, "%d ", port); - modemStream->write(buf); - debugPrint(buf); + char sport[4]; + if (port > 99) + { + sport[0] = ((port - (port % 100)) / 100) + 48; + sport[1] = (((port % 100) - (port % 10)) / 10) + 48; + sport[2] = (port % 10) + 48; + sport[3] = '\0'; + } + else if (port > 9) + { + sport[0] = ((port - (port % 10)) / 10) + 48; + sport[1] = (port % 10) + 48; + sport[2] = '\0'; + } + else + { + sport[0] = port + 48; + sport[1] = '\0'; + } + modemStream->write(sport); + modemStream->print(" "); + debugPrint(sport); + debugPrint(F(" ")); uint8_t i = 0; for (i = 0; i < length; i++) { - sprintf(buf, "%02X", payload[i] ); - modemStream->print(buf); - debugPrint(buf); + if (payload[i] < 16) + { + modemStream->print("0"); + modemStream->print(payload[i], HEX); + debugPrint(F("0")); + debugPrint(payload[i], HEX); + } + else + { + modemStream->print(payload[i], HEX); + debugPrint(payload[i], HEX); + } } modemStream->write(SEND_MSG); debugPrintLn(); diff --git a/src/TheThingsNetwork.h b/src/TheThingsNetwork.h index 9ed3eb07..05edbd89 100755 --- a/src/TheThingsNetwork.h +++ b/src/TheThingsNetwork.h @@ -71,7 +71,6 @@ class TheThingsNetwork size_t checkModuleAvailable(); void autoBaud(); - void configureChannelsFreq(uint32_t freq, uint8_t first, uint8_t last, uint8_t first_dr); void configureEU868(); void configureUS915(uint8_t fsb); void configureAS920_923();