Связь с подключенным устройством UART работает только в одном направлении
Как говорится в названии, у меня есть два устройства с Arduino (Uno и Mega) соединены друг с другом через интерфейсы UART (Мега аппаратного UART, Uno-это программа по UART); мне нужно чтобы Мега отправил команду в Uno, Uno, чтобы выполнить команду, потом Уно доложить Мега, когда он завершил свою задачу. Таким образом, я хочу реализовать асинхронное программирование для управления различными схемами освещения, а также несколькими двигателями (код не показан, это необязательно, так как управление освещением находится в изолированном сегменте) без необходимости взлома прошивки. Отправка команд из Mega в Uno работает, но обратное неверно, и даже очереди ожидания опроса не работают. Обратите внимание, что если я отправлю команду "подтвердить" несколько раз в течение бесконечности, но затем я повешу код в Uno, и у Mega не будет возможности остановить заграждение; он начнет получать вероятные случайные байты. Мой код для Мега громоздкий и многофайловый, поэтому я не могу отправить все целиком, но вот контрольный код:
lights::showRow(Serial1, 0, 0, 1, 1, 2, 2);
lights::waitUntilFinished(Serial1);
delay(500);
lights::clear(Serial1);
lights::waitUntilFinished(Serial1);
lights::chantO(Serial1);
lights::waitUntilFinished(Serial1);
lights::showRow(Serial1, 1, 0, 1, 1, 1, 2);
lights::waitUntilFinished(Serial1);
delay(500);
lights::clear(Serial1);
lights::waitUntilFinished(Serial1);
lights::chantX(Serial1);
lights::waitUntilFinished(Serial1);
Эти команды реализуются с помощью:
namespace lights{
boll ready = false;
boll helloSent = false;
void chantO(HardwareSerial coms){
coms.write(1);
}
void chantX(HardwareSerial coms){
coms.write(2);
}
void showRow(HardwareSerial coms, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t x3, uint8_t y3){
coms.write(3);
coms.write(x1);
coms.write(y1);
coms.write(x2);
coms.write(y2);
coms.write(x3);
coms.write(y3);
}
void clear(HardwareSerial coms){
coms.write(4);
}
void waitUntilFinished(HardwareSerial coms){
while (coms.available() == 0){};
Serial.println("Done.");
// Он не может сказать ничего, кроме "подтверждено", поэтому мы можем сохранить некоторый код, не проверяя.
}
}
Световой код:
/* Чтобы облегчить жизнь, я включу карту подключения. Меняйтесь по мере необходимости.
* Обратите внимание, что каждое кольцо имеет размер 24 пикселя и помечено первой позицией для доступа к нему. Следующий, очевидно, будет заключительным пунктом.
____ ____ ____
/48 \___/72 \ /192 \
\____/ \____/ \____/
|___ |___ |___
/24 \ /96 \ /168 \
\____/ \____/ \____/
|___ |___ |___
/0 \ /120 \___/144 \_____[END]
\____/ \____/ \____/
|
|
[CONTROLLER]
*/
#include <Adafruit_NeoPixel.h>
#include <SoftwareSerial.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 6
#define NUMPIXELS 216
#define DELAYVAL 500
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
SoftwareSerial coms(9, 8);
int white = pixels.Color(255, 255, 255);
int red = pixels.Color(255, 0, 0);
int getPixel(uint8_t x, uint8_t y, uint8_t num){
if (x == 0){
return 48 - (y * 24) + num;
}
else if (x == 1){
return 72 + (y * 24) + num;
}
else if (x == 2){
return 192 - (y * 24) + num;
}
}
void setRing(uint8_t x, uint8_t y, int color){
for (int i = 0; i < 24; i ++){
pixels.setPixelColor(getPixel(x, y, i), color);
}
}
void setup(){
pinMode(9, INPUT);
pinMode(8, OUTPUT);
coms.begin(9600);
Serial.begin(9600);
pixels.begin();
pixels.setBrightness(205); // 0.8 * 256 = 204.8; это составляет 80% мощности. Только 6 могут быть освещены до того, как у вас возникнут проблемы.
}
void loop(){
if (coms.available() > 0){
uint8_t d = coms.read();
Serial.println("He talkin' me");
Serial.print("He say ");
Serial.println(d);
switch (d){
case 1:
for (uint8_t x = 0; x < 2; x ++){
setRing(0, 1, white);
setRing(1, 0, white);
setRing(2, 1, white);
setRing(1, 2, white);
pixels.show();
delay(500);
pixels.clear();
pixels.show();
delay(500);
}
break;
case 2:
for (uint8_t x = 0; x < 2; x ++){
setRing(0, 0, white);
setRing(2, 2, white);
setRing(2, 0, white);
setRing(0, 2, white);
setRing(1, 1, white);
pixels.show();
delay(500);
pixels.clear();
delay(500);
}
break;
case 3:
Serial.println("Hello, World");
setRing(coms.read(), coms.read(), red);
setRing(coms.read(), coms.read(), red);
setRing(coms.read(), coms.read(), red);
pixels.show();
break;
case 4:
pixels.clear();
pixels.show();
break;
}
coms.write(1);
}
}
@nerdguy, 👍-1
Обсуждение1 ответ
Вы передаете свои объекты HardwareSerial
(Сериал1
) по значению. Это означает, что объект копируется, что нехорошо - он разрывает соединение между буфером входящих данных и прерыванием, которое загружает кольцевой буфер RX.
Вместо этого вы должны либо передавать по ссылке, либо по указателю. Лично я предпочитаю указатели, потому что это то, что я привык использовать, но вы можете использовать и то, и другое.
Например:
void waitUntilFinished(HardwareSerial &coms){ // <--- помните &
while (coms.available() == 0){};
Serial.println("Готово.");
// Он не может сказать ничего, кроме "подтверждено", поэтому мы можем сохранить некоторый код, не проверяя.
}
Я бы также подумал о том, чтобы изменить это из пространства имен в класс и передать последовательный объект, который вы хотите использовать в качестве параметра, конструктору и сохранить указатель на него в классе - тогда вам нужно будет передать его только один раз, а затем использовать этот указатель с этого момента. Это просто упростило бы ваш код и несколько очистило бы ситуацию.
- Как использовать SPI на Arduino?
- Как сбросить или отформатировать Arduino?
- Управление скоростью вентилятора с помощью библиотеки Arduino PID
- Как получить уникальный идентификатор для всех плат Arduino?
- Как очистить буфер FIFO на MPU6050?
- Элегантное решение для обновления содержимого TFT-дисплея
- Считывание нескольких поворотных энкодеров
- Что выбрать между датчиками температуры и влажности: AM230x или DHT22?
загрузите скетч примера программного обеспечения в оба ардуино ... используйте аппаратный последовательный порт на мега ... проверьте подключение между двумя ардуино, @jsotola
Вам необходимо передать параметры HardwareSerial по ссылке, чтобы предотвратить копирование объектов., @Majenko