Я не уверен насчет базовой реализации Serial
, однако может произойти какое-то бесконечное ожидание происходящего Serial.println()
.
И чтение документации по Serial.flush()
Похоже, что это также может быть причиной бесконечного ожидания окончания вывода последовательного выхода до sh.
Поскольку Serial.println()
, кажется, использует функциональность Serial.write()
для своей цели, я бы предположил что если в какой-то момент у вас нет устройства, считывающего данные с последовательного порта, буфер записи переполняется и блокируется Serial.println()
. См. https://www.arduino.cc/reference/en/language/functions/communication/serial/write/
Примечания и предупреждения
Начиная с Arduino IDE 1.0, последовательная передача является асинхронной. Если в буфере передачи достаточно свободного места, Serial.write () вернется до того, как любые символы будут переданы через последовательный порт. Если буфер передачи заполнен, то Serial.write () будет блокироваться, пока в буфере не будет достаточно места. Чтобы избежать блокировки вызовов Serial.write (), вы можете сначала проверить количество свободного места в буфере передачи, используя availableForWrite ().
См. Это объяснение функции Serial.flush()
https://www.arduino.cc/reference/en/language/functions/communication/serial/flush/ с примечаниями:
Serial.flu sh ()
Описание
Ожидает завершения передачи исходящих последовательных данных. (До Arduino 1.0 вместо этого удалялись все буферизованные входящие последовательные данные.)
flu sh () наследуется от служебного класса Stream.
И см. Эту статью https://www.baldengineer.com/when-do-you-use-the-arduinos-to-use-serial-flush.html с надписью "
Что делает Serial.flu sh ()?
Из ссылки на Arduino для Serial.flu sh ( находится на этой странице):
Ожидание завершения передачи исходящих последовательных данных.
Ключ этого оператора - "исходящий". Serial.flu sh () не очищает «входящий» буфер, как думают многие. Он приостанавливает вашу программу, пока очищается буфер передачи.
Я бы использовал функцию Serial.availableForWrite()
перед выполнением любого вывода с использованием Serial.println()
и если число доступных байтов указывает на то, что буфер записи заполняется, пропустите вывод.
Вероятно, наилучшим подходом будет использование функции Setup()
для проверки размера буфера записи после делать Serial.begin()
и хранить это в глобальной переменной Файл, который вы затем используете для проверки, очищается ли буфер записи или нет.
См. https://www.instructables.com/id/Arduino-Serial/, в котором говорится:
Шаг 3: Команда: AvailableForWrite ()
Описание
Получите количество байтов (символов), доступных для записи в последовательный буфер, без блокировки операции записи.
Синтаксис
Serial.availableForWrite ()
См. Также https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/
Существует также if (Serial)
, который можно использовать для проверки, если порт доступен. https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/ однако я подозреваю, что это скорее проверка того, что запрашиваемый порт доступен, а не то, действительно ли порт работает с устройством на другом конце линии.
И есть также Serial.available()
https://www.arduino.cc/reference/en/language/functions/communication/serial/available/
Serial.available ()
Описание
Получить количество байтов ( символы) доступны для чтения из последовательного порта. Это данные, которые уже получены и хранятся в буфере последовательного приема (который содержит 64 байта).
Serial.available () наследуется от служебного класса Stream.
Синтаксис
Serial.available ()
Параметры
Serial: объект последовательного порта. См. Список доступных последовательных портов для каждой платы на главной странице Serial.
Возвращает
Количество байтов, доступных для чтения.
Рекомендуется курс действий
Прежде всего, я не вижу необходимости Serial.flush()
в функции Setup()
, и ее можно безопасно удалить. Хотя это делает вывод на консоль немедленным во время Setup()
, оно вводит ожидание удаленного случая, в котором нет устройства, считывающего данные из последовательной линии, чтобы очистить буфер вывода.
Я также предлагаю, чтобы для каждого В строке, которую вы делаете Serial.println()
, вы проверяете число байтов буфера, доступных с Serial.availableForWrite()
, сначала как:
int firstAvailableForWrite = 0;
void Setup ()
{
// set up everything you do then add the following statement
firstAvailableForWrite = Serial.availableForWrite();
}
Затем, где бы вы ни собирались выполнить запись, измените это с помощью if
оператор, подобный следующему примеру:
if (Serial.availableForWrite() >= firstAvailableForWrite) Serial.println("Config SIM900...");
Или вы также можете создать функцию, подобную следующей:
int serialPrintLineIfAvailable (char *aszLine)
{
int iCount = 0;
if (Serial.availableForWrite() >= firstAvailableForWrite) iCount = Serial.println(aszLine);
return iCount;
}
Тогда везде, где вы хотите использовать Serial.println()
, вы бы вместо этого используйте serialPrintLineIfAvailable()
как в serialPrintLineIfAvailable("Config SIM900...");