Что значит - Посылаем заголовок пакета?

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Всем доброго вечера!
Возникла необходимость передавать данные через радиомодуль по UART.
Нашли пример, но не могу понять что значит Посылаем заголовок пакета.
вот пример кода:
Передача массива и включение светодиода на расстоянии:
byte data[5];                       // Объявляем массив для приёма и хранения данных
                                    //
void setup() {                      //
  Serial1.begin(9600);              // Инициируем последовательный порт на скорости 9600 бод
}                                   //
                                    //
void loop() {                       //
  data[0] = 0;                      // Записываем ноль (ВЫКЛ) в первый байт массива
  Serial1.write(0xAA);              // Посылаем заголовок пакета
  Serial1.write(data, sizeof(data));// Посылаем массив данных
  Serial1.write('\n');              // Посылаем символ новой строки
  delay(500);                       // Ждём полсекунды
  data[0] = 1;                      // Записываем единицу (ВКЛ) в первый байт массива
  Serial1.write(0xAA);              // Посылаем заголовок пакета
  Serial1.write(data, sizeof(data));// Посылаем массив данных
  Serial1.write('\n');              // Посылаем символ новой строки
  delay(500);                       // Ждём полсекунды
}                                   //
Есть предположение, что строкой Serial1.write(0xAA); посылается некий разделитель пакетов, чтобы они не путались.
Так ли это. и что значит (0xAA) - это надо всегда писать или могут быть другие значения.
Если объясните будем очень признательны. Ну или ссылку где про это почитать.
Заранее спасибо!
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Служебное поля для инициации приема нового объема на другой стороне .
0хАА условность. Можно выбрать свою, можно 2 байта, если есть шанс, что 0xAA будет в пакете данных
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Там в приемнике, вот что идет - условие.
C++:
void loop() {                                    //
// Если в буфере порта есть данные и прочитанный байт равен заголовку пакета
  if (Serial1.available() && Serial1.read() == 0xAA){
    // Читаем строку из последовательного порта и конвертируем её в массив байт data  
    Serial1.readStringUntil('\n').toCharArray(data, sizeof(data));                        
    digitalWrite(LED_BUILTIN, data[0]);          // Включаем или выключаем встроенный светодиод, в зависимости от полученных данных
  }
Получается мы должны знать размер отправляемого массива, и указать (отправить) этот размер в шестнадцетиричном виде?
А если без заголовка отправлять данные, то не будет работать? или это просто перестраховка?
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Размер нет. Концом служит символ новой строки, как я понял. Не вникал особо, но размер нигде не передается, хотя можно и так.
Serial1.write('\n'); // Посылаем символ новой строки

Например послать АА, потом размер , потом фигачить данные. Еше и crc можно добавить хитрое, и шифрование.
В данном случае массив data должен иметь СТРОГО ОДИНАКОВЫЙ размер и в приемнике и в передатчике
 

bort707

★★★★★★✩
21 Сен 2020
3,062
912
Получается мы должны знать размер отправляемого массива, и указать (отправить) этот размер в шестнадцетиричном виде?
где вы в этом коде видите, чтобы отправлялся размер массива, да еще и в шестнадцатиричном виде ? :)

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

А если без заголовка отправлять данные, то не будет работать? или это просто перестраховка?
формат отправки должен быть согласован между приемником и передатчиком. Если приемник ждет заголовок - без него работать не будет. Если приемник и передатчик вы пишете сами - можно и без заголовка. Но вообще поверьте моему опыту - с заголовком удобнее и проще
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
0xAA я подумал это 16ричное число? 😣
В комментарии сказано:
// Если в буфере порта есть данные и прочитанный байт равен заголовку пакета
и я подумал это про размер... 😖
Поясните пожалуйста Что такое 0хАА...
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
0xAA это ЧИСЛО записанное в 16-ричном формате, для нас, для людей.
0xAA условное обозначение начала пакета. Автор так сам с собой договорился
 
  • Лойс +1
Реакции: prohor-nastya

bort707

★★★★★★✩
21 Сен 2020
3,062
912
Поясните пожалуйста Что такое 0хАА...
сказано же - это заголовок пакета. Конкретное значение (0xAA = 170) - выбрано "с потолка" и с размером пакета никак не связано.
Это просто красивое число, получив которое, приемник будет знать, что дальше пойдут данные пакета.

и то что оно "шестнадцатиричное" - ровно ничего особенного не значит
Вот так
C++:
Serial1.write(0xAA);
и вот так
C++:
Serial1.write(170);
результат будет одинаковым
 
  • Лойс +1
Реакции: prohor-nastya

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
И добавлю, если передавать русский текст, то код 0xAA может не подойти, он тогда будет соотв. русской букве "к"
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
Спасибо! Про заголовок понял.
про русский текст не понял... Он же просто сравнивает отправленное с таким же значением.
А потом читает строку в массив...
я так понял через заголовки можно в разные массивы отправлять?
Но мы русский текст не будем передавать. в основном float.
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
0хABABABAB Такое редкое? Я честно сказать не в теме какие байты редкие, а какие нет...
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,263
1,301
Москва
Смотря для чего. Для текста редкое, для чисел тоже, для цвета 8-мибитного может быть сплошь и рядом. Разговор ни о чем
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
И вот еще интересный вопрос немного не в тему, то же случай с 16-ричным числом.
адрес трубы задан 16ричным числом (откуда узнаем этот адрес?)
C++:
radio.openWritingPipe (0xAABBCCDD11LL);                    // Открываем трубу с адресом 0xAABBCCDD11 для передачи данных (передатчик может одновременно вещать только по одной трубе).
Здесь адрес трубы задается вообще не понятным мне способом... Можете ктонибудь объяснить, пожалуйста.
C++:
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб

void setup() {
    //
radio.openWritingPipe(address[0]);   //мы - труба 0, открываем канал для передачи данных
    //
}
 

bort707

★★★★★★✩
21 Сен 2020
3,062
912
адрес трубы задан 16ричным числом (откуда узнаем этот адрес?)
мы его сами придумали

Здесь адрес трубы задается вообще не понятным мне способом... Можете ктонибудь объяснить, пожалуйста.
Для компьютера это данные одного типа

0xAABBCCDD11
и
"2Node"

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

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
прошу прощения, Скажите пожалуйста, а что значит LL в конце... 😣
0xAABBCCDD11LL
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
0xAABBCCDD11LL

"Для компьютера это данные одного типа

0xAABBCCDD11
и
"2Node"

и то и другое -всего лишь последовательность из пяти байт. "

А зачем там LL если там должна быть последовательность из пяти байт... И L вообще в 16системе нет. 🤒
В чем смысл.... 🙏🙏🙏
 

bort707

★★★★★★✩
21 Сен 2020
3,062
912
LL - это модификатор типа переменной, к 16-системе не имеет ровно никакого отношения.
LL можно применять и к десятичным числам, например вот так
x = 456789999LL

LL - это означает, что компилятор должен отвести для хранения этого значения не стандартные 2 байта, как для типа int, и даже не 4, как для long. а 8 байт - как для типа long long
 

prohor-nastya

✩✩✩✩✩✩✩
30 Ноя 2020
51
1
🤝👍 спасибо !
Правильно я понял, что если:
int x ;
x = 456789999LL;
то x преобразуется в long long x;
 

bort707

★★★★★★✩
21 Сен 2020
3,062
912
Правильно я понял, что если:
int x ;
x = 456789999LL;
то x преобразуется в long long x;
неправильно, сам по себе x никуда не преобразуется, это я вам не вполне верно написал в прошлом сообщении.

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