当前位置: 首页 > news >正文

C#有人IO模块USR-IO808的完整指南

C#有人IO模块USR-IO808的完整指南

概述

有人USR-IO808是一款8通道数字输入输出模块,支持Modbus RTU协议,通过RS485接口进行通信。本文将介绍如何使用C#语言通过串口操作该模块,实现数字输入(DI)状态的读取和数字输出(DO)的控制。

硬件连接与配置

在开始编程前,请确保:

  1. USR-IO808模块已正确供电

  2. RS485接口与计算机正确连接(通常通过USB转485转换器)

  3. 模块的波特率、数据位、停止位和校验位与软件设置一致

  4. 模块地址已正确设置(默认为0x11)

核心代码解析

1. 数据包构建类(DataPacketIO808)

public class DataPacketIO808
{// 模块默认地址public const byte AddressDefault = 0x11;// 功能码定义public enum EfunctionNum{read0x02 = 0x02,  // 读取DI状态read0x01 = 0x01,  // 读取DO状态read0x05 = 0x05,  // 控制DO状态}// 控制状态定义public enum EcontrolStatus{open = 0xFF00,   // 开启DOclose = 0x0000,  // 关闭DO}// DI/DO寄存器地址定义public enum EDIDOAddress{DI1 = 0x0020, DI2 = 0x0021, DI3 = 0x0022, DI4 = 0x0023,DI5 = 0x0024, DI6 = 0x0025, DI7 = 0x0026, DI8 = 0x0027,DO1 = 0x0000, DO2 = 0x0001, DO3 = 0x0002, DO4 = 0x0003,DO5 = 0x0004, DO6 = 0x0005, DO7 = 0x0006, DO8 = 0x0007,}// 构建读取DI状态的数据包public static DataPacketIO808 GetDIStatus(byte address){return BuildReadParam(address, EfunctionNum.read0x02, EDIDOAddress.DI1, 8);}// 构建读取DO状态的数据包public static DataPacketIO808 GetDOStatus(byte address){return BuildReadParam(address, EfunctionNum.read0x01, EDIDOAddress.DO1, 8);}// 构建开启DO的数据包public static DataPacketIO808 OpenDO(byte address, ushort DONum){return BuildControlParam(address, EfunctionNum.read0x05, DONum, EcontrolStatus.open);}// 构建关闭DO的数据包public static DataPacketIO808 CloseDO(byte address, ushort DONum){return BuildControlParam(address, EfunctionNum.read0x05, DONum, EcontrolStatus.close);}// 将数据包转换为字节数组public byte[] ToBytes(){lock (Locker){List<byte> bts = new List<byte>{Serialaddress,functionNum,};// 添加地址数据(大端模式)byte[] startArr = BitConverter.GetBytes(startAddress);Array.Reverse(startArr, 0, startArr.Length);bts.AddRange(startArr);// 添加参数数据(大端模式)byte[] controlsta = BitConverter.GetBytes(param);Array.Reverse(controlsta, 0, controlsta.Length);bts.AddRange(controlsta);// 计算并添加CRC校验byte[] checkList = CalcChecksum(bts);bts.AddRange(checkList);return bts.ToArray();}}// CRC校验计算public byte[] CalcChecksum(List<byte> content){UInt16 wCrc = 0xFFFF;for (int i = 0; i < content.Count; i++){wCrc ^= Convert.ToUInt16(content[i]);for (int j = 0; j < 8; j++){if ((wCrc & 0x0001) == 1){wCrc >>= 1;wCrc ^= 0xA001;}else{wCrc >>= 1;}}}byte[] arr = BitConverter.GetBytes((ushort)wCrc);return arr;}
}

2. 数据解析类(DataParseIO808)

public class DataParseIO808
{// 解析返回数据public static bool parseData(byte[] param, byte address, byte funNo){if (param[0] == address && param[1] == funNo){bool crcStatus = CRC_Check(param);if (crcStatus){return true;}}return false;}// CRC校验检查public static bool CRC_Check(byte[] byteData){bool Flag = false;byte[] CRC = new byte[2];UInt16 wCrc = 0xFFFF;for (int i = 0; i < byteData.Length - 2; i++){wCrc ^= Convert.ToUInt16(byteData[i]);for (int j = 0; j < 8; j++){if ((wCrc & 0x0001) == 1){wCrc >>= 1;wCrc ^= 0xA001;}else{wCrc >>= 1;}}}CRC[1] = (byte)((wCrc & 0xFF00) >> 8);CRC[0] = (byte)(wCrc & 0x00FF);if (CRC[1] == byteData[byteData.Length - 1] && CRC[0] == byteData[byteData.Length - 2]){Flag = true;}return Flag;}
}

3. 应用层方法

// 获取所有DI状态
public void GetALLDIStatus(out bool oneStatus, out bool twoStatus, out bool threeStatus, out bool fourStatus, out bool fiveStatus, out bool sixStatus, out bool sevenStatus, out bool eightStatus)
{oneStatus = twoStatus = threeStatus = fourStatus = fiveStatus = sixStatus = sevenStatus = eightStatus = false;try{oneStatus = GetDIStatus(1);twoStatus = GetDIStatus(2);threeStatus = GetDIStatus(3);fourStatus = GetDIStatus(4);fiveStatus = GetDIStatus(5);sixStatus = GetDIStatus(6);sevenStatus = GetDIStatus(7);eightStatus = GetDIStatus(8);}catch (Exception ex){// 异常处理Console.WriteLine("获取DI状态时发生错误: " + ex.Message);}
}// 获取所有DO状态
public void GetALLDOStatus(out bool oneStatus, out bool twoStatus, out bool threeStatus, out bool fourStatus, out bool fiveStatus, out bool sixStatus, out bool sevenStatus, out bool eightStatus)
{oneStatus = twoStatus = threeStatus = fourStatus = fiveStatus = sixStatus = sevenStatus = eightStatus = false;try{oneStatus = GetDOStatus(1);twoStatus = GetDOStatus(2);threeStatus = GetDOStatus(3);fourStatus = GetDOStatus(4);fiveStatus = GetDOStatus(5);sixStatus = GetDOStatus(6);sevenStatus = GetDOStatus(7);eightStatus = GetDOStatus(8);}catch (Exception ex){// 异常处理Console.WriteLine("获取DO状态时发生错误: " + ex.Message);}
}

完整使用示例

// 创建串口对象
SerialPort serialPort = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();// 读取所有DI状态
bool di1, di2, di3, di4, di5, di6, di7, di8;
GetALLDIStatus(out di1, out di2, out di3, out di4, out di5, out di6, out di7, out di8);Console.WriteLine("DI状态:");
Console.WriteLine($"DI1: {di1}, DI2: {di2}, DI3: {di3}, DI4: {di4}");
Console.WriteLine($"DI5: {di5}, DI6: {di6}, DI7: {di7}, DI8: {di8}");// 控制DO1开启
DataPacketIO808 openPacket = DataPacketIO808.OpenDO(0x11, 1);
byte[] openData = openPacket.ToBytes();
serialPort.Write(openData, 0, openData.Length);// 等待并读取响应
Thread.Sleep(100);
byte[] response = new byte[serialPort.BytesToRead];
serialPort.Read(response, 0, response.Length);// 验证响应
bool success = DataParseIO808.parseData(response, 0x11, 0x05);
if (success)
{Console.WriteLine("DO1开启成功");
}// 关闭串口
serialPort.Close();

注意事项

  1. 线程安全:使用lock确保在多线程环境下串口操作的线程安全

  2. 异常处理:妥善处理可能出现的串口通信异常

  3. 超时设置:合理设置读取超时,避免程序无响应

  4. CRC校验:务必验证CRC确保数据完整性

  5. 地址匹配:确保程序中使用的模块地址与实际硬件设置一致

常见问题排查

  1. 通信失败:检查硬件连接、串口参数和模块地址

  2. CRC校验错误:检查数据传输过程中是否受到干扰

  3. 无响应:检查模块供电和通信线路

总结

通过上述C#代码,我们可以方便地操作有人USR-IO808模块,实现数字输入状态的读取和数字输出状态的控制。代码采用了面向对象的设计,提供了良好的封装性和可扩展性,可以根据实际需求进一步扩展功能。

希望本文对您使用USR-IO808模块有所帮助!


文章转载自:

http://lG5MwwWO.gychx.cn
http://UKySxgHR.gychx.cn
http://LvzEKGJ7.gychx.cn
http://w1YHMPnE.gychx.cn
http://9O3pUzgN.gychx.cn
http://X2icUyD5.gychx.cn
http://ADbM48S6.gychx.cn
http://xAYXecfL.gychx.cn
http://KE0jPnvY.gychx.cn
http://TxsY9Tli.gychx.cn
http://VcLB52CK.gychx.cn
http://JNQ6Qan1.gychx.cn
http://ZwzOgxZa.gychx.cn
http://wiwNcPE4.gychx.cn
http://B5chfP7W.gychx.cn
http://DxMDDuZJ.gychx.cn
http://9u7kQqrh.gychx.cn
http://9zkE1fWR.gychx.cn
http://RethqucW.gychx.cn
http://ROMYLd0d.gychx.cn
http://SYUjlGeO.gychx.cn
http://NdUkit0y.gychx.cn
http://8lU6dguL.gychx.cn
http://sUtYwGRi.gychx.cn
http://sBNcZAPr.gychx.cn
http://0eRWwHL1.gychx.cn
http://bKPcb7Ps.gychx.cn
http://K4fcLKEl.gychx.cn
http://4iIim2i2.gychx.cn
http://5swq3vFQ.gychx.cn
http://www.dtcms.com/a/371696.html

相关文章:

  • Apache Dubbo学习笔记-使用Dubbo发布、调用服务
  • CTFshow系列——PHP特性Web97-
  • Photoshop - Photoshop 创建图层蒙版
  • DevOps实战(3) - 使用Arbess+GitLab+Hadess实现Java项目自动化部署
  • Python从入门到精通_00_初识python
  • LabVIEW 与 PLC 通讯
  • 项目介绍:图像分类项目的最小可用骨架--代码细节讲解
  • 【.Net技术栈梳理】01-核心框架与运行时(CLR与GC)
  • 简述ajax、node.js、webpack、git
  • Java安全体系深度研究:技术演进与攻防实践
  • Drupal XSS漏洞复现:原理详解+环境搭建+渗透实践(CVE-2019-6341)
  • Mybatis常见问题
  • Python基础语法篇:布尔值是什么?True 和 False 的实际用途
  • FMI(Functional Mock-up Interface,功能模型接口)
  • macOS中设置环境变量的各文件及作用域
  • Python+DRVT 从外部调用 Revit:批量创建楼板
  • 课前准备--解码乳腺癌进展:单细胞基因组与转录组的联合分析
  • 机器学习中的损失函数是什么
  • P5019 [NOIP 2018 提高组] 铺设道路
  • 【 苍穹外卖 | Day2】
  • 简单的说一说前端开发语言React
  • 跨域解决方案——CORS学习了解
  • leetcode 1304. 和为零的 N 个不同整数 简单
  • LeetCode 面试经典 150 题:合并两个有序数组(双指针解法详解)
  • Nestjs框架: 基于策略的权限控制(ACL)与数据权限设计
  • Go语言实战案例-实现简易定时提醒程序
  • 如何在项目中使用 Claude 记忆库系统(二开场景指南)
  • Matlab Simulink中的一些记录
  • 在Word和WPS文字的表格中快速输入连续的星期、月、日
  • Linux 周期性用户作业计划:crontab