Парсинг serial.Теряются байты.

bambucho
Offline
Зарегистрирован: 30.08.2014

Плата mega2560 (16Мгц).

На Serial1 поступает поток на скорости  38400.

С Serial работающем на скорости 38400,снимается поток (читается).

Задача алгоритма пока примитивна,при появлении байта 0xFE на Serial1,передать последующие 8 байт на Serial0.

В чем проблема,после обнаружения байта  0xFE на Serial1,в процессе передачи на Serial теряются стабильно 1-2 байта (шаблон кадра мне известен) .Почему так происходит?

 

Код:

boolean flag_start_frame = false;

void setup()

{

                                Serial.begin(38400); // устанавливаем последовательное соединение

                                Serial1.begin(38400); // устанавливаем последовательное соединение

}

void loop()

 {

      if (Serial1.read() == 0xFE)

        {

         flag_start_frame = true;

        }

If (flag_start_frame)

        {

           for(int i=0; i<8; i++)

                    {

                      Serial.write(Serial1.read());

                  }  

          flag_buf_full = false; 

         }

}

 

 

kasper007
Offline
Зарегистрирован: 23.05.2016

А почему нет перед чтением нет проверки на то, что что-то поступило в буфер порта:

if (Serial1.available()>0) {}

Это раз, а во вторых рекомендую как раз после проверки поставить delay(2) или delay(3). Практика показывает, что эта задержка позволяет поступить всем данным в буфер, из которого вы их потом читаете.

 

bambucho
Offline
Зарегистрирован: 30.08.2014

Изначально я его использовал,но где то нашел информацию,что Serial1.available()>0 может пропускать пустые байты.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Выше объяснили, почему теряются данные - вы читаете из Serial в полной уверенности в том, что там уже есть необходимые вам 8 байт, без проверки на то, что они туда реально свалились. Отсюда - и потери.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

bambucho пишет:

Изначально я его использовал,но где то нашел информацию,что Serial1.available()>0 может пропускать пустые байты.

Это где вы такую чушь прочитали? Что есть пустой байт - 0? 0 - это тоже информация ;)

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

bambucho пишет:

Изначально я его использовал,но где то нашел информацию,что Serial1.available()>0 может пропускать пустые байты.

пустой байт - это как это?

bambucho
Offline
Зарегистрирован: 30.08.2014

Да,забыл отметить,теряются стабильно именно после обнаружения 0xFE.

Задержки на delay очень  бы не хотел юзать,т.к. предпалагается работать еще в довесок с ws2812,опрашивать кнопку и мерять 6ть каналов напряжений.

1)А есть в арду среде возможность следить за состоянием флага переполнения буфера serial? 

2)Еще не понятно вот что,буфер сериала равен 16ти байтам,получается если код не успеет их всех от туда вытянуть,то поступающие данные просто проигнорятся,так?

3)Я так понимаю,буфер смещается на один байт,когда я вызываю метод read() (Serial1.read();)?

или что является сигналом,что буфер сериала прочитан и можно его опустошить для приема следующих данных?

Как доберусь до платы,еще раз попробую заюзать проверку на поступление байт.

 

В коде подправил ошибку с флагом:

boolean flag_start_frame = false;

void setup()

{

                                Serial.begin(38400); // устанавливаем последовательное соединение

                                Serial1.begin(38400); // устанавливаем последовательное соединение

}

void loop()

 {

      if (Serial1.read() == 0xFE)

        {

         flag_start_frame = true;

        }

If (flag_start_frame)

        {

           for(int i=0; i<8; i++)

                    {

                      Serial.write(Serial1.read());

                  }  

          flag_start_frame = false; 

         }

}

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Код всё равно неправильный, правильный примерно такой:

bool waitForFrameCompleted = false;
int readedFrameLen = 0;

void loop()
{
	while(Serial.available())
	{
		byte b = Serial.read();
		if(waitForFrameCompleted)
		{
			readedFrameLen++;
			if(readedFrameLen >7)
			{
				waitForFrameCompleted = false;
				readedFrameLen = 0;
			}
			
			Serial1.write(b);
		} // waitForFrameCompleted
		else
		{
			if(b == 0xFE)
			{
				waitForFrameCompleted = true;
				readedFrameLen = 0;
			}
		} // else
		
	} // while
}

 

kasper007
Offline
Зарегистрирован: 23.05.2016

bambucho пишет:

Задержки на delay очень  бы не хотел юзать,т.к. предпалагается работать еще в довесок с ws2812,опрашивать кнопку и мерять 6ть каналов напряжений.

Я не говорю, что панацея вставлять delay. В вашем изначальном вопросе не было информации, что вы будете еще что-то довешивать. Можете заменить delay на какие-то посторонние математические расчеты и операции. НО СУТЬ ТО В ДРУГОМ!!!

Вам каким-то образом нужно выждать время, чтобы в порт свалился весь ваш пакет.

Давайте посчитаем грубо на пальцах, просто чтобы понять порядок цифр:

Скорость выполнения команды на arduino не более 10 мкс. Скорость передачи одного байта при скорости 38400 бод = 0,2 мс. Т.е. ваша посылка из 10 байт будет передаваться 2 мс.

Итак началась передача данных, и к моменту выполнения первого Serial.Read уже что-то залетело в буфер. И в этот момент начинается жесткое выбирание данных из буфера со скоростью выполнения команды Serial.Read. И уже буквально через 100 мкс будет все из буфера считано. Но вся посылка за 100 мкс не успевает прийти в буфер. Поэтому вычитывается все что есть, а потом у вас скорее всего пойдут читаться 0xFF.

bambucho
Offline
Зарегистрирован: 30.08.2014

kasper007 пишет:

bambucho пишет:

Задержки на delay очень  бы не хотел юзать,т.к. предпалагается работать еще в довесок с ws2812,опрашивать кнопку и мерять 6ть каналов напряжений.

Я не говорю, что панацея вставлять delay. В вашем изначальном вопросе не было информации, что вы будете еще что-то довешивать. Можете заменить delay на какие-то посторонние математические расчеты и операции. НО СУТЬ ТО В ДРУГОМ!!!

Вам каким-то образом нужно выждать время, чтобы в порт свалился весь ваш пакет.

Давайте посчитаем грубо на пальцах, просто чтобы понять порядок цифр:

Скорость выполнения команды на arduino не более 10 мкс. Скорость передачи одного байта при скорости 38400 бод = 0,2 мс. Т.е. ваша посылка из 10 байт будет передаваться 2 мс.

Итак началась передача данных, и к моменту выполнения первого Serial.Read уже что-то залетело в буфер. И в этот момент начинается жесткое выбирание данных из буфера со скоростью выполнения команды Serial.Read. И уже буквально через 100 мкс будет все из буфера считано. Но вся посылка за 100 мкс не успевает прийти в буфер. Поэтому вычитывается все что есть, а потом у вас скорее всего пойдут читаться 0xFF.

Верно,я на вскидку также и прикинул,от сюда и возникли вопросы.

 

 

bambucho
Offline
Зарегистрирован: 30.08.2014

DIYMan пишет:

Код всё равно неправильный, правильный примерно такой:

bool waitForFrameCompleted = false;
int readedFrameLen = 0;

void loop()
{
	while(Serial.available())
	{
		byte b = Serial.read();
		if(waitForFrameCompleted)
		{
			readedFrameLen++;
			if(readedFrameLen >7)
			{
				waitForFrameCompleted = false;
				readedFrameLen = 0;
			}
			
			Serial1.write(b);
		} // waitForFrameCompleted
		else
		{
			if(b == 0xFE)
			{
				waitForFrameCompleted = true;
				readedFrameLen = 0;
			}
		} // else
		
	} // while
}

 

Сегодня вечером попробую заюзать.

vde69
Offline
Зарегистрирован: 10.01.2016

твою задачу нужно решать по другому в принцепе

1. создать буфер длинной 8 байт, и указатель на пустой элемент буфера

2. считываем 1 байт и записываем в буфер[указатель+1] и увеличиваем указатель

3. проверяем если указатель = 7 то проверяем первый байт буфера, если это начало - то отправляем весь буфер а указатель обнуляем, если нет - сдвигаем буфет на 1 и уменьшаем указатель на 1

4. переходим к п.2

 

что даст такой поход? да очень просто - он даст возможность копатся в полученом пакете целиком его имея в буфере еще до отправки...

 

вот моя процедура разбора входящего на пакеты (она выделяет пакет из потока и игнорирует мусор)

 

void BusRS485::poll() {
  uint8_t mCRC = 0;
  uint8_t i1 = 0;
  int ii;

  while (true) {
    // FInPack=0
    //    0-ждем заголовок 
    //    1-ждем дополнительные данные 
    //    2-пакет загружен валиден 
    //    3-пакет загружен, но не валиден
    
    if (FInPack > 3) {FInPack = 0;}  // не понятный флаг, значит будем ждать заголовок
    else if (FInPack == 2) {break;}  // пакет загружен и не обработан
    else if (FInPack == 3) {break;}  // пакет загружен и не валиден
    
    ii = port->available();
    if (ii == 0) { break; } // данных нет

    // вне зависимости от ожиданий пробуем выцепить заголовок
    if (port->peek() == MARK && ii >= 8){
      mCRC =  CRC(MARK, 0);
      mCRC =  CRC(port->peek(1), mCRC);
      mCRC =  CRC(port->peek(2), mCRC);
      mCRC =  CRC(port->peek(3), mCRC);
      mCRC =  CRC(port->peek(4), mCRC);
      mCRC =  CRC(port->peek(5), mCRC);
      mCRC =  CRC(port->peek(6), mCRC);
      if (mCRC == port->peek(7)) {  // да это заголовок пакета,
        InPack.Mark           = Read();
        InPack.Id_Destination = Read();
        InPack.Id_Source      = Read();
        InPack.Control_1      = Read();
        InPack.Control_2      = Read(); 
        InPack.SizeDate       = Read(); 
        InPack.CRC_Data       = Read(); 
        InPack.CRC_Head       = Read(); 
        
        if (InPack.SizeDate == 0) {              // пакет не содержит дополнительных данных, только номер и команду          
          FInPack = 2;
        }
        else if (InPack.SizeDate <= MAX_BUFFER){ // заголовок загружен, нужно пытатся загрузить данные          
          FInPack = 1; continue;
        }
        else {                                   // мы не можем обработать такой большой пакет          
          FInPack = 3;
        }
        break;
      }
      else if (FInPack == 0) {      // ждали заголовок а CRC не совпало
        Read();
        continue;        
      }
    }

    if (FInPack == 0) {   // ждем заголовка, а маркера нет
      if (port->peek() != MARK) {
        Read();
        continue; 
      } 
    }

//--------------------------------------------------------------------------
    if (FInPack == 1 && ii >= InPack.SizeDate) { 
      // Загрузим доп данные вне зависимости от CRC
      for (int i1=0; i1 < InPack.SizeDate; i1++){ InPack.Data[i1] = Read(); } 
      //теперь проверим валидность
      mCRC = 0;
      for (int i1=0; i1 < InPack.SizeDate; i1++){ mCRC = CRC(InPack.Data[i1], mCRC); } 
      if (mCRC == InPack.CRC_Data) { FInPack = 2; }   // это правильные дополнительные данные
      else                         { FInPack = 3; }   // контроль доп данных не сошелся весь пакет выкенем
    }
    break;
  } // ---- while ------
  
  if (FInPack == 2) { 
    if (Id_Unit == InPack.Id_Source) {
      // мы видим входящий пакет от устройства с нашим ID, это ошибка, в сети 2 устройства с одним ID
      FStatus = FStatus | B00000101;
      Id_Unit = 241;    
      Reply.OnReply = false;
    }
    else if (Id_Unit == 0) {
      // это мастер, на нем обрабатываем только пакеты которые мы ожидаем
      // неожиданно пришедшие пакеты пришедшие на мастер пропускаем

      if (   Reply.OnReply 
          && Reply.Id_Destination == InPack.Id_Destination
          && Reply.Id_Source == InPack.Id_Source
          && Reply.Control_1 == InPack.Control_1
          && Reply.Control_2 == (InPack.Control_2 & B00001111)
          ) {
            
       // запускаем подключеную обработку ответа   
       Reply.OnReply = false;
       Reply.Reply_OnStep();    
      }
    }  
    else {
      // это слейв, на нем обрабатываем 
      // 1. ожидаемые ответы
      // 2. широковещательные пакеты
      // 3. новые пакеты от мастера
      if (   Reply.OnReply 
          && Reply.Id_Destination == InPack.Id_Destination
          && Reply.Id_Source == InPack.Id_Source
          && Reply.Control_1 == InPack.Control_1
          && Reply.Control_2 == (InPack.Control_2 & B00001111)
          ) {
        // это ожидаемый пакет    
        // запускаем подключеную обработку           
       Reply.OnReply = false;
       Reply.Reply_OnStep();    
      } 
      // кроме ожидаемых ответов на слейве отрабатываем вариант прихода новой команы
      else if (InPack.Id_Destination == 255) {
        // это широковещательный пакет   
        Reply.OnReply = false;
        OnSlave();
      }
      else if (InPack.Id_Destination == Id_Unit
            && InPack.Id_Source == 0) {
        // это новый пакет от мастера      
        Reply.OnReply = false;
        OnSlave();
      }  
    }
    FInPack = 0;
  }  
  
  if (FInPack > 1) { FInPack = 0; } 
}
kasper007
Offline
Зарегистрирован: 23.05.2016

vde69, это очень универсальный метод. Я тоже в своем проекте передавал информацию по RS485, но у меня было всего два связанных между собой устройства. Чтобы не городить 132 строки дополнительного кода,  я к 10 байтам информации  впереди добавил байт идентификатор, а в конце один байт CRC (организован обыкновенным XOR).  В моем конкретном случаем (с двумя обменивающимися пакетами данных ардуинами) это все заняло 12 строк. И я точно знал, что получившийся пакет именно тот, что передавался (при условии, что CRC принятой посылки совпадал с последним переданным байтом.).

Возможно у автора этой темы нет нужды связывать десятки устройств в одну сеть, а вы его сразу таким фундаментальным подходом :))

bambucho
Offline
Зарегистрирован: 30.08.2014

Через буфер размером в 512 байт (массив) я ее частично решил,но это хламит ОЗУ и происходя не нужные операции.

Т.е. как появляется 0xFE,тупо захватывается 512 байт в буфер и далее буфер "насилуеться" циклами с разбором найденных кадров и представлением (преобразованием) нужных байтов в значения и.т.д. 

vde69
Offline
Зарегистрирован: 10.01.2016

bambucho пишет:

Через буфер размером в 512 байт (массив) я ее частично решил,но это хламит ОЗУ и происходя не нужные операции.

Т.е. как появляется 0xFE,тупо захватывается 512 байт в буфер и далее буфер "насилуеться" циклами с разбором найденных кадров и представлением (преобразованием) нужных байтов в значения и.т.д. 

буфер на 512 байт ??? нафиг он такой нужен? буфер нужен размером одной команды (кадра), если у Вас много данных - делаете несколько кадров...

напомининаю буфер Serial 64 байта, по этому размер одного кадра более 64 байт делать уже опасно (чревато потерями)...

vde69
Offline
Зарегистрирован: 10.01.2016

если хотите могу дать исходники для своего протокола по RS485, единственное отличие Вашего случая - это дуплекс...

bambucho
Offline
Зарегистрирован: 30.08.2014

Дуплекс не требуется,т.к. планируется только слушать и дешифровывать кадры.

В идеале бы CAN (позволит иметь одну шину между множеством устройств (TWI/I2C не годится)),но это для меня пока очень сложно,требует смены "камней" и прочей перефирии/блоков взаимодействия.

Вся эта затея для чтения протокола mavlink (полетного контроллера).

Есть готовая либа,но что то не идет при компиляции,сначала ругается на либу fastserial,а потом далее по коду...

Интерестно на низком уровне "прочуствовать".

Мне по сути нужны три разновидности кадра,их длина варьируется от (примерно) 20-128 байт.

Нужно уловить каждого из них целиком,за интервал времени не менее 5 сек (кадры циклически по (примерно) два раза пролетают за этот интервал).

Так как алгоритм формирования протока со стороны полетного контроллера мне до конца не известен (между кадрами могут сыпаться 0xFF (посмотрел через монитор порта) в большом объеме от 0-512 байт),поэтому буфер выбрал зверски большой,расчитывая на угад отловить полный (полезный) кадр.

Сам кадр,его структура мне понятна.

Хорошо,если удасться толково выуживать (без программных буфер) на прямую с порта полезный кадр.

 

vde69
Offline
Зарегистрирован: 10.01.2016

тогда берешь терминал, в нем настраиваешь вывод в файл, пишешь несколько часов а потом на компе файл крути как хочешь, не упрешся ни в память ни во что еще...

bambucho
Offline
Зарегистрирован: 30.08.2014

Нужна автономность,контроллер получив от полетного контроллера полезные кадры,проанализировав,выполнил дополнительный функционал на ЛА.

В этот протокол сериализуется вся полезная информация.

vde69
Offline
Зарегистрирован: 10.01.2016

bambucho пишет:

Нужна автономность,контроллер получив от полетного контроллера полезные кадры,проанализировав,выполнил дополнительный функционал на ЛА.

В этот протокол сериализуется вся полезная информация.

извените, а Вы кто? если технический спец по самолетам - Вам это не нужно ибо есть документация...

или Вы планируете вмешиватся в полетное задание миниатюрным устройством? В ФСБ не хотите объяснения давать? :)

Ну а если это какая-то модель квадрокоптера - так привяжите го на тросах с кабелем и снимайте трафик...

bambucho
Offline
Зарегистрирован: 30.08.2014

))) нет,просто радио-авиа любитель.

Это небольшие летательные аппараты,БПЛА.

Да нет же)) какой трафик,я его и так могу по радио линку на километры получить,говорю же,автономность,что бы кнопки на пульте меньше жать.

Просто интерестно поковырять,сделать аппарат более автономным)

vde69
Offline
Зарегистрирован: 10.01.2016

так сначало расковыряйте протокол на земле, для этого не нужно его в воздух поднимать... просто снимите трафик в файл и его ковыряйте, а как все поймете - то только тогда приступайте к автоматизации полета...

 

причина простая, Вы сейчас не видите всей картины в целом и наделаете архитектурных ошибок....

bambucho
Offline
Зарегистрирован: 30.08.2014

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

Алгоритм полетного контроллера не затронут,ронять аппарат дорого и опасно.

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

Сегодня вечером попробую варианты кода предложенные выше)

bambucho
Offline
Зарегистрирован: 30.08.2014

Загрузил код предложенный в сообщении #7,немного подправил,(не уверен) но ситуация вроде похожа на правду,перед нужными байтами пока не вижу потерь.Спасибо.

Но тему не закрывайте)

Еще возможно вопросы возникнут)

bambucho
Offline
Зарегистрирован: 30.08.2014
Отладил программу на mega2560.
Переношу ее на mega328 (Arduino nano 3.0),она не принимает поток на uart,программа не отрабатывает,штатный светодиод не индицирует активность поступающей информации.
На mege 328 uart (serial) единственный,может это в аппаратной части дело?
Программа естетсвенно подправлена для работы на mega 328.  
DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Код в студию.

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

bambucho пишет:

Отладил программу на mega2560.
Переношу ее на mega328 (Arduino nano 3.0),она не принимает поток на uart,программа не отрабатывает,штатный светодиод не индицирует активность поступающей информации.
На mege 328 uart (serial) единственный,может это в аппаратной части дело?
Программа естетсвенно подправлена для работы на mega 328.  

нормально на М328 юарт работает, а код мы должны как смотреть, что ты там на разных платформах понаотлаживал?

bambucho
Offline
Зарегистрирован: 30.08.2014

Код тут не причем.

К 328 Nano, напаян с обратной стороны FTDI контроллер,может он мешает 328й получать поток на RX0?


void setup()

{

    Serial.begin(38400); // устанавливаем последовательное соединение

}






void loop()
{  

	while(Serial.available())
	{
		byte b = Serial.read();
   ....
}

 

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

bambucho пишет:

может он мешает 328й получать поток на RX0?

мешает получить поток чему?

источник и направление потока?

bambucho
Offline
Зарегистрирован: 30.08.2014

Зашил самый простой код,при наличии потока что бы светодиод зажег,так и штатный диод на плате не горит и подцепленный диод не зажигается.

void setup()
{
       Serial.begin(38400); // устанавливаем последовательное соединение
       pinMode(3, OUTPUT); 
}

void loop()
{  
       while(Serial.available())
	{
		byte b = Serial.read();
                digitalWrite(3, 1);    
       	} // while
}

 

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

ерунда какая-то - заюзай эхо для аппаратной отладки

if (Serial.available()) {
Serial.write(Serial.read()); 
digitalWrite(3, !digitalRead(3));
}

 

bambucho
Offline
Зарегистрирован: 30.08.2014

Нет,нет активности входящего потока на 328,видать FTDI мешает.

Такую же проблему наблюдал и на mega 2560,если поток подавать на uart0 (он в связке с другой микрухой,которая с USB общается).

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

bambucho пишет:

видать FTDI мешает.

чему мешает FTDI?

ты чем шлёшь инфу в контроллер?

bambucho
Offline
Зарегистрирован: 30.08.2014

Из 2560.

Такая связка работала 2560>2560.

Соеденены tx>rx;земли;+питание.

При поступающем потоке должен мерцать диод (штатный).

Я не знаю как она мешает (догадки),но должно работать.Значит нужно что о замыкать или в секции Setup указывать.

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

bambucho пишет:

Из 2560.

Такая связка работала 2560>2560.

Соеденены tx>rx;земли;+питание.

так бы и сказал - нужно соединить tx->rx, rx->tx двух контроллеров, а всё остальное отключить нафиг

bambucho
Offline
Зарегистрирован: 30.08.2014

Это я знаю,но не воркет:

2560(tx)>(rx)328

Земля и + соеденены.

USB у обоих контроллеров из компа вытащены.

Нет активности светодиода на плате 328,оповещающего о входящем потоке)

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

bambucho пишет:

USB у обоих контроллеров из компа вытащены.

а, это тут при каких делах?

у тебя к RX, TX контроллеров не должно быть ничего не подключено аппаратно - при чём тут USB и комп?

bambucho
Offline
Зарегистрирован: 30.08.2014

У Вас имеется в наличии плата с контроллером (328 или 2560) и с напаянным FTDI или иным хостом.

Попробуйте передать информацию на тот пин,к которому параллельно подключен/напаян FTDI или иной хост.

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

bambucho пишет:

У Вас имеется в наличии плата с контроллером (328 или 2560) и с напаянным FTDI или иным хостом.

Попробуйте передать информацию на тот пин,к которому параллельно подключен/напаян FTDI или иной хост.

у меня не имеется платы с напаянным FTDI или иным хостом - у меня имеются платы с V-USB хостом(но это другая песня и к сериалу никакого отношения не имеет)

*ещё раз повторяю - у тебя не должно быть ничего подключено к сериалу одного контроллера, кроме RX-TX другого контроллера.

bambucho
Offline
Зарегистрирован: 30.08.2014

)))

А как мне быть,если у меня 328 с напаянным FTDI,т.е. он параллельно подключен к нужному пину.

Чтож придется заказывать 328 без FTDI.

Вспомнил,есть у меня mega8 в чистом виде,попробую заюзать ее.

Она будет работать с тем же кодом?

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

bambucho пишет:

Она будет работать с тем же кодом?

чем твой код как-то оригинален от чего-то ещё?

write - записать в порт на одном контроллере.

read - считать из порта на другом контроллере.

условие передачи - линия RX, TX

bambucho
Offline
Зарегистрирован: 30.08.2014

Проверил,328 без припаянных контроллеров типа FTDI,данные по serial получает (от других источников).