亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

如何在 Arduino 中使用 Modbus

组件和用品

Arduino UNO
× 1
Arduino 的专业 RS422 / RS485 扩展板
× 1
USB-to-RS485 转换器
× 1
面包板(通用)
× 1
LED(通用)
× 1
电阻 10k ohm
× 1
电阻 221 ohm
× 1
跳线(通用)
× 1
SparkFun 按钮开关 12mm
× 1

应用和在线服务

Arduino IDE
Modbustester

关于这个项目

Modbus,一种串行通信标准,已经成为事实上的标准通信协议,现在是连接工业电子设备的常用手段。在 Modbus RTU 和 Modbus ASCII 中,RS485 用作物理层。在 Modbus 应用程序中可以将 Arduino 用作从设备(并且有一些限制也可以用作主设备),但需要 RS485 接口。我们的 RS422 / RS485 扩展板是一种完全电流隔离的串行通信扩展板,专为与 Arduino UNO 和其他兼容板(如 Arduino 101、STM Nucleo...

本文档的目的是展示如何与 Arduino UNO 一起创建一个简单的 Modbus 从设备。我们将使用一台 PC 作为 Modbus 主站。

工具和材料

  • Arduino UNO
  • 适用于 Arduino 的 RS485 扩展板
  • 任何用于 PC 连接的 RS485-USB 适配器(或更便宜的)

可选:

  • 面包板
  • 按钮
  • 红色 LED
  • 220 欧姆电阻
  • 10k 电阻
  • 跳线

软件

  • Arduino IDE
  • Modbus 测试仪

接线 RS485:

接线非常简单。您只需将屏蔽的 A 和 B 端子与 Modbus 系统的 A 和 B 线连接。 Y 和 Z 端子不用于此类应用。对于长距离,建议 A 和 B 使用双绞线。

Arduino 接线(可选):

建议在 Arduino 上添加一个 LED 和一个按钮,以查看 Modbus 通信的一些效果。它是可选的,不是必需的。

DIP 开关设置:

RS422/RS485 Shield 带有 3 个 DIP 开关组。您必须为 Modbus 设置这些 DIP 开关,如下图所示。

开关 1:1-OFF 2-ON 3-ON 4-OFF

开关2:1-OFF 2-OFF 3-ON 4-ON

开关 3:1-OFF 或 ON* 2-OFF 3-OFF 4-OFF

*根据 RS422/RS485 屏蔽在 Modbus 线路中的位置,您必须打开或关闭终端电阻。仅当 Shield 位于总线的一端时,才将电阻切换到 ON 位置。在所有其他情况下,关闭终端电阻:

跳线设置:

您可以在盾牌上找到 3 个不同的跳线区域。非常重要的是电源电压的跳线 JP1。 Arduino UNO 内部工作电压为 5V。您必须将此跳线设置到 5V 位置(对于 3.3V 板,例如 Arduino 101 到 3.3V 位置)。

再如上图设置左上角通讯口的跳线。在这种情况下,端口 0 和 1 上的内部 UART 将连接到屏蔽的 RS485 接口。

最后但并非最不重要的是,我们必须为 RX/TX 控制端口设置 Jumper。我们不使用这个 Jumper,因为配置了自动 RX/TX 切换。

在 PC 上安装 Modbus 测试仪软件:

在本例中,我们将使用 PC 作为 Modbus 主站。您必须下载 Modbustester。请将 zip 存档解压缩到硬盘上的新目录。打开软件并更改标记的字段,如下图所示。您必须先连接 USB-RS485 适配器 - 请在 Modbustester 中为此适配器选择正确的 COM 端口。

Arduino 软件:

请将固件加载到 Arduino IDE 中进行编译和编程。

测试您的工作:

现在是时候测试您的工作了!

您可以按下 Modbustester 中的读取按钮。此命令将读取我们新从设备的 8 个字节的内存。在地址 400008 中,您可以找到按钮的状态。地址 400001 - 400006 包含 ADC 端口的值。

使用写入按钮,您可以操作从站中的寄存器。您可以在地址 400007 中输入 0 或 1 以打开或关闭 LED。

代码

  • Arduino UNO 的示例代码
Arduino UNO 的示例代码Arduino
/* * Arduino RS422/RS485 Shield 测试程序 * 版本 1.0 * 版权所有 (C) 2018 Hartmut Wendt www.zihatec.de * *(基于 https://github.com/angeloc/simplemodbusng 的来源)* * * 本程序是免费软件:您可以根据 * 自由软件基金会发布的 GNU 通用公共许可证的条款重新分发和/或修改 * 它,许可证的第 3 版,或 *(由您选择)任何更高版本。 * * 分发此程序是希望它有用,* 但不作任何保证;甚至没有对*适销性或针对特定目的的适用性的暗示保证。有关更多详细信息,请参阅 * GNU 通用公共许可证。 * * 您应该已经收到一份 GNU 通用公共许可证 * 以及该程序。如果没有,请参见 .*/ #include #define ledPin 12 // onboard led #define buttonPin 7 // push button/* 这个示例代码有9个保持寄存器。 6 个模拟输入、1 个按钮、1 个数字输出和 1 个寄存器,用于指示自启动以来遇到的错误。未实现功能 5(写入单线圈),因此我使用整个寄存器和功能 16 来设置 Atmega328P 上的板载 LED。 modbus_update() 方法更新holdingRegs 寄存器数组并检查通信。注意:Arduino 串行环形缓冲区为 128 字节或 64 个寄存器。大多数情况下,您将使用 MAX485 或类似设备通过串行将 arduino 连接到主机。在功能 3 请求中,主机将尝试从您的从机读取数据,并且由于 5 个字节已用于 ID、功能、字节数和两个字节 CRC,因此主机只能请求 122 个字节或 61 个寄存器。在功能 16 请求中,主机将尝试写入您的从机,因为 9 个字节已用于 ID、功能、地址、寄存器数、字节数和两个字节 CRC,因此主机只能写入 118 个字节或 59 个寄存器.使用 FTDI USB 到串行转换器,您可以发送的最大字节数仅限于其内部缓冲区,即 60 字节或 30 个无符号整数寄存器。因此:在功能 3 请求中,主机将尝试从您的从机读取数据,并且由于 5 个字节已用于 ID、功能、字节数和两个字节 CRC,因此主机只能请求 54 个字节或 27 个寄存器。在功能 16 请求中,主机将尝试写入您的从机,并且由于 9 个字节已用于 ID、功能、地址、寄存器数、字节数和两个字节 CRC,因此主机只能写入 50 个字节或 25 个寄存器.由于假设您将主要使用 Arduino 连接到主机而不使用 USB 到串行转换器,因此内部缓冲区设置与 Arduino 串行环形缓冲区相同,为 128 字节。*/ // 使用 enum 指令允许用于添加和 // 删除寄存器的简单方法。这样做可以为您节省 #defining // 每次您想要添加更多寄存器时从属寄存器数组的大小// 并且一瞥会通知您从属寄存器的布局。//////////// ///// 你的奴隶的寄存器 /////////////////enum { // 只需添加或删除寄存器,你就可以了... // 第一个寄存器从地址 0 开始 ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, LED_STATE, BUTTON_STATE, TOTAL_ERRORS, // 保留这个 TOTAL_REGS_SIZE // 功能 3 和 16 的寄存器总数共享相同的寄存器数组};unsigned int holdingRegs[ TOTAL_REGS_SIZE]; // 函数 3 和 16 寄存器数组//////////////////////////////////////// ////////////////void setup(){ /* 参数(长波特率,无符号字符 ID,无符号字符传输使能引脚,无符号整数保持寄存器大小,无符号字符低延迟) 发送使能引脚用于半双工通信以激活 MAX485 或类似以禁用此模式,使用任何小于 2 的值,因为 0 和 1 为 Rx 和 Tx 保留。低延迟延迟使实现变得非标准,但实际上它适用于所有主要的 modbus 主实现。 */ modbus_configure(9600, 1, 6, TOTAL_REGS_SIZE, 0); pinMode(ledPin,输出); pinMode(buttonPin, INPUT); }void loop(){ // modbus_update() 是loop() 中唯一使用的方法。它返回自从站启动以来的总错误 // 计数。您不必使用它,但它对 modbus 主站的故障查找很有用。 HoldingRegs[TOTAL_ERRORS] =modbus_update(holdingRegs); for (byte i =0; i <6; i++) { holdingRegs[i] =analogRead(i);延迟微秒(50); } byte buttonState =digitalRead(buttonPin); // 读取按钮状态 // 将 buttonState 值赋给保持寄存器 holdingRegs[BUTTON_STATE] =buttonState; // 读取 LED_STATE 寄存器值并使用函数 16 字节 ledState =holdingRegs[LED_STATE]; 将板载 LED 设置为高电平或低电平; if (ledState) // 设置 led { digitalWrite(ledPin, HIGH); } else if (ledState ==0) // reset led { //digitalWrite(ledPin, LOW);控股Regs [LED_STATE] =0; } }

示意图

将一些测试组件连接到 Arduino

制造工艺

  1. C# 队列示例:什么是 C# 队列以及如何使用?
  2. 使用按钮通过 PWM 调光灯光
  3. Arduino Gyroscope Game with MPU-6050
  4. Unopad - 带有 Ableton 的 Arduino MIDI 控制器
  5. 带有 Arduino 的简单障碍物传感器
  6. 找到我
  7. Arduino Joystick
  8. 使用热敏电阻有多容易?!
  9. 如何用 Arduino 制作音乐
  10. 如何在 Arduino 中使用 NMEA-0183
  11. 如何制作基于 Arduino 的自动开门
  12. PhoneLocator