Как правильно установить аппаратный UART-соединение между Arduino DUE и Mega?

Здравствуйте! Могу ли я получить рекомендации по правильной настройке передачи данных по UART от Arduino DUE к Arduino MEGA? <br/><br/> В проекте DUE постоянно принимает данные в реальном времени через USB-порт (35 байт), которые затем используются для управления светодиодами и сервоприводами. Она также функционирует как HID-устройство через второй порт, в результате чего играет роль симулятора приборной панели. <br/><br/> Теперь я хочу добавить дисплей для отображения некоторых данных, таких как время, статус круиз-контроля и уровень повреждений. Я попробовал использовать дисплей с разрешением 480x320 на чипе 9488, но из-за медленной SPI-шины возникали проблемы с задержками в работе, что влияло на поведение светодиодов и сервоприводов.<br/><br/> В результате я решил заменить дисплей на другой, который собираюсь подключить к MEGA, а часть приходящих данных буду передавать по UART (около 15 байт). <br/><br/> Однако возникла проблема: данные доходят, но их порядок постоянно меняется. Привожу примеры скетчей ниже. <br/><br/> Подключение: DUE TX -> MEGA RX, также соединены земли. <br/><br/> Как правильно ограничить количество передаваемых байт и организовать передачу данных? <br/><br/><b>DUE - отправитель</b> <br/><pre><code class="cpp">#define PACKET_SYNC 0xFF
void setup() {   
  Serial.begin(255000); // USB-порт 
  Serial1.begin(9600); // UART-порт
}

void loop() {
  // Отправка данных
  Serial1.write(PACKET_SYNC);
  Serial1.write(120);
  Serial1.write(66);
  Serial1.write(200);
}</code></pre> 
  • 27 августа 2024 г. 10:24
Ответы на вопрос 2
Для настройки UART-соединения между Arduino DUE и Mega, а также для обеспечения правильной передачи данных, вам нужно учитывать несколько важных пунктов:
1. **Согласование скорости передачи**: Убедитесь, что оба устройства настроены на одинаковую скорость передачи данных. В вашем случае DUE работает на 9600 бод, поэтому Mega также должен быть настроен на такую же скорость.
2. **Формат передачи данных**: Используйте специальный байт-синхронизатор (как вы уже сделали с `PACKET_SYNC`) для того, чтобы принимать данные в правильном порядке. Также рекомендуется передавать длину пакета или использовать уже установленный четкий протокол для чтения данных на принимающей стороне.
3. **Правильная настройка приема данных**: Необходимо убедиться, что Mega корректно считывает передаваемые данные, используя подходящее количество байтов и правильный порядок, чтобы избежать проблем с путаницей.

Вот пример, как можно настроить обе стороны:

### Код для DUE (отправитель)
```cpp
#define PACKET_SYNC 0xFF

void setup() {
  Serial.begin(255000); // USB-порт
  Serial1.begin(9600);  // UART-порт
}

void loop() {
  // Отправка данных
  Serial1.write(PACKET_SYNC);
  Serial1.write(120);   // Данные
  Serial1.write(66);    // Данные
  Serial1.write(200);   // Данные

  delay(1000); // Задержка для снижения частоты отправки данных
}
```

### Код для MEGA (приемник)
```cpp
#define PACKET_SYNC 0xFF

void setup() {
  Serial.begin(9600);  // Для дебага
  Serial1.begin(9600); // UART-порт
}

void loop() {
  while (Serial1.available()) {
    static uint8_t buffer[10];  // Буфер для хранения входящих данных
    static uint8_t index = 0;
    
    uint8_t byteReceived = Serial1.read();
    
    // Если пришел байт синхронизации, очистим буфер
    if (byteReceived == PACKET_SYNC) {
      index = 0; // Сброс индекса
    } else {
      if (index < sizeof(buffer) - 1) {
        buffer[index++] = byteReceived;  // Заполняем буфер
      }
    }

    // Если буфер полностью заполнен, обрабатываем данные
    if (index >= 3) { // Длина пакета 3 ранее установленные байтов
      // Извлекаем данные из буфера
      uint8_t data1 = buffer[0];
      uint8_t data2 = buffer[1];
      uint8_t data3 = buffer[2];

      // Здесь можно добавить код для обработки данных
      Serial.print("Received data: ");
      Serial.print(data1);
      Serial.print(", ");
      Serial.print(data2);
      Serial.print(", ");
      Serial.println(data3);
      
      // Сбрасываем буфер для следующего пакета
      index = 0;
    }
  }
}
```

### Объяснения:
1. **Синхронизация**: Используется байт синхронизации для обработки данных на принимающей стороне, сбрасывая индекс буфера при получении этого байта.
2. **Буферизация данных**: Данные сохраняются в массиве `buffer`, и когда заполняется заданное количество байтов, данные обрабатываются.
3. **Отладка**: Serial для Mega используется для отладки полученных данных, чтобы убедиться, что данные принимаются корректно.

С таким подходом упорядоченность передаваемых данных должна быть стабильной, и вы сможете избежать проблем со смешением байтов. Настройка задержек с помощью `delay()` поможет избежать перегрузки передачи.
Первое, что стоит сделать, это взять в качестве образца пример получения данных из serial, идущий в комплекте с Arduino IDE. По результату уже смотреть далее.
Похожие вопросы