Передача данных из одной Arduino в другую

RZ3AMJ
Offline
Зарегистрирован: 13.09.2015

Приветствую всех.

Необходимо передать данные из одной Arduino в другую по Serial порту. Передаваться должны не байты, а символы. Помучавшись какое-то время я смог этого добиться, но теперь другая проблема. Обе Arduin`ы работают со своими программами и задержками типа delay(). В итоге данные принимаются или кусками или полностью искаженные. Соответсвенно вопрос, как наладить синхронизацию передачи и приёма данных?

Ниже привожу коды:

Передатчик:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(1200);
}

void loop() {
  Serial.println("220va");
  Serial.println("1220wa");
  Serial.println("221vb");
  Serial.println("1221wb");
  Serial.println("222vc");
  Serial.println("1222wc");
}

Приемник:

String bufer="";
void setup() {
Serial.begin(115200);
Serial1.begin(1200);
}
void loop() {
delay(500);
if (Serial1.available() > 0)
{
char ByteRead=Serial1.read();
//Serial.println(ByteRead);
if (ByteRead==13)
  {
    Serial.println(bufer);
    bufer="";
  }
else
  {
     if(ByteRead!=10)bufer=bufer+char(ByteRead); 
  }
}

}

Т.е. в приёмнике принимаются байты, потом переводятся в символы и "склеиваются" пока не получат перевод строки (код 13), ну и выдаются в Serial чтобы убедится что всё дошло успешно.

Если убрать в приёмнике delay(500), то данные приходят верно, но при использовании задержек, данные искажаются.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

RZ3AMJ пишет:

Передаваться должны не байты, а символы. 

Вы можете сформулировать чёткое различие между этими понятиями? Символы в Вашем случае представляются байтами и ничем другим.

RZ3AMJ пишет:

как наладить синхронизацию передачи и приёма данных?

Вы сами же ответили на этот вопрос ...

RZ3AMJ пишет:

Если убрать в приёмнике delay(500), то данные приходят верно

Ну так и сделайте. Убериет delay(500). Что мешает? Проблема-то в чём?

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Скорее вопрос стоит не в умении одной Ардуине отправить данные, а другой принять. Ведь каждая Ардуна должна еще что-то делать кроме этого. Вот это что-то не должно занимать времи больше delay(500). Но даже просто опрос клавиатуры может потребовать больше.  Для решения этого надо или принципиально менять архитектуру программы или городить паровоз с прерываниями.

Если вы пойдете первым путем, то надо программировать не "вертикально", а "горизонтально".

strarbit
Offline
Зарегистрирован: 12.06.2016

Все они умеют, ничего менять не надо  Arduine

RZ3AMJ
Offline
Зарегистрирован: 13.09.2015

Т.е. как я понял если две ардуины занимаются своими делами, то простым, ламерским образом никак их синхронизировать. А как еще можно передать данные без потерь с одной ардуины на другую, не обязательно по сериал, может беспроводные какие приблуды есть? Главное чтобы передать и принять точно одно и то же значение. 

strarbit
Offline
Зарегистрирован: 12.06.2016

Не нужно синхронизировать Arduino

RZ3AMJ
Offline
Зарегистрирован: 13.09.2015

strarbit пишет:

Не нужно синхронизировать Arduino

Хорошо, с одной ардуины на другую я передаю по байтам 4-х значное число в конце с переводом строки. Получаемая ардуина получает байты и "соеденияет" их в символьную строку пока не получит символ перевода строки, что является признаком что одно число передано. Когда на второй ардуине я делаю задержку delay(500), тем самым эмулируя работу, которую она должна выполнять кроме приёма данных, то число приходит или неполное, или может вообще принять байт от другого числа, вообщем получется билеберда. Как этого избежать?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

посмотри эту функцию. Serial.available(). Если есть принятые байты выкачивай из буфера. Если нет уходи delay(500) "другие задачи"

http://arduino.ru/Reference/Serial/Available

RZ3AMJ
Offline
Зарегистрирован: 13.09.2015

Пока добился передачи и приёма данных без искажений, если ставлю задержку передачи данных больше чем задержка работы программы "приёмника" и передаю по одному значению. Но как-то это не камильфо.

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

выкидывайте из скетчя delay и не используйте , замените на milis в справочнике почитай

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Цитата: "Функция получает количество байт(символов) доступных для чтения из последовательного интерфейса связи. Это те байты которые уже поступили и записаны в буфер последовательного порта. Буфер может хранить до 64 байт."

У Ардуины буфер в 64 байта. Так что за раз можно качнуть до 64 байт. У вас буфер не успевает разгрузится из-за паузы . Вот и косяки лезут

strarbit
Offline
Зарегистрирован: 12.06.2016

Посмотрите пример Serial Event из IDE Arduino
еще соедините минусы  Arduino 

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

RZ3AMJ, первое - избавляйтесь от задержек. Совсем. Программа никогда не должна останавливаться. Любые более или менее разумные действия укладываются либо в доли миллисекунды, либо, максимум, в единицы миллисекунд. Процессор работает на частоте 16 МГц и большую часть инструкций выполняет за 1 такт. Попытайтесь привести пример действия, которое требовало бы более 100000 инструкций. Это большая экзотика и такая экзотика оказывается несовместимой с передачей данных без подтверждения приема. В этом случае необходимо предусматривать, чтобы передающая программа узнавала, приняты ли данные, и если нет - перепосылоать их. Но намного проще избавиться от больших задержек.

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

RZ3AMJ
Offline
Зарегистрирован: 13.09.2015

В общем получилось все нормально синхронизировать заменив все delay на millis, и использовав  Serial Event. 

Всем спасибо, на данный момент проблема решена.