Некорректный приём данных UART

georgiy.psk
Offline
Зарегистрирован: 21.03.2017

Всем привет!

Гугл не помог, самому не догнать, нужна помощь)

Отправляю строку с одной ардуины на другую. На второй, которая принимает, для теста залито:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 3); // RX, TX
String s;
void setup() {
  s = "";
  
mySerial.begin(19200);
pinMode(13, OUTPUT);
mySerial.println("Test");
}

void loop() {
 while (mySerial.available() > 0) {
    s+=mySerial.write(mySerial.read());
  }
 }

Первая трудится с таким кодом:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 2); // RX, TX
void setup()
{ 
  Serial.begin(38400);
  mySerial.begin(19200);
 }

void loop()
{
   if (Serial.available()){
       mySerial.write(Serial.read());
  } 
 }

При подключении первой к USB-COM, в терминале всё отображается корректно, а если USB-COM подключить к ардуике №2, то на выходе получаем мусор. Что ещё замечено интересного, первый символ всегда приходит верный. 

ЗЫ: Ардуина №1 - Mega328 8mHz External 3v3 (pro)

Ардуина №2 - Mega328 16mHz External 5v (nano)

Уровни согласованы, скорости проверены, идей больше нет...

 

georgiy.psk
Offline
Зарегистрирован: 21.03.2017

Кнопку редактировать не обнаружил, в первом коде ляп.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 3); // RX, TX

void setup() {

  
mySerial.begin(19200);
pinMode(13, OUTPUT);
mySerial.println("Test");
}

void loop() {
 while (mySerial.available() > 0) {
    mySerial.write(mySerial.read());
  }
 }

 

Nkl-777
Offline
Зарегистрирован: 27.08.2016

Столкнулся с подобной проблемой - работаю с gprs модулем Neoway M590, напрямую через UART to USB переходник, через тот же ком монитор ардуины иде - все работает, модем отвечает корректно. Подключил к Arduino Nano 328, ее код 2 строки (если что, я только учусь):

if(SoftSerial.available() > 0)Serial.write(SoftSerial.read()); 
if(Serial.available() > 0)SoftSerial.write(Serial.read());

с короткими строками все работает отлично, а вот при отправке длинной строки появляются какие-то непонятьные символы. На скрине при отправке всей строки "AT+CGDCONT=1,"IP","internet.tele2.ru"" кодировка сбивается, а вот если отправить часть "AT+CGDCONT=1,"IP","intern", то все опять в порядке. Уже пробывал сначала считывать в переменную, потом выводить в порт, все так же работает. Особенность в том, что модем строку воспринимает корректно (на что отвечает ОК), а вот этот сбой происходит на стадии считывания програмного ком порта и передачи в аппаратный.

Мне по сути нуже ретранслятор с програмного порта на аппаратный, для контроля того что творится с модемом. Вроде задачка и простая, но мне оказалась не по силам. Может кто сталкивался?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
if(SoftSerial.available() > 0)Serial.write(SoftSerial.readString()); 
if(Serial.available() > 0)SoftSerial.write(Serial.readString());

 

Nkl-777
Offline
Зарегистрирован: 27.08.2016
if(SoftSerial.available() > 0)Serial.print(SoftSerial.readString());
if(Serial.available() > 0)SoftSerial.print(Serial.readString());

Пришлось вместо write использовать print, но результат оказался тот же:

Спасибо за отзыв)

fogary
Offline
Зарегистрирован: 05.03.2016

georgiy.psk пишет:

Кнопку редактировать не обнаружил, в первом коде ляп.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 3); // RX, TX

void setup() {

  
mySerial.begin(19200);
pinMode(13, OUTPUT);
mySerial.println("Test");
}

void loop() {
 while (mySerial.available() > 0) {
    mySerial.write(mySerial.read());
  }
 }

В коде Serial.begin() - пропущен; вариант вставить инициализацию порта пробовали?

belousovev
Offline
Зарегистрирован: 14.02.2017

Я могу ошибаться, но мне кажется вот в чем дело. Возможно вы все перепутали и на не те ножки посылаете информацию с первой платы на вторую. Сделайте везде скорость одинаковую (и на компьютере тоже), ну, например, 19200.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

1. Приведите схему включения.

2. Если предположить, что со схемой все в порядке, Вы уверены, что "скорости проверены"? У меня был случай, когда при передаче даже коротких сообщений (2-3 байта) наблюдались ошибки из-за того, что кварц на Ардуине (или керамический резонатор) имел частоту на 0.7% ниже номинала. Исправил пропорциональным увеличением заявленной скорости порта.

georgiy.psk
Offline
Зарегистрирован: 21.03.2017

Спасибо всем за отклики.

Помог вариант с readString. Строка считывается корректно. Если читать по одному байту (read), то по прежнему на выходе не понятно что.



if  (mySerial.available()>0){
       SerialString=mySerial.readStringUntil('#');        
        mySerial.println(SerialString);
          FixString();
            }
           if (SerialString!="") ReadDataFromString();

 

Единственное, что не нравится, теперь приходится тратить больше времени на поиск начала строки, раньше я поверял каждый байт на соответствие символу начала строки, сейчас приходится считывать всю строку, и потом, в отдельной функции искать символ начала и приводить её к нужному виду

Nkl-777
Offline
Зарегистрирован: 27.08.2016

Решил проблему с работой Neoway M590 по UART (Serial) через Arduino - оказалось строка просто не успевала попасть в порт целиком. Пара задержек и все работает стабильно:

  delay(20);//выждем, чтобы строка успела попасть в порт целиком раньше чем будет считана
  if(SoftSerial.available() > 0){Serial.write(SoftSerial.read());}
  delay(20);//выждем, чтобы строка успела попасть в порт целиком раньше чем будет считана
  if(Serial.available() > 0){SoftSerial.write(Serial.read());}