# RemoteIO-一个简单的Modbus远程IO板
![x.jpg](//image.lceda.cn/pullimage/QC7yHWRbORDF8aKUYXygnQsn1E4fq7KXm7OjsUlc.jpeg)
![y.jpg](//image.lceda.cn/pullimage/Nib1zZOr8YiOoO2YuACkYd0ooFvJtAdKydhuVcbM.jpeg)
### 更新记录
**20240501:**
1. PCB版本升级到V1.1
2. 修正ADS1115的VDD未正确连接到5v电源的错误.(这里非常感谢[shaoele]指出了电源连接错误)。
3. 电源部分注释对齐。
4. 避开电感底层绕线。
5. 优化DCDC芯片FB反馈线路。
6. 单片机程序部分增加了模拟量输入部分程序,发布版本V40501。
7. 附件中的固件也更新到40501。
### 写在之前
1. 设计中参考了开源广场上的一些开源项目,借鉴了一些电路设计,感谢开源大神。
2. 当前版本的IO板已经完成打样,除了模拟量输入部分的软件功能未实现之外,其余功能均已验证通过,并经过连续4天运行通信无异常。
3. 本次的硬件、程序、调试软件全部开源,欢迎各位小伙伴参考。若准备应用到项目上,请自行进行一些抗干扰和老化测试,并承担因使用产生的风险。
4. 下一个版本计划解决模拟输入的问题,并设计PCF8575扩展IO板。
## 设计背景
本人现从事自动化设备开发工作,平时主要是和PLC、上位机、机械手这些打交道,发现在一些特殊场合或者空间受限的情况下,使用PCB和单片机能更方便地实现功能。所以工作之余在学习电子电路相关知识,为了巩固所学知识,避免一看就会一做就废,所以花了点时间做了这个IO板,通过这个IO板的软硬件设计,来巩固学习的知识。当然,由于知识不足和能力有限,有设计不当或考虑不全的地方,请各位大神指点,万分感谢。
## 模块说明
### 功能简介
基于STM32F103C8T6单片机的Modbus远程IO板,可用于上位机通信、远程控制等场景。
- **主控芯片**:STM32F103C8T6单片机
- **电源**:DC24V
- **输入**:8路隔离数字输入
- **输出**:6路隔离数字输出
- **模拟量输入**:4路16位模拟量输入
- **通信接口**:RS485、以太网、TTL串口、IIC
- **通信参数设置**:通过拨码开关,可以设置站号、波特率,打开与关闭120欧姆的终端电阻
- **工作指示**:一路ERR指示灯,一路RUN指示灯
- **通信协议**:ModbusRTU、ModbusTCP
- **开发环境**:Visual Studio Code
- **开发框架**:PlatformIO+Arduino
- **软件架构**:FreeRTOS+看门狗
- **程序开源**:附件中有HEX程序文件,需要将程序下载到单片机中
- **调试软件**:附件中调试工具,需要通过RS485或网络连接到模块上
### 对外接口
- 使用拔插式端子,方便快速配线。
![bj.png](//image.lceda.cn/pullimage/84BFfEi4PmxUF99y9FTRM9pEPCxuYL0tJcrKH87d.png)
### 详细功能说明
1. **主控芯片**:采用STM32F103C8T6最小开发板。
- 使用源地YD-STM32F103C8T6,TYPE-C接口,做工和质量都不错,个人感觉性价比很高。
- ![yd.jpg](//image.lceda.cn/pullimage/zTE0QubADkX3QNmVszhmTbAkRDu3pQa3EvVodBdv.jpeg)
[看看这个模块](https://item.taobao.com/item.htm?_u=k2qc7to57c3a&id=726246752648&spm=a1z09.2.0.0.34d42e8di4pMLV)
2. **电源**:设计DC24V,实测9-24V都能正常工作。
- 24V为电源正,0V为电源负,PE为接地。
3. **输入**:8路隔离数字输入。
- 使用双向光耦做隔离。
- SS为公共端,X0-X7为输入端口,兼容NPN/PNP输入。
- 设计工作电压DC24V,实测9-26V都能正常工作。
- 输入带有滤波算法,默认5ms。
4. **模拟输入**:使用ADS1115芯片。
- 使用IIC读取ADS1115模拟量芯片数据。
- 使用了电压跟随器提高输入阻抗。
- 4路输入,16位ADC精度。
- 输入电压范围0-5V。
5. **输出**:6路隔离数字输出
- 输出经过光耦进行了隔离。
- PD+和PD-为输出侧电源,由于使用了24V继电器,需供电DC24V。
- 2路NPN输出,输出时与PD-连通。
- 4路继电器输出,COM为公共端,Y2/Y3/Y4/Y5共用COM口,虽然继电器单路最大3A,但COM总电流建议不要超过3A。
6. **通信接口**:RS485、以太网、TTL串口、IIC
- RS485x1:支持Modbus RTU协议。
- TTL串口x1:用于下载程序或打印信息。
- IIC接口x1:用于后续扩展使用。
- 以太网x1:支持Modbus TCP协议,以太网通信通过W5500模块实现,需注意模块引脚方向调整(如果只需要ModbusRTU可以不接这个模块)。
- **注意:模块引脚方向需要修改向下**。
- **注意:模块引脚方向需要修改向下**。
- **注意:模块引脚方向需要修改向下**。
- 下图为对比图
[看看这个模块](https://item.taobao.com/item.htm?_u=k2qc7to57b85&id=620666569256&skuId=4806387853896&spm=a1z09.2.0.0.34d42e8di4pMLV)
![W5500.png](//image.lceda.cn/pullimage/87JEe8kZmRrsQXjAXJAjq6smuBzEW75VFCKgpSai.png)
![xxx.png](//image.lceda.cn/pullimage/3D41ORub8uvdGI0egpshfjN3RaONphV8JX2oCHpV.png)
7. **通信参数**:通过拨码开关,可以设置站号、波特率,打开与关闭120欧姆的终端电阻。
- 站号设置:通过SW1 SW2 SW3组合,来设置站号,详见表一。
- 波特率设置:通过SW4 SW5组合,来设置波特率,详见表二。
- 终端电阻:SW8为ON接入终端电阻,OFF断开终端电阻,详见表三。
**表一**
| 站号 | SW3 | SW2 | SW1 |
| --- | --- | --- | --- |
| 1 | OFF | OFF | OFF |
| 1 | OFF | OFF | ON |
| 2 | OFF | ON | OFF |
| 3 | OFF | ON | ON |
| 4 | ON | OFF | OFF |
| 5 | ON | OFF | ON |
| 6 | ON | ON | OFF |
| 7 | ON | ON | ON |
**表二**
| 波特率 | SW5 | SW4 |
| --- | --- | --- |
| 115200 | OFF | OFF |
| 9600 | OFF | ON |
| 19200 | ON | OFF |
| 38400 | ON | ON |
**表三**
| 终端电阻 | SW8 |
| --- | --- |
| 接入 | ON |
| 断开 | OFF |
8. **工作指示**:一路ERROR指示灯,一路运行指示灯
- ERR指示灯:当IO板出现看门狗超时时,ERR指示灯常量
- RUN指示灯:当IO板开始扫描输入输出时,RUN指示灯以1S间隔闪烁
9. **通信协议**:ModbusRTU、ModbusTCP
- ModbusRTU:标准ModbusRTU协议,程序中只使用了保持寄存器区域,总共20个保持寄存器。
- 默认参数:站号1,波特率115200 8N1,
- ModbusTCP:标准ModbusRTU协议,数据区与ModbusRTU一致。
- 默认IP:192.168.1.168
- 端口:502
- 寄存器地址说明:详见后附的Modbus寄存器说明。
10. **开发环境**:全球最牛逼IDE Visual Studio的弟弟Visual Studio Code。
11. **开发框架**:PlatfromIO+Arduino
- PlatformIO:集成了很多工具,非常好用。
- Arduino:简单好用。
12. **程序架构**:FreeRTOS+看门狗
### 预留的IIC接口
- 板子上预留了一个带5V电源的IIC接口,可以通过IIC接口去再次扩展更多的输入输出口。
### 引脚定义
![dd.png](//image.lceda.cn/pullimage/6VvlbZkex5RdHIzgei4wyeMjdzM0nBbmj4FBwmWk.jpeg)
### 程序软件部分
- [跳转到单片机程序开源地址](https://gitee.com/manrong_2008/remote-io.git)
- [跳转到调试工具软件开源地址](https://gitee.com/manrong_2008/remote-ioguide.git)
### PCB程序下载
- **程序文件**:附件中已包含HEX文件
- **stlink下载**:推荐使用stlink下载器,某宝十来块钱。只需要接3根线,不需要切换模式,方便快捷。[看看stlink](https://item.taobao.com/item.htm?_u=k2qc7to50d81&id=26802964172&skuId=4861485891320&spm=a1z09.2.0.0.29cf2e8dqZ7G7h)
- **串口下载**:需要准备USB转串口工具,板子上已预留下载口,下载时需要将Boot0设置为1,下载后boot0再切换回0。
### Modbus寄存器说明
| Modbus地址 | 参数定义 | 默认值 | 单位 | 范围 | 读写 | 说明 |
| ---------- | ---------- | ---------- | ---------- | ---------- | ---------- |----------|
| 0 | 固件版本号 | 40408 | / | | R | 固件版本号,一位年尾号+2位月份+2位日 |
| 1 | 当前站号 |1 | / | | R | 全off为1,其他按位组合,修改后需重启生效
DIP3 DIP2 DIP1
000:1
001:1
010:2
依次类推,最大为111:7 |
| 2 | 当前波特率 |0 |bps | |R | 全off位115200,,修改后需重启生效
DIP5 DIP4
00:115200
01:9600
10:19200
11:38400 |
| 3 | 参数保存 | 0 | / | | R/W | 写入对应数值后,程序会自动清零
= 10, // 将Modbus寄存器的值保存到EEPROM中
= 20, // 从EEPROM中加载Modbus寄存器的值
= 30, // 重启设备
= 66, // 恢复出厂设置并重启设备 |
| 4 | 输入滤波时间 | 5 | ms | 1-100 | R/W | 输入端口的滤波时间 |
| 5 | MAC地址字节1和2 | 0XCDAB | / | | R/W | 初始化时是以单片机ID自动生成 |
| 6 | MAC地址字节3和4 | 0X12EF | / | | R/W | |
| 7 | MAC地址字节5和6 | 0X5634 | / | | R/W | |
| 8 | IP地址低16位 | 0X01A8 | / | | R/W | 例如:192.168.1.168,修改IP地址后必须重启才会生效。
15:高字节01=1,低字节A8=168
16:高字节C0=192,低字节A8=168 |
| 9 | IP地址高16位 | 0XC0A8 | / | | R/W | |
| 10 | 设备运行时间 | | 秒 | 0-65535 | R | 设备运行时间,重复0-65535,可用于心跳检测 |
| 11 | 输入状态反馈 | | | | R | bit0-bit7分别对应X0-X7 |
| 12 | 输出状态反馈 | | | | R/W | bit0-bit5分别对应Y0-Y5 |
| 13 | 扩展输入状态反馈 | | | | R | bit0-bit7分别对应X10-X17 bit8-bit15分别对应X20-X27 |
| 14 | 扩展输出状态反馈 | | | | R/W | bit0-bit7分别对应Y10-Y17 bit8-bit15分别对应Y20-Y27 |
| 15 | AI0模拟量电压输入 | | | | R | AI0的模拟量电压输入转换的数字量,电压输入范围0-5V,精度0.01V,数字量经过转换公式(测量值\*0.0001818)后得到时实际输入电压值。例如数字值为27415,则输入电压为27415*0.0001818=4.98V。 注:如果读取值为32767,则表似乎模拟输入芯片部分未初始化完成,存在故障。 |
| 16 | AI1模拟量电压输入 | | | | R | 参考AI0计算 |
| 17 | AI2模拟量电压输入 | | | | R | 参考AI0计算 |
| 18 | AI3模拟量电压输入 | | | | R | 参考AI0计算 |
### 配线
![PX.png](//image.lceda.cn/pullimage/fZKtMub7FumAPmmPLdZIxmhWg5yTbFRGxZzPMiDV.jpeg)
## 测试部分
### 使用ModbusPoll软件测试
- 测试软件:我使用的Modbus软件。
链接:https://pan.baidu.com/s/1gVSAOsch675w53tLc9f6kw?pwd=um7m 提取码:um7m 复制这段内容后打开百度网盘手机App,操作更方便哦
- 硬件配线:连接IO板电源,可根据需要连接输出或输入侧的电源。
![yj.jpg](//image.lceda.cn/pullimage/yOjWpdpkGt0qgzKiFb5jMLHhmvWGJbFxcep8e83Q.jpeg)
- 软件:用了ModbusRTU和ModbusTCP同时连接IO板
![通信.png](//image.lceda.cn/pullimage/2E21Kwha3VCiERlSTgZTcG2nhL3ZpNh5JrNWkecb.jpeg)
### 通过ModbusPoll软件修改IP地址
- 例如需要设置IP地址为192.168.10.5。
1. 连接IO板:通过ModbusRTU或者ModbusTCP连接到IO板。
2. IP地址转换16进制:可使用电脑计算器计算,计算16进制得C0.A8.0A,05。
3. 设置IP:地址9设置为0xC0A8,地址8设置为0x0A05。
4. 保存参数:设置地址3为10。
5. 重启:设置地址3为30。
6. 配置完成,IO板的IP地址就修改完成了。
### 使用调试工具软件
- 附件中包含调试工具软件
- 使用方式请查看帮助
![a1.png](//image.lceda.cn/pullimage/SedXHT9QXgzEXBZqUngyddRcZYpvVWYLvRD4S4LZ.jpeg)
## 其他
### 需要手动添加的物料
- 有三种拔插式接线端子不在BOM种,请手动添加:
- 1*6P:物料号:C7247,用量1个
- 1*3P:物料号:C8413,用量1个
- 1*9P;物料号:C31287,用量2个
### 关于一些问题
1. 使用STM32最小开发板:能够快速验证自己的思路,并降低一些想学习的小伙伴复刻难度。
2. 使用W5500模块:考虑一些场合不需要使用以太网时可以不接这个模块。需要注意的是模块的引脚默认是向上的,需要将引脚修改成向下,这可能是比较麻烦的地方。
3. 模拟输入部分:为提高分辨率和提高输入阻抗,模拟电压经过电阻分压后进入运放做的电压跟随器,运放输出再进入ADS1115的输入,所以转换公式为(输入值*4.096/32767)*1.4545。
### 写在最后
再次感谢在网络上开源软硬件的大神们,让我们能站在他们的肩膀上做一些有意义的事情。
24
70
收藏到专辑