Устойчивость передачи данных по Serial

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

А вот за это спасибо. Ваше замечание натолкнуло на хорошую идею.

Пока пытался поймать данные на ESP, понял, что устойчиво уходят только те пакеты, которые идут вторыми.
Спасибо @b707 и @Upper (напомнил про полудуплексный режим).
Предположил, что контроллер остался в режиме передачи после отправки команды и не готов принимать ответные данные. Решил будить ESP отправкой пустого пакета, он его не видит, но следующие проходят без всяких проблем.
Для меня это решение. Если вы считаете это костылем, буду рад услышать конструктивные предложения.

Спойлер
//ситываем из порта структуру команды
if (esp.readBytes((byte*)&bufOutESP, sizeof(bufOutESP)))
{
	//считаем контрольный байт
	byte crc = crc8_bytes((byte*)&bufOutESP, sizeof(bufOutESP));
	if (crc == 0)
	{
		//если контроль пройден, отправляем пока еще пустую структуру с данными
		sendData();
		//перебираем значения идентификатра структуры
		if (bufOutESP.val_id == 8)
		{
			//готовим структуру данных в соответствии с командой
			bufOutArduino.val_id = 107;
			bufOutArduino.val_1 = Channels[0].number;
			bufOutArduino.val_2 = Channels[1].number;
			bufOutArduino.val_3 = Channels[2].number;
			bufOutArduino.val_4 = Channels[3].number;
			bufOutArduino.val_5 = Channels[4].number;
			bufOutArduino.val_6 = Channels[5].number;
			//отправляем заполненную структуру
			sendData();
			//очищаем структуру команд
			clearComand();
		}
		if (bufOutESP.val_id == 9)
		{
			//готовим данные под другие команды
		}
	}
	else
	{
		//если контрольный байт неверен - команда повреждена
		//будим ESP пустой структурой
		sendData();
		//готовим ответ, что все плохо
		bufOutArduino.val_id = 101;
		//отправляем
		sendData();
		//очищаем структуру команд
		clearComand();
	}
} 

У меня такое впечатление, что вы не читали ответов совсем.
Вам же обьяснили, что именно выдает readBytes() и почему это нельзя использовать как логическую переменную…
А у вас опять та же фигня:

Такой вариант лучше?

//Считываем из порта структуру данных, нужно 8 байт
if (Serial.readBytes((byte*)&bufOutArduino, sizeof(bufOutArduino)) == 8)
{
	//считаем контрольный байт
	byte crc = crc8_bytes((byte*)&bufOutArduino, sizeof(bufOutArduino));
	if (crc == 0)
	{
		//если контроль пройден, перебираем значения идентификатра структуры		
	}
	else
	{
		//если контрольный байт неверен - данные повреждены
		//добавляем в сообщение все, что удалось принять
		messg = F("data is damaged \n");
		
		//очищаем структуру данных
		clearData();
	}
}
else
{
//если получено больше или меньше 8 байт
	messg = F("data is damaged \n");
	clearData();
}

правильнее

поменяете структуру - не надо будет условия переписывать

Большое спасибо

А может быть есть возможность принудительно перевести serial ESP на прием?
Отправить пакет и сказать “Слушай”, а не будить его снаружи.

Так он и так всегда слушает, никуда переводить не надо.

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

Как, по Вашему, приемник должен понять, что принятый байт - это начало нового пакета и не продолжение предыдущего?

Как вы думаете, какое слово тут записано?

…АТЬМАТЬМАТЬМАТЬМАТЬМАТЬМАТ…

МАТЬ? а почему не ТЬМА?

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

Изменение условия - не основная проблема в задаче передачи структуры между 8bit AVR и 32bit ESP…

@sadman41 я правильно понял? Речь о выравнивании полей структуры?

А что, в ПК не так?

А в Ардуино - 64.

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

А какой МК?)) На ARM буфер в ОЗУ реализован. На AVR ни так, ни сяк.

А у меня почему-то не хочет. После отправки команды на ардуино, первый ответный пакет теряет. И только со второго начинает читать.

Без разницы.
В микросхеме буфер ровно на 1 байт. Информация приходит побитно, ее надо где-то хранить, пока байт не придет целиком.
А все буфера более 1 байта - в оперативной памяти.

В АВР 2 байта по факту вроде. Пока один читаем программой, во второй идут следующие биты.

Да, это и есть грабли невидимые глазу.

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

судя по тому, что у ТС иногда работает - проблем с выравниванием у него нет. Да и не должно быть, на мой взгляд - у него все поля по байту, что там выравнивать.

Никогда не видел выравнивание на границу слова/двойного слова? Когда структура из 6 байтовых элементов занимает в памяти 12-24 байта?