modbus 写多个保持寄存器时遇到的问题 已解决
#include#include #include #define RX_PIN 13 #define TX_PIN 15 RS485Class RS485(Serial2, RX_PIN, TX_PIN,-1,-1); uint16_t msg[3] = {0x0041,0x0042,0x0043}; void setup() { M5.begin(true,true,true); if (!ModbusRTUClient.begin(9600, SERIAL_8E1)) { Serial.println("Failed to start Modbus RTU Client!"); return; } ModbusRTUClient.beginTransmission(0x01,HOLDING_REGISTERS,1,3); int i=3; uint16_t *p = msg; while(i){ if(!ModbusRTUClient.write(*p)){ Serial.println(ModbusRTUClient.lastError()); return; } p++; i--; } ModbusRTUClient.endTransmission(); } void loop() { }
设置的从站id是1,可是modbus slave软件的记录里收到的从站地址(即第一个字节)却是不对的,如下
正确的应该是01 10 00 01 00 03 06 00 41 00 42 00 43 6A AF,从站id为1时最后的校验码是6A AF
尝试将波特率调整为115200,这时前几字节数据也不对,如下
第一个字节变成了00,然后是正确的从站id等数据
在仅使用holdingRegisterWrite()函数写单个寄存器时,这种情况也出现了(起初我以为写单个寄存器时没有首字节异常的问题),下面是代码及记录
#include#include #include #define RX_PIN 13 #define TX_PIN 15 RS485Class RS485(Serial2, RX_PIN, TX_PIN,-1,-1); uint16_t x = 0; int i = 5; void setup() { M5.begin(true,true,true); if (!ModbusRTUClient.begin(9600, SERIAL_8E1)) { Serial.println("Failed to start Modbus RTU Client!"); return; } } void loop() { if(!ModbusRTUClient.holdingRegisterWrite(1,1,x)){ Serial.print("Failed to write holdingRegister! "); Serial.println(ModbusRTUClient.lastError()); } x++; i--; if(i == 0){ ModbusRTUClient.end(); return; } delay(1000); }
所以解决这类问题的方法就是先发一帧无用的数据,再发有效的数据
我试着直接向串口写16进制数据,发现收到的数据中第一个字节仍然不对
#include#define RX_PIN 13 #define TX_PIN 15 int i = 8; uint8_t s[8] = {0x02,0x06,0x00,0x04,0x13,0x88,0xC5,0x6E}; uint8_t *p = s; void setup() { M5.begin(true,true,true); Serial2.begin(9600, SERIAL_8E1, RX_PIN, TX_PIN); } void loop() { while(i){ Serial2.write(*p); p++; i--; } delay(1000); }
直接向串口写字符数据
电脑端收到的数据仍然有问题
#include#define RX_PIN 13 #define TX_PIN 15 int i = 5; char *s = "hello"; void setup() { M5.begin(true,true,true); Serial2.begin(9600, SERIAL_8E1, RX_PIN, TX_PIN); } void loop() { while(i){ Serial2.write(*s); s++; i--; } delay(1000); }
但是从电脑端向485设备写数据,设备端收到的却与发送的数据完全一致,可正常显示在IotBase的屏幕上
解决方法很简单 在设备初始化后加个延时就好