Я пытаюсь отправить сообщения через последовательный интерфейс USB моего Arduino (C++) в Paspon Raspberry (Python).Arduino to Raspberry crc32 check
На стороне Arduino я определяю структуру, которую затем копирую в char []. Последняя часть структуры содержит контрольную сумму, которую я хочу вычислить с помощью CRC32. Я копирую структуру во временный массив символов -4 байта, чтобы удалить поле контрольной суммы. Затем контрольная сумма вычисляется с использованием временного массива, и результат добавляется в структуру. Затем структура копируется в byteMsg, который получает передачу по последовательному соединению.
На конце малины я делаю обратное, я получаю bytestring и вычисляю контрольную сумму над сообщением - 4 байта. Затем распакуйте байтовую строку и сравните полученную и вычисленную контрольную сумму, но это, к сожалению, не выполняется.
Для отладки я сравнил проверку crc32 как на python, так и на arduino для строки «Hello World», и они сгенерировали ту же контрольную сумму, что, похоже, не представляет проблемы с библиотекой. Малина также может декодировать остальную часть сообщения просто отлично, поэтому распаковка данных в переменные, похоже, тоже в порядке.
Любая помощь будет высоко оценена.
Питон Код:
def unpackMessage(self, message):
""" Processes a received byte string from the arduino """
# Unpack the received message into struct
(messageID, acknowledgeID, module, commandType,
data, recvChecksum) = struct.unpack('<LLBBLL', message)
# Calculate the checksum of the recv message minus the last 4
# bytes that contain the sent checksum
calcChecksum = crc32(message[:-4])
if recvChecksum == calcChecksum:
print "Checksum checks out"
crc32 библиотека Aruino взяты из http://excamera.com/sphinx/article-crc.html
crc32.h
#include <avr/pgmspace.h>
static PROGMEM prog_uint32_t crc_table[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
unsigned long crc_update(unsigned long crc, byte data)
{
byte tbl_idx;
tbl_idx = crc^(data >> (0 * 4));
crc = pgm_read_dword_near(crc_table + (tbl_idx & 0x0f))^(crc >> 4);
tbl_idx = crc^(data >> (1 * 4));
crc = pgm_read_dword_near(crc_table + (tbl_idx & 0x0f))^(crc >> 4);
return crc;
}
unsigned long crc_string(char *s)
{
unsigned long crc = ~0L;
while (*s)
crc = crc_update(crc, *s++);
crc = ~crc;
return crc;
}
Главная Arduino эскиз
struct message_t {
unsigned long messageID;
unsigned long acknowledgeID;
byte module;
byte commandType;
unsigned long data;
unsigned long checksum;
};
void sendMessage(message_t &msg)
{
// Set the messageID
msg.messageID = 10;
msg.checksum = 0;
// Copy the message minus the checksum into a char*
// Then perform the checksum on the message and copy
// the full msg into byteMsg
char byteMsgForCrc32[sizeof(msg)-4];
memcpy(byteMsgForCrc32, &msg, sizeof(msg)-4);
msg.checksum = crc_string(byteMsgForCrc32);
char byteMsg[sizeof(msg)];
memcpy(byteMsg, &msg, sizeof(msg));
Serial.write(byteMsg, sizeof(byteMsg));
void loop() {
message_t msg;
msg.module = 0x31;
msg.commandType = 0x64;
msg.acknowledgeID = 0;
msg.data = 10;
sendMessage(msg);
С уважением, Thiezn
Спасибо за быстрый ответ! Ясное объяснение и буду реализовывать его сегодня вечером и отчитываться о своих результатах. – thiezn
Я пробовал сериализовать структуру (беря каждый элемент и копируя их в char *, но результат был такого же размера (в этом случае 18 байт). иногда я получал результат контрольной суммы в 0, пока я определенно заполнял структуру данными. Это дало мне догадку о том, что функция crc32 уходит, когда находит строку NULL '\ 0' в строке и после некоторых тестов кажется, что это действительно, дело. Теперь я должен признать, что функция crc32 немного из моей лиги, кто-нибудь знает, как заставить ее обрабатывать символы с завершающим символом NULL? – thiezn
При ближайшем рассмотрении crc_string() я заметил ваше время (* s). Теперь '\ 0' действительно является 0, поэтому ваш цикл * будет * останавливаться всякий раз, когда он встречается с ним. Это недостаток использования строки, а не байтового массива! Таким образом, решение перестает рассматривать его как строку. Не проверяйте (* s), но p по длине вашей «строки» и запустить цикл for на основе этой длины. И наконец: CRC 0 отлично подходит. Все это просто добавление и смещение битов, так что в итоге вы можете получить 0. Особенно с более короткими CRC, которые могут переполняться более легко. – Nathilion