diff --git a/src/TheThingsNetwork.cpp b/src/TheThingsNetwork.cpp index 7270cd2e..24ac556c 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) @@ -969,11 +1007,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..05edbd89 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,6 +69,7 @@ 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 configureEU868(); void configureUS915(uint8_t fsb); @@ -78,7 +88,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 +103,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);