I'm not sure about the underlying implementation of Serial
however there may be some kind of an infinite wait for the Serial.println()
that is happening.
And reading the documentation on Serial.flush()
it appears that it may also be the cause of an infinite wait for the serial output to finish before it returns.
Since Serial.println()
seems to use the Serial.write()
functionality to do its thing I would suppose that if you have no device reading from the serial port at some point the write buffer is getting full and causing the Serial.println()
to block. See https://www.arduino.cc/reference/en/language/functions/communication/serial/write/
Notes and Warnings
As of Arduino IDE 1.0, serial transmission is asynchronous. If there
is enough empty space in the transmit buffer, Serial.write() will
return before any characters are transmitted over serial. If the
transmit buffer is full then Serial.write() will block until there is
enough space in the buffer. To avoid blocking calls to Serial.write(),
you can first check the amount of free space in the transmit buffer
using availableForWrite().
See this explanation of the Serial.flush()
function https://www.arduino.cc/reference/en/language/functions/communication/serial/flush/ which notes:
Serial.flush()
Description
Waits for the transmission of outgoing serial data to complete. (Prior
to Arduino 1.0, this instead removed any buffered incoming serial
data.)
flush() inherits from the Stream utility class.
And see this article, https://www.baldengineer.com/when-do-you-use-the-arduinos-to-use-serial-flush.html which says"
What does Serial.flush() do?
From the Arduino reference for Serial.flush (found on this page):
Waits for the transmission of outgoing serial data to complete.
The key to that statement is “outgoing”. Serial.flush() doesn’t
empty the “incoming” buffer as many people think. It pauses your
program while the transmit buffer is flushed.
I would use the Serial.availableForWrite()
function before doing any output using Serial.println()
and if the number of bytes available indicates that the write buffer is getting full then skip the output.
Probably the best approach would be as part of the Setup()
function to check the write buffer size after doing the Serial.begin()
and store that in a global variable which you then use to check to see if the write buffer is getting emptied or not.
See https://www.instructables.com/id/Arduino-Serial/ which has this to say:
Step 3: Command : AvailableForWrite()
Description
Get the number of bytes (characters) available for writing in the
serial buffer without blocking the write operation.
Syntax
Serial.availableForWrite()
See also https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/
There is also if (Serial)
which can be used to check if the port is available. https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/ however I suspect that it is more of a check that the requested port is available rather than whether the port is actually functioning with a device on the other end of the link.
And there is also the Serial.available()
https://www.arduino.cc/reference/en/language/functions/communication/serial/available/
Serial.available()
Description
Get the number of bytes (characters) available for reading from the
serial port. This is data that’s already arrived and stored in the
serial receive buffer (which holds 64 bytes).
Serial.available() inherits from the Stream utility class.
Syntax
Serial.available()
Parameters
Serial: serial port object. See the list of available serial ports for
each board on the Serial main page.
Returns
The number of bytes available to read.
Suggested course of action
First of all, I don't see that the Serial.flush()
in the Setup()
function is necessary and it could be safely removed. While this makes the console output immediate during the Setup()
it does introduce a wait for the remote case in which there is no device reading from the serial line to empty the output buffer.
I also suggest that for each line you do Serial.println()
you do a check on the number of bytes of buffer available with Serial.availableForWrite()
first as in:
int firstAvailableForWrite = 0;
void Setup ()
{
// set up everything you do then add the following statement
firstAvailableForWrite = Serial.availableForWrite();
}
Then where ever you are going to do a write modify that with an if
statement similar to the following example:
if (Serial.availableForWrite() >= firstAvailableForWrite) Serial.println("Config SIM900...");
Or you could also create a function something like the following:
int serialPrintLineIfAvailable (char *aszLine)
{
int iCount = 0;
if (Serial.availableForWrite() >= firstAvailableForWrite) iCount = Serial.println(aszLine);
return iCount;
}
Then wherever you want to use Serial.println()
you would instead use serialPrintLineIfAvailable()
as in serialPrintLineIfAvailable("Config SIM900...");
delay
like that. You must read and parse the responses received from the modem. – hlovdalSerial.availableForWrite()
inSetup()
? – Richard Chambers