一 概 述
在我这么多年的西门子PLC模块技术支持生涯中,在编程相关的问题里面,字符串编程保守估计得占四分之一,而这其中字符串转换占了绝大多数,今天我们就盘点一下常见的字符串转换问题。
二 字符串转换
2.1 字符串
西门子的 SIMATIC 字符串和第三方常见的字符串有所不同,SIMATIC 字符串的结构与占用空间,如图 1 所示。
图 1. SIMATIC 字符串的结构
SIMATIC 字符串数据类型zui大字符长度与占用空间的关系,如图 2 所示。
图 2. zui大字符长度与占用空间
SIMATIC 字符串还可以自定义zui大字符长度数据类型,如图 3 所示。
图 3. 自定义zui大字符长度的数据类型
图 4 展示了不同编码下的汉字。一个 String[10] 类型变量,一个 WString[20] 类型变量,值都是“西门子”,以“西”字为例,String 类型变量值为 16#CEF7,WString 类型变量值为 16#897F。此外可以观察一下zui大长度和实际长度在字符串中的位置和值。
图 4. 不同的编码
上面所说的是西门子的 SIMATIC 字符串,而一般市面常见上位机或者仪表等所指的字符串其实对应的是图 1 所示的 SIMATIC 字符串后半截的字符部分,对于西门子来说,这叫做字符数组,Array Of Char,或者 Array Of WChar。对于上位机来说还好,只是格式不相同,编码通常是一样的。困难的是仪表,除了格式不同,仪表的字符编码通常也是各式各样的,为程序的读取转换造成了很多麻烦,字符串转换问题也主要是因为这个而产生。
2.2 字符串转换指令
前面聊了字符串的基本知识,下面简单介绍一下字符串转换的相关指令,更多指令说明需要查阅 TIA Portal 帮助。如图 5 红框所示为 TIA Portal 自带的字符串转换指令。
图 5. 字符串转换相关指令
这部分指令又细分成三类。
第 一类是数值和字符串之间的转换
这里注意,数值都是十进制数,不论是浮点数还是整数,如图 6 所示。
图6.数值转换相关指令
第二类是字符数组与字符串之间的转换
主要用在通信前的zui后一次、通信后的第 一次转换。如前所述通信对象通常都是字符数组,需要将字符串转为字符数组(通信前)、将字符数组转换为字符串(通信后),详细介绍如图 7 所示。
图7.字符数组和字符串的转换
第三类是字符和十六进制之间的转换
从名字就能看出来,ATH和HTA,A就是ASCII,H就是Hex(十六进制Hexadecimal),记住这两个缩写就能知道转换方向,在与第三方通信时经常需要用到,详细介绍如图 8 所示。
图8.字符和十六进制之间的转换
2.3 字符串转换案例
下面就用几个常见的例子为大家演示字符串的转换。
案例1
某扫码枪将扫描到的二维码,通过 Profinet IO 将这一串字符送入 西门子PLC模块 的 String字符串变量,如图 9 所示。
图9. 转换案例
编程思路:
通常我们的做法是新建一个非优化 DB 块,然后建立 String 类型变量(这里是String[15]),然后通过 SCL 的 PEEK 指令将每个 IB 的字符送入 String 的每个字符,zui后为 String 变量的实际字符长度赋值(这里是15),然后结束。
这么做肯定是没有问题的,不过推荐使用 Chars_TO_Strg 指令,这个指令需要字符数组作为输入,我们可以通过将 西门子PLC模块 变量(案例中的 IB100-IB114)设置为字符数组类型,然后进行转换。这里的 String 是优化变量,也不专门为实际字符长度赋值。
虽然 PLC 变量不能直接设置为数组类型,但是可以设置为 PLC 数据类型,所以我们可以考虑新建 PLC 数据类型,里面添加数组类型变量,然后就可以间接地将PLC 变量设置为数组,如图 10 所示。(注:如果 PLC 数据类型中包含字符串类型,那么 PLC 变量无法定义为该 PLC 数据类型,否则无需编程即可实现)
图10. 定义变量
之后就可以编写相关转换程序,查看转换结果。如图 11 所示。
图11. 转换及结果
案例2
某仪表需要进行给定,西门子PLC模块 设定的浮点数值传送到字符数组后通过 TCP 传送给仪表,如图 12 所 示。
图12. 转换案例
编程思路:
因为 S_CONV 进行浮点数转换时,只会将浮点数转换的字符串显示为科学计数法形式,所以在没有 VAL_STRG 指令的 S7-300/400 上,这个问题编程会很麻烦,比如通过放大/缩小倍数取整得到每一位,然后把每一位连同小数点转换成对应字符。
现在有了 VAL_STRG 指令,就可以直接指定转换为正常小数显示的字符串。SCL编程如图 13 所示。
图13. 转换编程
这里需要注意的是 VAL_STRG 转换后是右对齐,所以前面会产生很多空格,如图 14 所示。所以需要使用 delet 指令删除空格得到zui终的字符串。
图14. 转换删除
zui后得到的字符数组 “strData”.setChars 变量通过 TCP 发送程序传送到仪表,如图 15 所示为输出结果。
图15.输出结果
案例3
某仪表将浮点数的十六进制表示方式以字符的形式,通过串口通信的方式传递给西门子PLC模块,如图 16 所示。
图16.仪表发送原理
编程思路:
通过串口接收指令(Receive_P2P)可以直接将对方发送的字符数组接收为字符串,通过串口发送指令(Send_P2P)可以直接发送字符串,对方将会收到字符数组,这样就无需使用 Strg_TO_Chars 与 Chars_TO_Strg 指令进行转换了。
注意:通过 TCP、UDP 等开放式用户通信的方式与串口是不一样的,需要使用上面的转换指令。
因为西门子PLC模块 接收到的是十六进制对应的 ASCII 组成的字符串,所以需要先转换成十六进制数,这时需要使用 ATH 进行转换,转换成 DWord 类型后,再转换成Real 即可,程序如图 17 所示,结果如图 18 所示。
图17.程序
图.18 结果
对案例 3 再进行修改,如果仪表传递的是十六进制每个字符的 ASCII 数值的 ASCII 码呢,如图 19 所示。
图19.修改后的仪表发送原理
此时 西门子PLC模块 需要使用两次 ATH 指令,第 一次把每两个连续 ASCII 码转换成一个十六进制对应的 ASCII 码,第二次再把 ASCII 转换成十六进制,如图 20 所示。
图20.转换过程
图 17 中第二行程序替换程序,如图 21 所示,注意第 一次 ATH 转换16个字符,第二次转换8个字符,结果如图 22 所示。
图21.替代程序
图22.结果
三 总结
从以上案例能总结出,编好字符串转换需要掌握的要点如下:
1、深刻理解字符串的格式,SIMATIC 字符串与第三方的不同
2、弄清楚第三方所提供/所需要的编码方式
3、了解西门子字符串转换指令区别,适用范围
本文摘自:网络