风筝
发表于: 2019-6-13 11:26:42 | 显示全部楼层

在本篇文章,Arduino作为MODBUS主站(Master)与MODBUS从站(Slave)进行通信。本文中将使用安装MODBUS Slave Software的计算机用作MODBUS从站。那么,让我们首先简要介绍一下RS-485和Modbus。


RS-485串行通信

RS-485是一种异步串行通信协议,不需要时钟。它使用称为差分信号的技术将二进制数据从一个设备传输到另一个设备。当使用两根电线时,它提供半双工通信,而全双工需要4条电线。


RS-485模块可以连接到任何带有串行端口的微控制器。微控制器使用RS-485模块时,需要一个基于Maxim MAX485的5V MAX485 TTL到RS485的模块,因为它允许1200米长距离的串行通信。它是双向和半双工的,数据传输速率为2.5 Mbps。该模块需要5V的电压。

Pinout-of-RS-485.jpg


RS-485模块的引脚输出定义:

引脚名称
描述
VCC
5V
A
非反相接收器输入、非反相驱动器输出
B
反相接收器输入、反相驱动器输出
GND
GND(0V)
R0
接收器输出(RX引脚)
RE
接收器输出使能(低电平有效)
DE
驱动器输入使能(高电平启用)
DI
驱动器输入(TX引脚)

USB转RS-485转换模块:

USB-to-RS-485-Converter-Module.png


这是一个USB转RS485转换器适配器模块,支持WIN7、XP、Linux、Mac OS,并通过使用计算机中的COM端口提供易于使用的RS485接口。该模块是即插即用设备。没有命令结构,发送到虚拟COM端口的任何内容都会自动转换为RS485,反之亦然。该模块完全由USB总线供电。因此,无需外部电源即可运行。


它显示为串行/ COM端口,可从应用程序或超级终端访问。该转换器提供半双工RS-485通信。波特率范围为75 bps至115200 bps,最高可达6 Mbps。


要使用此设备,互联网上提供了各种Modbus软件。在本教程中,使用了来自Witte Software的名为Modbus Slave软件的软件。该软件可从www.modbustools.com网站下载。


Modbus Slave软件

Modbus Slave应用程序通过使用串行通信端口从任何Modbus主站设备接收值。它是一种数据通信测试软件。在使用该软件之前,必须了解以下事项。有关更多信息,请参阅软件手册


SlaveID:网络中的每个从站都分配有1到127的唯一单元地址。当主站请求数据时,它发送的第一个字节是从站地址。这样,每个从设备在第一个字节之后知道是否忽略该消息。

Modbus寄存器:

离散输出线圈:它是一个1位寄存器,用于控制离散输出,可以读取或写入。它们的寄存器编号为(1至9999)。

离散输入:它是一个1位寄存器,用作输入,只能读取。他们有(10001年至19999年)的登记号码。

输入寄存器:用于输入的16位寄存器,只能读取。它们的寄存器编号为(30001至39999)。

保持寄存器:它是一个16位寄存器,可以读写。它们的寄存器编号为(40001至49999)。


Modbus功能代码:

功能代码 操作 表名称
04(04 hex) 读取 模拟输入寄存器
03(03 hex) 读取 模拟输出保持寄存器
06(06 hex) 单个写入 模拟输出保持寄存器
16(10 hex) 多个写入 模拟输出保持寄存器

CRC:CRC代表循环冗余校验。它是在每个Modbus消息的末尾添加两个字节以进行错误检测。


需要的组件

●    Arduino UNO开发板

●    MAX-485 TTL转RS-485转换模块

●    USB转RS-485转换模块

●    1602 LCD显示屏

●    Modbus Slave


电路原理图

MAX-485 TTL至RS-485转换器模块与Arduino UNO之间的电路连接:

Circuit-Diagram-for-RS-485-MODBUS-Serial-Communication-with-Arduino-as-Master.png


带有10k下拉电阻的两个按钮也连接到Arduino引脚4和5。10K电位器用于为Arduino引脚A0提供模拟输入值。

电路连接后,完整设置如下所示。

RS-485-MODBUS-Serial-Communication-with-Arduino-as-Master.jpg


编程Arduino Uno作为MODBUS Master

在本文中,Arduino Uno配置为Modbus Master,通过Modbus Master库编写Master Modbus Arduino代码。在这里,Arduino Uno有两个按钮和一个电位器,用于将Modbus Master Arduino的值发送到Modbus Slave软件。


为了在Arduino UNO中使用Modbus,使用库<ModbusMaster.h>。该库用于通过RTU协议与RS-485 Modbus主站或从站通信。下载Modbus Master并按照Sketch-> include library-> Add .zip Library在草图中添加库。


本文末尾处给出了完整的代码。这里我们解释了下面的一些主要步骤。


首先,包括ModbusMaster和Liquid Crystal库:

  1. #include <ModbusMaster.h>
  2. #include <LiquidCrystal.h>
复制代码

接下来定义MAX485 TTL到RS-485转换器模块和Arduino UNO之间连接的引脚名称。

  1. #define MAX485_DE      3
  2. #define MAX485_RE_NEG  2
复制代码

初始化类ModbusMaster的节点对象。

  1. ModbusMaster node;
复制代码

然后写入两个函数preTrasnmission()postTrasmission(),使Max485 TTL到RS-485转换器模块的引脚RE和DE高或低为发送或接收数据。

  1. void preTransmission()
  2. {
  3.   digitalWrite(MAX485_RE_NEG, 1);
  4.   digitalWrite(MAX485_DE, 1);
  5. }
  6. void postTransmission()
  7. {
  8.   digitalWrite(MAX485_RE_NEG, 0);
  9.   digitalWrite(MAX485_DE, 0);
  10. }
复制代码

接下来在void setup()中,LCD设置为1602模式,并显示欢迎信息。

  1. lcd.begin(16,2);
  2.   lcd.print("CIRCUIT DIGEST");
  3.   delay(3000);
  4.   lcd.clear();
  5.   lcd.print("Arduino");
  6.   lcd.setCursor(0,1);
  7.   lcd.print("Modbus Master");
  8.   delay(3000);
  9.   lcd.clear();
复制代码

然后将RE和DE引脚设置为OUTPUT引脚,将引脚4和5设置为INPUT引脚(按钮)。

  1.   pinMode(MAX485_RE_NEG, OUTPUT);
  2.   pinMode(MAX485_DE, OUTPUT);

  3.   pinMode(4,INPUT);
  4.   pinMode(5,INPUT);
复制代码

最初,MAX-485 TTL到RS-485转换器模块的DE和RE引脚设置为低电平

  1.   digitalWrite(MAX485_RE_NEG, 0);
  2.   digitalWrite(MAX485_DE, 0);
复制代码

将波特率设置为115200,并通过从站ID 1通知Modbus主站。

  1. Serial.begin(115200);
  2. node.begin(1, Serial);
复制代码

之后使用回拨语句,以便正确配置RS-485收发器。

  1.   node.preTransmission(preTransmission);
  2.   node.postTransmission(postTransmission);
复制代码

现在在void loop()函数中:

◾    首先,从与电位器连接的引脚A0读取模拟值。

  1.   float value = analogRead(A0);
复制代码

◾    然后将ADC值(0到1023)写入0x40000寄存器,使用以下语句将其发送到Modbus Slave。

  1. node.writeSingleRegister(0x40000,value);
复制代码

◾    然后该值也会显示在16x2 LCD显示屏上

  1.   lcd.setCursor(0,0);
  2.   lcd.print("POT Val :");
  3.   lcd.print(value);
复制代码

◾    接下来读取两个按钮的状态。

  1.   int a= digitalRead(4);
  2.   int b= digitalRead(5);
复制代码

◾    根据按钮的状态,按钮1的值0x40001和按钮2的0x40002被写入Modbus从站,并显示在LCD显示屏上。

  1.   if (a == 1)
  2.   {
  3.     node.writeSingleRegister(0x40001,1);
  4.     lcd.setCursor(0,1);
  5.     lcd.print("S1: 1");
  6.   }
  7.   else
  8.   {
  9.     node.writeSingleRegister(0x40001,0);
  10.     lcd.setCursor(0,1);
  11.     lcd.print("S1: 0");
  12.   }
  13.   if (b == 1)
  14.   {
  15.     node.writeSingleRegister(0x40002,1);
  16.     lcd.setCursor(8,1);
  17.     lcd.print("S2: 1");
  18.   }
  19.   else
  20.   {
  21.     node.writeSingleRegister(0x40002,0);
  22.     lcd.setCursor(8,1);
  23.     lcd.print("S2: 0");
  24.   }
复制代码

测试Arduino UNO作为RS485 MODBUS Master

电路连接完成后,将代码上传到Arduino Uno,现在可以将USB转RS-485模块连接到安装了Modbus Slave软件的计算机。

注意:打开设备管理器,根据连接USB转RS-485模块的PC检查COM端口,然后打开Modbus Slave软件。

1. Modbus Slave Tool如下所示,表示无连接。

Modebus-Slave-Tool-for-Serial-Communication.jpg

2.下一步打开Connection->Connect...,显示如下。

Connecting-Modebus-Slave-Tool-for-Serial-Communication.jpg

3.它显示以下对话框,因为该软件是试用版,因此请单击“稍后注册”

Register-for-full-version-on-Modebus-Slave-Tool-for-Serial-Communication.jpg


4.  此试用软件仅在打开后运行10分钟。

Trial-version-of-Modebus-Slave-Tool-for-Serial-Communication.jpg


5.  连接细节如下所示。将连接设置为串行端口,将串行设置设置为连接USB转RS-485模块的相应COM端口。然后将波特率设置为115200,数据位为8,无奇偶校验,1个停止位和模式为RTU,然后单击“确定”。

Setup-Modebus-Slave-Tool-for-RS485-Serial-Communication.jpg

6.  请注意,显示No connection,现在打开Setup-> Slave Definition

Set-Modebus-Tool-as-Slave-for-RS485-Serial-Communication.jpg

7.现在Slave ID字段输入1,Function选择03保持寄存器,以及地址设置为0,然后单击OK。

Testing-Modebus-Slave-Tool-for-RS485-Serial-Communication.jpg


8.  之后,将ID验证为1,将F为03.。在本文中,使用前三个寄存器(0-电位器ADC值,1-Push按钮值,2-Push按钮值)。

Setup-Resistors-for-RS-485-MODBUS-Serial-Communication-with-Arduino.jpg

9.  现在按下按钮2。注意第三行中的值1。当没有按下按钮1时,它在第二行中保持为0,在第一行中显示电位器值。

Sending-Data-to-Arduino-using-RS485-Serial-Communication.jpg

10.  按下按钮1时。注意第二行中的值1。并且由于没有按下按钮2所以它在第三行保持为0,第一行中显示电位器值。

Receiving-Data-on-LCD-with-Arduino-using-RS485-Serial-Communication.jpg

11.  现在当按下两个按钮时,在第二行和第三行中都有值1,并且还记下电位计值。

Sending-Data-using-RS485-Serial-Communication-with-Modebus-Slave-Tool.jpg

12.   当电位计变化时,Modbus从站软件中的第1行也会发生变化。

Tested-RS-485-Modbus-for-serial-communication-with-Arduino.jpg

以上就是Arduino UNO作为Master如何进行RS-485 Modbus串行通信。如果有任何建议,请在本帖下面进行回复。


代码

以下本文使用的完整代码: main.rar (868 Bytes, 下载次数: 310)

跳转到指定楼层
HGQ21102
发表于: 2019-9-29 20:38:47 | 显示全部楼层

楼主,你好,main.rar文件打不开,是什么格式了?
回复

使用道具 举报

风筝
发表于: 2019-9-30 10:19:20 | 显示全部楼层

HGQ21102 发表于 2019-9-29 20:38
楼主,你好,main.rar文件打不开,是什么格式了?

rar用WinRAR软件打开,如果打不开,请升级WinRar的软件版本
回复

使用道具 举报

richardgann
发表于: 2020-3-26 18:17:15 | 显示全部楼层

按照这个程序没有实现modbus slave出现数据啊?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 714 | 回复: 1501



手机版|

GMT+8, 2024-12-26 07:15 , Processed in 0.054029 second(s), 8 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表