C#通过OPC-UA读取第三方PLC字符串出现乱码问题求助
解决OPC-UA读取不同厂商PLC字符串乱码问题
你的问题核心是不同厂商PLC的OPC-UA字符串存储/编码规则不一致,西门子的UAClientHelperAPI默认适配了自家设备的编码,其他厂商设备的字符串格式(比如ASCII编码、固定长度填充空字符、字节数组存储)导致读取后出现无效字符。以下是针对性解决方法:
1. 确认目标PLC的字符串格式
先查目标厂商PLC的OPC-UA文档,重点看字符串节点的:
- 数据类型:是标准
String还是ByteString(字节数组) - 编码规则:用的是ASCII、UTF-8还是UTF-16
- 是否为固定长度字符串(是否用
\0填充到指定长度)
2. 针对字节数组类型的节点读取
如果目标节点实际存储为字节数组而非标准字符串,不要直接用ReadValues转成string,改为读取字节数组后指定编码解码:
// 读取节点值(假设返回的是byte[]类型) var readResult = UAClientHelperAPI.ReadValues("目标节点ID"); byte[] rawBytes = (byte[])readResult.Value; // 根据厂商文档选择对应编码,比如ASCII或UTF-8 string decodedString = Encoding.ASCII.GetString(rawBytes); // 去掉末尾的空字符和多余空格 decodedString = decodedString.TrimEnd('\0').Trim();
3. 改进字符串过滤逻辑
如果必须处理已读取的带无效字符的string,替换原有过滤代码,直接保留可打印字符并清理空字符:
方法一:使用LINQ过滤可打印字符
string cleanedString = new string(input.Where(c => char.IsPrintable(c) && c != '\0').ToArray());
方法二:用正则保留ASCII可打印范围
using System.Text.RegularExpressions; string cleanedString = Regex.Replace(input, @"[^\x20-\x7E]", ""); // 再去掉前后空格 cleanedString = cleanedString.Trim();
注:\x20-\x7E覆盖了所有ASCII可打印字符(从空格到波浪线),能精准过滤掉控制字符和无效编码字符。
4. 处理固定长度字符串的空字符填充
很多PLC会把字符串存为固定长度,用\0填充剩余空间,读取后可以直接截断到第一个空字符:
int nullPos = input.IndexOf('\0'); if (nullPos != -1) { input = input.Substring(0, nullPos); } input = input.Trim();
内容的提问来源于stack exchange,提问作者Luca Arniani
相关产品推荐
相关产品推荐

