请注意,我目前正在使用arduino和RS485模块进行Modbus项目,我在接收框架时遇到了问题,有时我将其装满并纠正了,有时没有什么影响应该作为输出值。这是我的代码:
uint8_t data[9];
uint16_t data1;
CustomSoftwareSerial* RS485;
static byte tension[] = {0x01, 0x03, 0x00, 0x12, 0x00, 0x02, 0x64, 0x0E};
while (RS485->available())
{
RS485->readBytes(data, 9);
String data1 = String(data[3], HEX) + String(data[4], HEX) + String(data[5], HEX) + String(data[6], HEX);
const char modbus_data[data1.length() + 1];
data1.toCharArray(modbus_data, data1.length() + 1);
union
{
uint32_t i;
float f;
} voltage;
voltage.i = strtoul(modbus_data, NULL, 16);
Serial.print("Frame Tension L3 : ");
Serial.println(data1);
Serial.println();
Serial.print("L3-V = ");
Serial.print(voltage.f, 2);
Serial.println(" V");
}这是一个显示示例:Monitor serial here
我认为我必须检查并计算CRC,我不知道如何将其集成到我的代码中?
我需要您的帮助
char modbus_data[64] = {'\0'}; // define globaly
char hex_buffer[4] = {'\0'}; // define globaly its a helper for HEX conversion
// tension => voltage (tech. correct)
static byte tension[] = {0x01, 0x03, 0x00, 0x12, 0x00, 0x02, 0x64, 0x0E}; // define globaly
uint8_t data[9];
//uint16_t data1; wedo not need this
CustomSoftwareSerial* RS485;
while (RS485->available()) {
RS485->readBytes(data, 9);
// replaced String(data[3], HEX) + String(data[4], HEX) + String(data[5], HEX) + String(data[6], HEX);
for (uint8_t i=3;i<7;i++){
ultoa(data[i], hex_buffer, 16); // convert to base 16
strcat (modbus_data, hex_buffer );
}
77 Not needed data1.toCharArray(modbus_data, data1.length() + 1);
union
{
uint32_t i;
float f;
} voltage;
voltage.i = strtoul(modbus_data, NULL, 16);
Serial.print("Frame tension L3 : ");
Serial.println(data1);
Serial.println();
Serial.print("L3-V = ");
Serial.print(voltage.f, 2);
Serial.println(" V");
}
缺少的是一种计时器,可以防止对数据进行缓冲。您的序列看起来像是典型的缓冲区溢出。然后再次为某些值工作。尝试设置为非阻塞状态(使用节省费用计时器)
unsigned long timeStamp = 0; unsigned long timeDelay = 2000; // 2sec if (millis() - timeStamp < timeDelay ){ // Your timed function here timeStamp = millis(); // reset timer }
希望这会有所帮助-有关crc的信息,请参见emodbus files here您会发现一个crc function here。只需避免String转换,请使用char函数!