В настоящее время я пытаюсь использовать Arduino UNO R3 в качестве ведущего устройства в последовательном протоколе связи Modbus (не TCP / IP). Я безрезультатно пытался использовать устаревшие библиотеки, в основном из-за устаревших зависимостей. В любом случае я решил начать с нуля, и моя текущая цель - записать значение регистра 301 (начальный адрес 300) в идентификатор ведомого устройства "5". Перед подключением к моему ведомому устройству я хочу убедиться, что могу восстановить CR C для кадра в зависимости от того, записываю ли я в регистр 0, 1 или 2. Для записи 1 у меня есть кадр «05 06 01 2D 00 01 D8 7B», и из моих исследований я могу сказать, что «D8 7B» - это 16-битный CR C для данных. Однако проблема в том, что я не могу воспроизвести вывод CR C на моем Arduino. Я считаю, что это связано с тем, как я подготовил и отформатировал свой байтовый массив, но я не уверен. Я плохо понимаю алгоритмы CR C, поэтому я использую библиотеку, любая помощь будет принята с благодарностью.
Следующий код представляет собой небольшую вариацию примера эскиза, предоставленного с vinmenn Библиотека Crc16 .
#include <Crc16.h>
//Crc 16 library (XModem)
Crc16 crc;
void setup()
{
Serial.begin(38400);
Serial.println("CRC-16 bit test program");
Serial.println("=======================");
}
void loop()
{
/*
Examples of crc-16 configurations
Kermit: width=16 poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189
Modbus: width=16 poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37
XModem: width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3
CCITT-False:width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1
see http://www.lammertbies.nl/comm/info/crc-calculation.html
*/
//calculate crc incrementally
byte data[] = {0x05, 0x06, 0x01, 0x2D, 0x00, 0x01};
Serial.println("Calculating crc incrementally");
crc.clearCrc();
for(byte i=0;i<6;i++)
{
Serial.print("byte ");
Serial.print(i);
Serial.print(" = ");
Serial.println(data[i]);
crc.updateCrc(data[i]);
}
unsigned short value = crc.getCrc();
Serial.print("crc = 0x");
Serial.println(value, HEX);
Serial.println("Calculating crc in a single call");
//Modbus
value = crc.Modbus(data,0,7);
Serial.print("Modbus crc = 0x");
Serial.println(value, HEX);
while(true);
}
Ниже приведен вывод последовательной консоли при выполнении вышеупомянутого кода.
CRC-16 bit test program
=======================
Calculating crc incrementally
byte 0 = 5
byte 1 = 6
byte 2 = 1
byte 3 = 45
byte 4 = 0
byte 5 = 1
crc = 0x2C86
Calculating crc in a single call
Modbus crc = 0x5A7B
Я использую программу под названием Modbus Poll чтобы организовать мои байты во фреймы. Ниже приведен снимок экрана с выводом программы.
Опять же, любая помощь приветствуется. Заранее спасибо!
edit: Я не упомянул, как в предоставленных материалах подробно описывается моя проблема. Согласно программе опроса Modbus CR C - это «D8 7B», однако моя последовательная консоль сообщает «0x5A7B»
изменить: я исправил код, чтобы отразить CR C более шести байтов (0, 5 ) и обновил вывод последовательной консоли.
решение: Устранена проблема, изменив value = crc.Modbus(data,0,7);
на value = crc.Modbus(data,0,6);