Arduino Modbus框架有时正确有时不正确

问题描述 投票:0回答:1

请注意,我目前正在使用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,我不知道如何将其集成到我的代码中?

我需要您的帮助

c++ arduino esp8266 crc modbus
1个回答
0
投票
我已经完善了您的代码。摆脱了将char转换为字符串和返回的转换。阅读评论

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函数!
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.