Нужна помощь с UART

slon197
Offline
Зарегистрирован: 05.01.2017

Доброго времени суток. Смыл затеи такой:

есть железка, которая в определенный момент времени начинает передавать данные в виде AA 00 00 00 00 00 C3 3C CB . Эти данные неизменны и передаются циклически до тех пор, пока эту железку не выключить. Как только появились эти данные ардуинка должна передавать этой железке данные типа 5A 01 22 29 27 10 01 3C до тех пор, пока железка не перестанет слать данные. Просто передачу данных с помощью Serial.write  сделал, но хотелось бы, чтобы ардуинка слала данные, только когда пришли данные от железки. Как то так.

void setup(){
Serial.begin(9600);
}

void loop() {
Serial.write(0x5A);
Serial.write(0x01);
Serial.write(0x22);
Serial.write(0x29);
Serial.write(0x27);
Serial.write(0x10);
Serial.write(0x01);
Serial.write(0x3C);
delay (100);

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ну дак а проблема то в чём?  Принимай, сравнивай, отправляй. 

slon197
Offline
Зарегистрирован: 05.01.2017

Проблема в том, что я не знаю как это написать.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

1. Научись принимать.  Gугал, "Ардуино приём по Serial"

Green
Онлайн
Зарегистрирован: 01.10.2015

И немедленно принял.)

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Как обычно, ищешь в принятых данных байт соответствующий началу пакета, вычитываешь нужное количество байт в массив. Сравниваешь полученные с эталоном, при совпадении отсылаешь свой пакет.
Если на это мозгов не хватает....

Тогда два варианта:
1. Читаешь тут темы по работе с uart
2.заказываешь в "ищу исполнителя"

slon197
Offline
Зарегистрирован: 05.01.2017

исчерпывающие ответы

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ты траншеи копать умеешь?  Давай меняца, ты мне траншею, я тебе красивый код. 

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

slon197 пишет:

исчерпывающие ответы

Ответы действительно исчерпывающие.

А если Вашей квалификации не хватает, чтобы суметь ими воспользоваться, то в сообщении №5 было предложено два варианта решения.

slon197
Offline
Зарегистрирован: 05.01.2017

Я умею людей лечить, а не траншеи копать.

b707
Offline
Зарегистрирован: 26.05.2017

slon197 пишет:

Я умею людей лечить, а не траншеи копать.

тогда ты оценил, как тебя тут "полечили".

На самом деле, обижаться не надо. Если даже ответ от Кактуса (#5)непонятен - то ничего другого, как повышать свой уровень - тут посоветовать нельзя.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

slon197 пишет:

Я умею людей лечить, а не траншеи копать.


А я вот людей лечить не умею, поэтому и не пытаюсь.

Upper
Offline
Зарегистрирован: 23.06.2020

b707 пишет:

slon197 пишет:

Я умею людей лечить, а не траншеи копать.

тогда ты оценил, как тебя тут "полечили".

На самом деле, обижаться не надо. Если даже ответ от Кактуса (#5)непонятен - то ничего другого, как повышать свой уровень - тут посоветовать нельзя.

Минус для Kakmyc поставил я. Посчитал, что способ решения просто не верен.

Green
Онлайн
Зарегистрирован: 01.10.2015

Ну так разверните оценку.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Upper пишет:

Минус для Kakmyc поставил я. Посчитал, что способ решения просто не верен.

Даже вот интересно, что именно не понравилось в этом примерном описании алгоритма приема и проверки пакета ?

b707
Offline
Зарегистрирован: 26.05.2017

Upper пишет:

Посчитал, что способ решения просто не верен.

расскажете?

Upper
Offline
Зарегистрирован: 23.06.2020

Kakmyc пишет:
Upper пишет:

Минус для Kakmyc поставил я. Посчитал, что способ решения просто не верен.

Даже вот интересно, что именно не понравилось в этом примерном описании алгоритма приема и проверки пакета ?

Как обычно, ищешь в принятых данных байт соответствующий началу пакета, вычитываешь нужное количество байт в массив. Сравниваешь полученные с эталоном,

Для случая  AA AA AA AA AA ...... AA AA 00 00 00 00 00 C3

В том виде как написано, практическая реализация усложнена. Какое "нужное количество  байт в массив", что делать когда не совпало и т.д. Поэтому и "Посчитал, что способ решения просто не верен."

(Изначально правда в моем комментарии было написано более категорично, наверное зря).

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

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

Когда не совпало, не отправлять пакет. Это явно следует из условия задачи.

Green
Онлайн
Зарегистрирован: 01.10.2015

Либо в пакете данных не должен попадаться префикс. Байт стаффинг называется.

Upper
Offline
Зарегистрирован: 23.06.2020

sadman41 пишет:

Когда не совпало, не отправлять пакет. Это явно следует из условия задачи.

Я имел в виду, не совпало в массиве в котором ищем. Как сдвигать точку поиска, и т.д.

Реализуемо, но будет усложнено.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Никак не сдвигать. Начинать отсчёт только от префикса. До этого всё скипать. 

Это стандартные процедуры для тех, кто пытается парсеры писать. Для других нужно было вообще объяснять с того, что такое "байт". Можешь сделать это, никто не запрещает.

__Alexander
Offline
Зарегистрирован: 24.10.2012

Я чет не понял, автор же говорит что данные не изменяемые. Может проще ждать последний (СВ) и слать ответ. Или я не так понял?

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

slon197 пишет:

Я умею людей лечить, а не траншеи копать.

Лечить людей - это хорошо.

А Вы можете дать консультацию - как делать лобэктомию?

MaksVV
Offline
Зарегистрирован: 06.08.2015

byte INmessage[]  = {0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x3C, 0xCB};
byte OUTmessage[] = {0x5A, 0x01, 0x22, 0x29, 0x27, 0x10, 0x01, 0x3C};

void UART_read()
{
  
static byte j=0;                 // инкремент
static uint32_t prevRESET=0;     // таймер сброса приема сообщения, если  данные оборвались
static bool RESET_timer = 0;     // таймер сброса приема сообщения, если  данные оборвались

if (Serial.available()) { // если имеются поступившие данные, работаем 

byte inbyte = Serial.read();     // читаем вновь поступивший байт

    // если очередной поступивший байт равен соответствующему байту нашего сообщения
     if (inbyte == INmessage[j] && j<sizeof(INmessage)) 
        {
        if (j == 0){RESET_timer=1;}  // если это начало сообщения, запустим таймер
        j++; // увеличиваем счётчик
        //если приняли все байты сообщения, делаем нужные вещи:
        if (j == sizeof(INmessage)) {Serial.write (OUTmessage, sizeof(OUTmessage)); j = 0; RESET_timer = 0;}
        prevRESET=millis(); // сбрасываем время таймера
        }
      else {j = 0; RESET_timer = 0;} // если очередной байт не равен нашему или счётчик насчитал более чем надо. 
}
  
  //  если таймаут кончился (данные оборвались), сбрасываем прием сообщения:
  if (RESET_timer && millis() - prevRESET > 500)  {j = 0; RESET_timer = 0;}
}

void setup() 
{
  Serial.begin (9600);

}

void loop() 
{
  UART_read();

}

Upper
Offline
Зарегистрирован: 23.06.2020

Подозрительные строчки

16      j++; // увеличиваем счётчик
17      if (j == 0){RESET_timer=1;}  // если это начало сообщения, запустим таймер
MaksVV
Offline
Зарегистрирован: 06.08.2015

согласен , поправил

sadman41
Онлайн
Зарегистрирован: 19.10.2016

В том случае, если сообщения не было более 500ms, после первого же байта произойдет сброс по таймауту. И на следующем пакете тоже. И т.д.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Sadman, специально проверил - нет такого проявления. Объясни, с чего так должно произойти. 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

А, сорян, скобку в конце 21 строки не приметил. Сейчас в IDE переформатировал - все скобки разбежались "по этажам". Вчера с телефона показалось, что prevRESET=millis(); выполняется только при "if (j == sizeof(INmessage))".

Upper
Offline
Зарегистрирован: 23.06.2020

(Не по поводу таймера)
Некоторые рассуждения - замечания.   Если в процессе приема байтов после стартового AA (т.е. J>0) придет не ожидаемый байт, то он просто отбрасывается. Т.е. если вместо ожидаемого (например 00) пришел стартовый , то он отбросится.

(Изменено были ошибочные выводы).

MaksVV
Offline
Зарегистрирован: 06.08.2015

Почему отбрасывается? весь пакет сбрасывается и скетч начинает ждать опять начальный байт ААh. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

А в случае битых пакетов в общем то сброс по таймаутуи и поможет. Можно таймаут поменьше сделать, чтоб надежнее защищал

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

slon197 пишет:

исчерпывающие ответы

А Вы каких ожидали? Можете привести "шаблон" ответа, который бы Вас устроил? Приведите, а мы подумаем.

slon197 пишет:

Я умею людей лечить

Отлично! У меня что-то болит возле локтя. Скальпель и фонендоскоп у меня есть.  И тонометр тоже валяется, только батарейку заменить надо. Как сделать, чтобы не болело? "Обратиться к врачу" и "идти в учиться в мед." не предлагать - это будут "исчерпывающие ответы".