-
Notifications
You must be signed in to change notification settings - Fork 96
Fixed LoRa module not waked from sleep by autoBaud sometimes #231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ff4d97c
ed31a8a
fa0079f
2193f9e
4be44af
2634eb0
1b3cdf9
cfb5679
bab08ab
a164a60
0a8141e
48f3239
ee3f781
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although I know that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I really don't like using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guys, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sprintf wasnt implemented in this PR, so that would be stuff for an issue @jpmeijers There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hallard @samuel-puschacher you are changing existing code and replacing that by using |
||
|
||
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) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the reason for all these (breaking) changes just so that we can send the break condition at a lower baudrate? Won't it be simpler to do it differently like bitbanging the break condition on the correct pins, using digitalWrite() and delay()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reasons of the changes are Low Power. Waking 32U4 (or other) from sleep by the watchdog every 8s for doing nothing is a non sense when you have a module such like the RN2483 than can wake you after a given time with sleep command. The wake up occur when the module sends data to the serial line (that wake up the Atmel device). Unfortunately sometimes with this technique, and we can reproduce the problem, the existing wake (autobaud) was not able to wake the module and then lock the RN2483/Atmel communication. The fix I've made with
begin()
solve this issue.I already thought about bitbanging but touching/changing I/O port that is configured before by hardware UART stack (by 1st begin) is not really clean, we don't know how all of this will react afterward. Except calling a new begin() afterward to ensure all is correctly initialized so we're back in startup point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I understand what you are trying to do. I did the same in this repos: https://github.com/ncthompson/ThingsWeather/blob/master/firmware/things_uno/things_uno.ino
We however saw that after a few weeks the RN2483 would not wake up as expected, so we reverted back to using the ATmega's WDT.
Is it really impossible to handle the serial interrupt and re-bauding of the RN2483 from the user space, without changing the library? How about just manually doing an autobaud, including the begin() and baud changes, but in the user's program?