首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RS485 Modbus通信

RS485 Modbus通信
EN

Stack Overflow用户
提问于 2021-03-18 13:33:23
回答 1查看 387关注 0票数 1

我一直在尝试通过Modbus通信使用Arduino从我的电能表中获取电气参数。但是我的代码无法从仪表中获取数据。在这段代码中,我试图从寄存器地址为12的电能表中获取相电压值。

代码语言:javascript
复制
  #include<ModbusMaster.h>
  #define MAX485_DE      3
  #define MAX485_RE_NEG  2
  ModbusMaster node;

  void preTransmission()
  {
    digitalWrite(MAX485_RE_NEG, 1);
    digitalWrite(MAX485_DE, 1);
  }

  void postTransmission()
  {
    digitalWrite(MAX485_RE_NEG, 0);
    digitalWrite(MAX485_DE, 0);
  }

  void setup() {
    pinMode(MAX485_RE_NEG, OUTPUT);
    pinMode(MAX485_DE, OUTPUT);
    // Init in receive mode 
    digitalWrite(MAX485_RE_NEG, 0);  
    digitalWrite(MAX485_DE, 0);  
  
    Serial.begin(9600);  
    //slave ID 1  
    node.begin(1, Serial);  

    Serial.println("Starting Modbus Transaction:");  
    node.preTransmission(preTransmission);  
    node.postTransmission(postTransmission);  
  }

  void loop() {
    static uint32_t i;
    uint8_t j, result;
    uint16_t data[10];

    i++;

    result = node.readInputRegisters(0x30012,2);

    Serial.println("");
  
    if (result == node.ku8MBSuccess) {
      Serial.print("Success, Received data: ");
      for (j = 0; j < 2; j++) {
        data[j] = node.getResponseBuffer(j);
        Serial.print(data[j], HEX);
        Serial.print(" ");
      }
      Serial.println("");
    } else {
      Serial.print("Failed, Response Code: ");
      Serial.print(result, HEX);
      Serial.println("");
      delay(5000); 
    }
    delay(1000);
  }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-19 21:58:31

您正在使用错误的Modbus函数。您应该使用函数0x03 readHoldingRegisters (注意页面底部框架开头的0x03 )。

只需更改这一行:

代码语言:javascript
复制
result = node.readInputRegisters(0x30012,2);

至:

代码语言:javascript
复制
result = node.readHoldingRegisters(12,2);

顺便说一句,你的设置肯定有其他错误,因为你得到的错误代码是0xE2,你应该得到的是0x02,意思是Ilegal Data Address,或者可能是0x01 (Illegal Function),这取决于仪表的固件。也许你应该再检查一下波特率。

您可能还需要在设置循环中使用以下命令将节点的ID设置为0xAA

代码语言:javascript
复制
node.begin(170, Serial);

就像上面有人评论的那样。文档不是很好...

如果您看一下底部的示例数据命令:

代码语言:javascript
复制
aa 03 0001 003C 0DC0

看起来aa是从机地址,03是如上所述的功能代码,003C是要读取的寄存器数(60表示一次性读取仪表中的所有数据)。最后两个字节的0DC0应该是CRC。

如果这是正确的,那么你应该考虑读取寄存器11和12,而不是12-13,如果你想得到相电压:

代码语言:javascript
复制
result = node.readHoldingRegisters(11,2);

再说一次,这只是我对填补文档空白的最好猜测。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66685314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档