Передавать данные структуры во внешнюю структуру через serial?
Используя две платы аналогичной архитектуры, я хотел бы отправить содержимое структуры с отправляющей платы на принимающую плату. Я использую UART для передачи данных.
Мой план состоял в том, чтобы заполнить массив начальными данными structs. Перенесите это, а затем распакуйте массив в структуру принимающих плат.
Я не уверен, что это возможный вариант. Распаковка массива кажется довольно жесткой, так как я бы присваивал каждой структурной переменной индекс массива. Это может сработать, но я не совсем уверен, что должен делать это таким образом.
Вот как выглядит мой скетч отправки.
Отправить:
typedef struct NWK_DataReq_t
{
uint8_t state;
uint8_t options;
} NWK_DataReq_t;
//Структура экземпляра
NWK_DataReq_t dataRequest;
void setup()
{
// Дайте ему некоторые значения
dataRequest.state = 2;
dataRequest.options = 4;
Serial.begin(9600);
}
void loop()
{
//установить переменный массив в длину структуры
uint8_t payload[sizeof(dataRequest)];
//скопировать структуру в переменный массив
memcpy(payload,&dataRequest,sizeof(dataRequest));
//отправить каждый элемент структуры, который теперь содержится в массиве полезной
for(int i=0;i < sizeof(payload);i++)
{
//Serial.print(i);
//Serial.print(":");
Serial.println(payload[i]);
}
Serial.println("");
delay(1000);
}
Получите:
typedef struct NWK_DataReq_t
{
uint8_t state;
uint8_t options;
} NWK_DataReq_t;
//Структура экземпляра
NWK_DataReq_t dataRequest;
uint8_t incomingPayload[sizeof(dataRequest)];
void setup()
{
Serial.begin(9600);
Serial.print("Recieve started");
}
void loop()
{
if (Serial.available())
{
//добавление входящих данных в массив
for(int i=0;i<sizeof(dataRequest);i++)
{
uint8_t incomingByte = Serial.read();
incomingPayload[i] = incomingByte;
}
}
//установите значения массива в structs
for (int i= 0;i < sizeof(dataRequest);i++)
{
structIndexPosition = incomingPayload[i];
}
}
structIndexPosition не прикреплен, так как я не был уверен, как я мог бы проиндексировать структуру, или если это правильный подход.
@Womble, 👍1
Обсуждение4 ответа
Зачем идти за водой по мосту?
Доступ к данным в структуре можно получить в виде символьного указателя. Нет необходимости переносить в буфер и т.д.
void loop()
{
...
...
const char* dp = (const char*) &dataRequest;
for (int i = 0; i < sizeof(dataRequest); i++) Serial.print(*dp++);
Serial.println();
delay(1000);
...
...
}
Может быть, трудно экстраполировать, как это получить?
void loop()
{
if (Serial.available() > sizeof(dataRequest)) {
char* dp = (char*) &dataRequest;
for (int i = 0; i < sizeof(dataRequest); i++) *dp++ = Serial.read();
Serial.read();
...
...
}
}
Serial.println() и дополнительный Serial.read() могут быть заменены "маркером кадра" и / или контрольной суммой.
Ваше здоровье!
Хорошо, но как мне заполнить новую структуру с помощью dp?, @Womble
Похоже, какое-то время это работает. У меня есть строка Serial.print(DataRequest.options) для подтверждения. Иногда он достигает 4, но также достигает пары других чисел в циклическом порядке., @Womble
Я думаю, что вы слишком усложняете его, чтобы отправить два байта. Просто отправьте их в виде прямого ASCII с новой строкой после и расшифруйте его на принимающей стороне.
например.
42,87
Однако, если вопрос был просто примером чего-то гораздо более сложного, то вам, возможно, потребуется проделать больше работы. Вам нужно, чтобы принимающая сторона знала, когда начинается и заканчивается пакет данных, и желательно иметь некоторую проверку того, что он не был поврежден. Если вы хотите продолжить эту идею, посмотрите мою тему об отправке данных через RS485, в которой есть библиотека, которая делает подобные вещи.
Спасибо за ссылку, Ник. Это будет сложнее, чем это. Я скоро займусь валидацией, просто хотел разобраться с некоторыми основами., @Womble
Самый простой из возможных способов отправки данных структуры - это:
Serial.write((const uint8_t *)&myData, sizeof(myData));
Получите адрес myData, преобразуйте его в указатель int без знака и, начиная с этого адреса, запишите количество байтов, указанное в sizeof(myData)
. Это позволит передавать необработанные данные структуры через serial, не связываясь с копированием данных в другие массивы, назначением указателей и т.д.
Однако: это не сработает.
Отправка необработанных двоичных данных по serial подобным образом, где serial не имеет понятия ни о чем, кроме байтов, просто невозможно узнать, где в потоке данных вы находитесь. Какой из множества поступающих байтов находится внутри структуры? Кто может сказать?
Итак, вам нужно написать протокол. Метод, при котором один конец сообщает другому концу: "Это начало данных. Это и есть данные. На этом данные заканчиваются ". Но также вы должны быть в состоянии сказать: "Этот бит, который выглядит так же, как сообщение "начало данных", на самом деле является битом данных, а не началом данных". Видите ли, на самом деле это довольно сложная задача.
Если вы не смогли запустить этот код, как я, то все, что вам нужно сделать, это вырезать: " структурный пакет { }; typedef структура пакета Package; Данные о пакете; " И вставьте его в "пустой цикл", и он должен работать нормально. P / s: Большое вам спасибо за это полезное видео, но надеюсь, что вы обновите это в будущем (я предполагаю, что обновление что-то изменило в кодах Arduino)
Как бы то ни было, я смотрю на вопрос и смотрю на ваш ответ, и это выглядит почти так, как будто вы отвечаете на совершенно другой вопрос, чем тот, который был задан. Но я не могу сказать наверняка., @timemage
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Отправить структуру через Serial
- Как получить размер (sizeof) массива структур
- C++ против языка Arduino?
- Как использовать SPI на Arduino?
- Ошибка: expected unqualified-id before 'if'
- Что лучше использовать: #define или const int для констант?
- Функции со строковыми параметрами
Возможно, вы захотите взглянуть на мою библиотеку КМГС. Он обрабатывает этот вид передачи очень чисто и надежно. Не стесняйтесь использовать его, злоупотреблять им, рвать его на куски, красть у него кусочки, учиться на нем, черпать из него идеи, что угодно: https://github.com/MajenkoLibraries/ICSC, @Majenko