Arduino считывает строку с другого Arduino, только если строка находится в цикле. Почему?
В моей настройке я последовательно соединил два arduino. Arduino Mega — это тот, который отправляет строку, а Arduino Uno — тот, который ее получает.
- Arduino Mega: RX1(19),TX1(18) - Serial1
- Arduino Uno: RX(10),TX(11) - с использованием SoftwareSerial
- Gnd подключен на обеих платах
Когда я отправляю одну строку из Мега в Уно несколько раз (в пустом цикле) Я получаю строку, отправленную бесконечное количество раз на Uno, что и следовало ожидать:
Arduino Mega — одна строка отправляется несколько раз
void setup()
{
Serial1.begin(9600);
}
void loop()
{
Serial1.println("e2e4");
delay(100);
}
Теперь я хочу отправить строку только один раз, поэтому я вставил exit(0) или бесконечный цикл после задержки, которая всегда верна.
Arduino Mega — одна строка отправляется только один раз
void setup()
{
Serial1.begin(9600);
}
void loop()
{
Serial1.println("e2e4");
delay(100);
while(true);
}
Arduino UNO — код одинаков для обоих случаев
#include <SoftwareSerial.h>
SoftwareSerial s(10, 11);
void setup()
{
delay(200);
Serial.begin(9600);
s.begin(9600);
while (!Serial) ; // ждем Arduino Serial Monitor
}
void loop()
{
if(s.available()>0)
{
Serial.print("\nrec\n");
delay(100);
String b = s.readStringUntil('\n');
delay(100);
Serial.print(b);
delay(40);
}
}
Примечание: Arduino uno получает строку с помощью: readStringUntil('\n')
Но когда я отправляю строку только один раз, я ничего не получаю на Arduino Uno. Может ли кто-нибудь помочь мне выяснить, почему это происходит?
Я хочу знать, почему uno получает строку только тогда, когда она отправляется бесконечное количество раз, а не тогда, когда она отправляется 1 раз.
РЕДАКТИРОВАТЬ (8 июля)
Я все еще не нашел решения, которое мне нужно. Если кому-то нужна дополнительная информация, чтобы помочь мне, пожалуйста, сообщите мне об этом.
РЕДАКТИРОВАНИЕ (8-9 июля)
Извините, это моя вина, что я написал Tx1 как 19, а Rx1 как 18, хотя я не делал той же ошибки в коде. Когда я нажал кнопку сброса на mega, строка была получена на стороне uno. Как это произошло? До сих пор, после того как я загрузил код в оба arduino, я открыл последовательный монитор порта, подключенного к Uno, и я не получал строку.
Почему мне нужно сбрасывать Mega, чтобы отправить строку, разве это не должно работать, когда открыт последовательный монитор?
Также мне нужно, чтобы мега автоматически отправлял строку без какого-либо принудительного/физического сброса. Это возможно?
Я спрашиваю об этом, потому что отправка строки является частью более крупного кода, где значения обновляются с течением времени, а сброс вернет все значения в исходное состояние, чего я не хочу.
@Roshan, 👍1
Обсуждение4 ответа
exit(0) — это не та команда, которую следует использовать, она используется для полной остановки программы, хотя я не уверен, что именно происходит в скетче Arduino.
Чтобы остановить цикл (и продолжить его выполнение), обычно используется оператор break. Это работает внутри цикла while или for, и скетч продолжается после цикла while или for, где выполняется оператор break.
Обратите внимание, вы также можете начать с начала цикла while или for с помощью оператора continue.
exit
отключает прерывания и затем переходит в бесконечный цикл. Поэтому любой ожидающий последовательный вывод не выполняется., @Nick Gammon
exit
отключает прерывания, которые остановят последовательный вывод. Я предлагаю что-то попроще, например while (true);
Я уже упоминал, что пытаюсь это сделать., @Roshan
попробуйте добавить задержку в код arduino mega, чтобы убедиться, что uno полностью настроен, прежде чем он начнет отправлять данные. Я вижу некоторые задержки в коде uno, так что возможно, что arduino uno еще не готов, когда данные отправляются. Добавьте большую задержку, скажем, 2000, чтобы убедиться, что uno готов. Также есть более изящные способы сделать это вместо того, чтобы просто добавлять бесконечный цикл, если только единственная цель вашей программы — просто отправить одну строку. Вы можете использовать флаг, который отключает отправку.
bool isSent = true;
void loop()
{
if(isSent)
{
isSent = false; // устанавливаем значение false, чтобы мы больше никогда не отправляли данные.
Serial1.println("e2e4");
}
}
До сих пор, после загрузки кода в обе платы Arduino, я открывал последовательный монитор порта, подключенного к Uno, и не получал строку.
Почему мне нужно сбрасывать Mega, чтобы отправить строку, разве это не должно работать, когда открыт последовательный монитор?
Очевидно, что есть проблема с синхронизацией. Когда вы открываете последовательный монитор, он сбрасывает Arduino (в данном случае, я предполагаю, Uno). Таким образом, Uno сбрасывается, однако Mega не сбрасывается, потому что вы не открыли последовательный монитор там. Ручной сброс Mega заставляет его снова отправить данные (он бы отправил их раньше при включении).
В нормальной работе, конечно, вам не нужно сбрасывать Mega только для того, чтобы заставить строку «быть отправленной один раз». Вы уже доказали, что можете отправлять строку много раз, и отправка строки один раз — это явно подмножество этой ситуации. Отправка n раз — это просто (отправка один раз) умноженная на n.
Ваша тестовая установка, которая требует одновременного питания обоих Arduino, а затем открытия последовательного монитора, который сбрасывает один, но не другой, — вот что вас сбивает с толку. Дело не в том, что вы не можете отправлять строки, когда захотите, в обычном режиме работы.
- Последовательная связь между двумя Arduino не работает при отправке строки в программе с большим количеством функций.
- Проблемы Serial.write и Serial.read
- Как использовать SPI на Arduino?
- Как сбросить или отформатировать Arduino?
- Управление скоростью вентилятора с помощью библиотеки Arduino PID
- Как получить уникальный идентификатор для всех плат Arduino?
- Как очистить буфер FIFO на MPU6050?
- Элегантное решение для обновления содержимого TFT-дисплея
Более простой способ — поместить печать в
setup
, что выполняется только один раз., @Nick Gammonэто тоже не работает, @Roshan
Мой вопрос здесь не о том, как распечатать его один раз. Я хочу знать, почему я ничего не получаю на Uno, когда я печатаю его только один раз. Даже когда я печатаю в настройке, я не получаю строку на uno., @Roshan
Вы использовали цикл
while(true)
безexit(0)
? Это не совсем понятно, @chrisl@chrisl да, я это сделал. Я попробовал один раз с exit(0) и проверил, была ли получена строка на Uno, затем я удалил exit(0) и попробовал использовать while(true) и проверить, была ли получена строка на Uno, затем я удалил его и попробовал использовать оператор goto и так далее..., @Roshan
можно использовать int cnt=0; в настройке, а затем изменить print на println(cnt);cnt++; таким образом вы увидите, всегда ли вы пропускаете первую отправленную строку или любые последующие., @Chad G
две вещи, которые стоит попробовать: увеличить delay() и удалить delay(), @jsotola
Ваш опубликованный код не компилируется. Пожалуйста, не публикуйте псевдокод с вещами вроде "это ИЛИ то" в середине. Публикуйте **реальный** код, который не работает. Желательно без
exit
в нем. От нас нельзя ожидать отладки псевдокода., @Nick GammonКроме того, разместите весь код. Ваш фрагмент не включает
setup
, который может содержать в себе важную информацию., @Nick Gammon@NickGammon отредактировал вопрос, добавив соответствующий код., @Roshan
Как вы это подключили? Я спрашиваю, чтобы воспроизвести. Одна вещь, которая приходит на ум, это состояние гонки. Mega может отправлять строку до того, как Uno будет готов ее принять., @Nick Gammon
@NickGammon Я упомянул о проводке в начале своего вопроса. Я выложу схему, если это облегчит задачу. Вы упомянули, что это может быть из-за состояния гонки, что весьма вероятно, но когда я попробовал - вставив задержку прямо перед Serial1.println(), это не сработало. Я пробовал различные задержки вплоть до 10 секунд., @Roshan
Я не могу это воспроизвести. С контактом 18 (TX1) на моем Mega, подключенным к контакту 10 (программный последовательный прием), я получаю ожидаемое сообщение в последовательном журнале, если я сбрасываю Mega (тем самым заставляя его отправить сообщение один раз). Обратите внимание, что у вас есть контакты 18 и 19 **перепутаны** в тексте вашего вопроса. Когда я сказал "как вы это подключили?", я надеялся, что вы действительно покажете, что и куда подключено (или фото). Если у вас 19 на Mega подключен к 10 на Uno, то это определенно не будет работать., @Nick Gammon
@NickGammon Вы сказали, что нажали кнопку сброса в mega, чтобы заставить его отправить один раз. Как это работает? На самом деле я только что попробовал это сделать, и это сработало. До сих пор, после загрузки кода в оба arduino, я открывал последовательный монитор порта, подключенного к Uno, и не получал строку. Зачем мне нужно сбрасывать mega, разве он не должен работать, когда последовательный монитор открыт? Также мне нужно, чтобы mega автоматически отправляла строку без какого-либо принудительного/физического сброса, возможно ли это? Поскольку это часть более крупного кода, где значения обновляются с течением времени, а сброс просто очищает все, @Roshan
Если вы хотите задать вопрос о сохранении данных в EEPROM, то я предлагаю вам создать новый вопрос. Он имеет весьма косвенное отношение к этому., @Nick Gammon
вы используете неправильный метод отладки... не отправляйте одно и то же сообщение несколько раз... добавьте порядковый номер к каждому сообщению, чтобы каждое сообщение было разным, @jsotola