modbus 寫多個保持寄存器時遇到的問題 已解決


#include <M5Stack.h>
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
#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 <M5Stack.h>
#include <ArduinoModbus.h>
#include <ArduinoRS485.h>
#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);
}
View Code

所以解決這類問題的方法就是先發一幀無用的數據,再發有效的數據

我試着直接向串口寫16進制數據,發現收到的數據中第一個字節仍然不對

#include <M5Stack.h>
#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 <M5Stack.h>
#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);
}
View Code

 

但是從電腦端向485設備寫數據,設備端收到的卻與發送的數據完全一致,可正常顯示在IotBase的屏幕上

解決方法很簡單 在設備初始化后加個延時就好


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM