Project

General

Profile

Interference between Sleepy and Serial Communication?

Added by physikus almost 7 years ago

Hi,
since I recently had problems with garbled characters in my serial communication, I wrote a small sketch for testing (on a Jeelink connected to a Mac running Arduino IDE):

#include 

ISR(WDT_vect) { Sleepy::watchdogEvent(); }

void setup () {
    Serial.begin(57600);
}

void loop () {
    Serial.println(millis());
    Serial.flush();
    //Sleepy::loseSomeTime(1000);
    delay(1000);
}

Everything works as expected:

0
999
2000
3001
4001

If I exchange the delay against the Sleepy line, the output is the following:

0H(ʒH(ʪHHʺÂHhʺŠ

Thus, my questions:
Does the Sleepy function/watchdog interfere with serial communication? At least my results suggest such an interference.
Can this be avoided or is there a workaround?

Regards,

Physikus.


Replies (3)

Answer and question - Added by Rolf almost 7 years ago

Answer:
Yes there is an interference, though I cannot tell you the reason, just how I circumvented it: place a delay, like “delay(1000);”, before the call of “loseSomeTime” (makes only sense if loseSomeTime-delay is much longer).

Question (to the experts):
I have a problem which may have the same cause. A program which sends measured values via rf12 and sleeps inbetween gets stucked sometimes in the following loop:

while (!rf12_canSend()) rf12_recvDone(); // wait until sending is allowed ()
(I know about the rf12_canSend-problem, rf12_sendStart is called immediatly afterwords).
At the end of the general loop, the call to set the system in sleep-mode looks like this:
for(i=0; i<sample_interval; i++) {
Sleepy::loseSomeTime(800);
}
My question is: What can be the cause for the program be locked (in this (
) loop)?

Thanks for your attention

RE: Interference between Sleepy and Serial Communication? - Added by jcw almost 7 years ago

The loseSomeTime() call puts the µC to sleep before the serial UART has finished sending the bytes out. It should be sufficient to add a brief wait before going to sleep, using:

Serial.flush();

You may still have to wait just a little longer, though. In that case, also add this line:

delay(2);

With 57600 baud, sending out 1 character takes under a millisecond.

Another way would be to wait until the UART transmit buffer is really empty, using this one-liner:

while (bitRead(UCSR0A, UDRE0) == 0) ;

Note the trailing semicolon: this does busy-looping.

RE: Interference between Sleepy and Serial Communication? - Added by physikus almost 7 years ago

Interesting. I tried it. With the Serial.flush() a delay(1) before Sleepy::… seems to be sufficient. Without, Serial.flush() but with delay(1), after some time, the CR or CRLF is dropped.

    (1-3/3)