在在上一教程中,我们学习了有关与Arduino作为从站的Modbus RS-485串行通信的信息。在今天的后续文章中, Arduino将被用作MODBUS主站并与MODBUS从站进行通信。此处已安装MODBUS Slave软件的计算机将用作MODBUS Master。因此,我们首先简要介绍一下RS-485和Modbus 。
RS-485串行通信
RS-485是异步串行通信协议,不需要时钟。它使用一种称为“ 差分信号”的技术将二进制数据从一个设备传输到另一个设备。当使用两根导线和全双工需要四根导线时,它提供半双工通信。
将RS-485与Arduino连接
RS-485模块可以连接到具有以下功能的任何微控制器:串行端口。为了将RS-485模块与微控制器一起使用,需要一个基于Maxim MAX485 IC 的名为 5V MAX485 TTL到RS485的模块,因为它可以实现1200米长距离的串行通信。它是双向半双工的,数据传输速率为2.5 Mbps。该模块需要5V的电压。
RS-485的插针输出:
《表边框=“ 1” cellpadding =“ 0” cellspacing =“ 0”》 引脚名称 使用 VCC 5V A 同相接收器输入同相驱动器输出 B 反相接收器输入反相驱动器输出 GND GND(0V) R0 接收器输出(RX引脚) RE 接收器输出(低启用) DE 驱动器输出(高启用) DI 驱动程序输入(TX引脚)
这是USB到支持WIN7,XP,Vista,Linux,Mac OS的RS485转换器适配器模块,并通过使用计算机中的COM端口提供易于使用的RS485接口。 即插即用设备。没有命令结构,发送到虚拟COM端口的任何内容都会自动转换为RS485,反之亦然。该模块完全由USB总线自供电。 因此,无需外部电源即可操作。
它显示为串行/COM端口,并且可从应用程序或超级终端访问。此转换器提供半双工RS-485通信。波特率范围为75 bps至115200 bps,最大速率为6 Mbps。
要使用此设备,互联网上提供了各种Modbus软件。在本教程中,使用了名为 Witte Software的Modbus Slave软件的软件。可以从网站www.modbustools.com下载该软件。
Modbus从站软件
Modbus从站应用程序接收值使用串行通讯端口从任何Modbus主设备上进行连接。它是一个数据通信测试软件。在使用该软件之前,必须了解以下内容。有关更多信息,请参阅软件手册。
从站ID:
网络中的每个从站都分配有一个唯一的单元地址,范围为1到127。 masterrequests数据,它发送的第一个字节是从设备地址。这样,每个从站都会在第一个字节之后知道是否忽略该消息。
Modbus寄存器:
离散输出线圈:它是一个1位寄存器,用于控制离散输出,并且可以读取或写入。它们的寄存器号为(1到9999)。
离散输入:这是一个1位寄存器,用作输入,只能读取。它们的寄存器号为(10001到19999)。
输入寄存器:这是一个用于输入的16位寄存器,只能读取。它们的寄存器号为(30001到39999)。
保持寄存器:这是一个16位寄存器,可以读取或写入。它们的注册号为(40001到49999)。
Modbus功能代码:
《表边框=“ 1” cellpadding =“ 0” summary = “此表显示了功能代码,其动作
及其影响的表“》
功能代码 动作 表名称 04(04hex) 读取 模拟输入寄存器 03(03hex) 读取 模拟输出保存寄存器 06(06hex) 写入单个 模拟输出保持寄存器 16(10hex) 写入多个 模拟输出保持注册
支持的线圈功能代码:
及其影响的表”》
功能代码操作表名
02(02hex )阅读Di特殊的输入触点
01(01hex)Read离散输出线圈
05(05hex)写单个离散输出线圈
15(0Fhex)写多个离散输出线圈
CRC:
CRC代表循环冗余校验。在每个Modbus消息的末尾添加了两个字节,用于错误检测。
所需的组件
Arduino UNO
MAX-485 TTL转RS-485转换器模块
USB转RS-485转换器模块
按钮(2)
10k电阻器(2)
16x2 LCD显示屏
10k电位器
软件
Modbus从站
电路图
MAX-485 TTL至RS-485转换器模块与Arduino之间的电路连接UNO:
Arduino UNO MAX-485 TTL转RS-485转换器模块
0(RX)RO
1(TX)DI
3DE
2RE
+ 5VVCC
GNDGND
MAX-485 TTL至RS-485模块与USB至RS-485转换器之间的电路连接:
MAX-485 TTL到RS-485
转换器模块USB转RS-485模块
已与PC连接
AA
BB
Arduino UNO和16x2 LCD显示器之间的电路连接:
《表border =“ 1” cellpadding =“ 0” cellspacing =“ 0”》
16x2 LCD
Arduino UNO
VSS
GND
VDD
+ 5V
V0
至电位计中心引脚,用于LCD对比度控制
RS
8
RW
GND
E
9
D4
10
D5
11
D6
12
D7
13
A
+ 5V
K
GND
两个具有下拉电阻10k的按钮也连接到Arduino的引脚4和5。 10K电位器用于向Arduino引脚A0提供模拟输入值。
电路连接后,完整的设置如下所示。
将Arduino Uno编程为MODBUS Master
在本教程中,Arduino Uno通过使用来配置为Modbus Master Master Modbus Arduino编码g在Modbus Master库的帮助下。这里Arduino Uno有两个按钮和一个电位计,可将值从Modbus Master Arduino发送到Modbus Slave软件。
要在Arduino UNO中使用Modbus,需要一个库 被使用。该库用于通过RTU协议与RS-485 Modbus主站或从站进行通信。下载Modbus主站,并按照素描-》包含库-》添加.zip库在草图中添加该库。
完整的程序,并附有详细的视频。在这里,我们解释了以下主要步骤。
首先,包括ModbusMaster和液晶库:
#include
#include
接下来定义连接在MAX485 TTL到RS-485转换器模块和Arduino UNO之间的引脚名称。
#define MAX485_DE 3
#define MAX485_RE_NEG 2
初始化类的节点对象 ModbusMaster 。
ModbusMaster node;
然后编写两个函数 preTrasnmission()和 postTrasmission()用于使Max485 TTL到RS-485转换器模块的RE和DE引脚高或低以发送或接收数据。
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
下一步,在 void设置()中,将LCD设置为16x2模式,并显示并清除欢迎消息。
lcd.begin(16,2);
lcd.print(“CIRCUIT DIGEST”);
delay(3000);
lcd.clear();
lcd.print(“Arduino”);
lcd.setCursor(0,1);
lcd.print(“Modbus Master”);
delay(3000);
lcd.clear();
然后将RE和DE引脚设置为OUTPUT引脚,将引脚4和5设置为INPUT引脚(按钮)。
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
pinMode(4,INPUT);
pinMode(5,INPUT);
最初,将MAX-485 TTL到RS-485转换器模块的DE和RE引脚设置为LOW
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
将波特率设置为115200,并用从站ID 1通知Modbus主站。
Serial.begin(115200);
node.begin(1, Serial);
之后,使用回调语句,以便RS-485收发器已正确配置。
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
现在位于 void loop()
首先从与电位计连接的A0引脚读取模拟值。
float value = analogRead(A0);
然后,使用以下语句将(0到1023)的ADC值写入0x40000寄存器,以将其发送到Modbus从站。
node.writeSingleRegister(0x40000,value);
然后该值也显示在16x2 LCD显示屏上
lcd.setCursor(0,0);
lcd.print(“POT Val :”);
lcd.print(value);
接下来,两个按钮的状态为
int a= digitalRead(4);
int b= digitalRead(5);
,并且取决于th的状态e按钮,将按钮1的值0x40001和按钮2的值0x40002写入Modbus从站,并显示在LCD显示屏上。
if (a == 1)
{
node.writeSingleRegister(0x40001,1);
lcd.setCursor(0,1);
lcd.print(“S1: 1”);
}
else
{
node.writeSingleRegister(0x40001,0);
lcd.setCursor(0,1);
lcd.print(“S1: 0”);
}
if (b == 1)
{
node.writeSingleRegister(0x40002,1);
lcd.setCursor(8,1);
lcd.print(“S2: 1”);
}
else
{
node.writeSingleRegister(0x40002,0);
lcd.setCursor(8,1);
lcd.print(“S2: 0”);
}
将Arduino UNO测试为RS485 MODBUS主设备
在电路连接完成并将代码上传到Arduino Uno之后,现在是时候将USB连接到RS-485模块了
注意:打开设备管理器,并根据连接了USB到RS-485模块的PC并检查COM端口。然后打开Modbus Slave软件。
1。Modbus Slave Tool出现如下,指示 No Connection。
2。下一步打开 Connection-》 Connect ,它显示如下。
3。由于该软件是试用版,因此会显示以下对话框,因此请点击稍后注册
4。此试用版软件打开后仅运行10分钟。
5。连接细节如下所示。将连接设置为串行端口,并将串行设置设置为连接USB到RS-485模块的COM端口。然后将波特率设置为115200 (就像我在Arduino代码中使用的一样),将数据位设置为8 ,无奇偶校验, 1停止位和“模式”作为RTU,然后单击“确定”。
6。请注意,无连接消失,现在打开设置-》从站 定义。
7。现在,将从站ID 输入为1,将功能输入为03 保留寄存器和地址0 ,然后单击确定。/p》
8。之后,确认ID为1,F为03。在本教程中,将使用前三个寄存器(0电位ADC值,1-按钮值,2-按钮值)。
9。现在,当按下按钮2时。注意第三行中的值1。由于未按下按钮1,它在第二行中保持为0,在第一行中显示了一些底池值。
10。按下按钮1时。注意第二行中的值1。并且由于没有按下按钮2,因此它在第三行中保持为0,在第一行中显示了一些底池值。
11。现在,当同时按下两个按钮时,第二行和第三行中都有值1,并记下电位计值。
12。当电位计变化时,行1在Modbus从站软件中也会变化。
这是 RS-485 Modbus可以与Arduino UNO作为主机进行串行通讯。请查看上一教程,以了解Arduino Uno在MODBUS通讯中作为从机。
查找完整的代码并下面的演示视频
》代码
#include //使用ModbusMaster的库
#include //使用LCD显示屏的库
#define MAX485_DE 3
#define MAX485_RE_NEG 2
ModbusMaster节点;//ModbusMaster类的对象节点
LiquidCrystal lcd(8,9,10,11,12,13);//带有LCD引脚(RS,E,D4,D5,D6,D7)并与Arduino UNO连接的液晶类液晶显示器的对象LCD。
void preTransmission()//用于设置引脚DE的stste的函数RS-485
{
digitalWrite(MAX485_RE_NEG,1)的&RE
digitalWrite(MAX485_DE,1);
}
无效postTransmission()
{
digitalWrite(MAX485_RE_NEG,0);
digitalWrite(MAX485_DE,0);
}
void setup()
{
lcd.begin(16,2);
lcd.print(“ CIRCUIT DIGEST”);
delay(3000) ;
lcd.clear();
lcd.print(“ Arduino”);
lcd.setCursor(0,1);
lcd.print(“ Modbus Master”);
delay(3000);
lcd.clear();
pinMode(MAX485_RE_NEG,OUTPUT);
pinMode(MAX485_DE,OUTPUT);
pinMode(4,INPUT);
pinMode(5,INPUT);
digitalWrite(MAX485_RE_NEG,0);
digitalWrite(MAX485_DE,0);
Serial.begin(115200);//波特率为115200
node.begin(1,Serial);//从站ID为1
node.preTransmission(preTransmission);//正确配置RS-485收发器的回调
node.postTransmission(postTransmission);
}
void loop()
{
float值= AnalogRead(A0);
node.writeSingleRegister(0x40000,值);//将值写入保存寄存器的0x40000
lcd.setCursor(0,0);
lcd.print(“ POT Val:”);
lcd.print(value);
int a = digitalRead(4);//读取按钮的状态
int b = digitalRead(5);
if(a == 1)
{
node.writeSingleRegister(0x40001,1);//将1写入0x40001保持寄存器
lcd.setCursor(0,1);
lcd.print(“ S1:1”);
}
else
{
节点.writeSingleRegister(0x40001,0);//将0到0x40001写入保持寄存器
lcd.setCursor(0,1);
lcd.print(“ S1:0”);
}
if(b == 1)
{
node.writeSingleRegister(0x40002,1);//写入1到0x40002的保持寄存器
lcd.setCursor(8,1);
lcd.print(“ S2:1”);
}
else
{
节点.writeSingleRegister(0x40002,0);//将0到0x40002写入保持寄存器
lcd.setCursor(8,1);
lcd.print(“ S2:0”);
}
}
责任编辑:wv
-
MODBUS
+关注
关注
28文章
1759浏览量
76779 -
Arduino
+关注
关注
187文章
6461浏览量
186549
发布评论请先 登录
相关推荐
评论