当前位置:   article > 正文

昆仑通态屏幕制作(连载5)---基础篇(串口接收,文本与灯显示)_昆仑通态屏幕可以解析报文吗

昆仑通态屏幕可以解析报文吗

前言

    前面介绍了基本的功能,现在差了一个串口的接收,所以按照以下流程进行接收,一步一步的来。这个思维挺重要的:

    第一步:接收数据,文本显示;

    第二步:接收数据,数据直接控制灯;

    第三步:接收数据,数据变位数据控制灯。

    其实中间还省略几步,比如用示波器观察传输数据的正确性,调试脚本程序的正确性。所以做技术得一步一步的,先完成最简单的,一步正确后再做后面的,当然这个分步骤就是自己的逻辑思维了,需要慢慢训练才能将一个事情分几步走。再将分步的几个事情转化为更小的步骤,然后一步一步的实现。

第一节:脚本编写

  1. DIM nSendByteArr(9) as BYTE
  2. DIM nRecvByteArr(9) as BYTE
  3. nSendByteArr[1] = &H5A
  4. nSendByteArr[2] = &HA5
  5. nSendByteArr[3] = &H03
  6. nSendByteArr[4] = &H04
  7. nSendByteArr[5] = !BitRShift(gnGetData1, 8)
  8. nSendByteArr[6] = gnGetData1
  9. nSendByteArr[7] = !BitRShift(gnGetData1, 8)
  10. nSendByteArr[8] = gnGetData1
  11. nSendByteArr[9] = !SvrByteArraySum(nSendByteArr,3,6)'和校验
  12. !DevClearBuff() '清缓冲
  13. !DevWriteAndReadByteArr(nSendByteArr,9,nRecvByteArr,9,通讯延时)

    这部分是前面串口发送部分的程序。发送9个,接收9个,完成发送之后,加入以下接收程序。其实接收的数据已经放进数组里面了,至于怎么接收怎么放进去的这个是屏幕自己完成的,不用去管,工程思想就是关注入口和出口就行了,至于里面的黑盒子是啥,不用关注。

  1. DIM glRecvDataH(9) as INTEGER
  2. DIM glRecvData(9) as INTEGER
  3. glRecvDataH[1] = nRecvByteArr[1] '0x5A--帧头
  4. glRecvDataH[2] = nRecvByteArr[2] '0xA5--帧头
  5. glRecvDataH[3] = nRecvByteArr[3] '0x06--数据长度(从长度位后一位开始的数据总长)
  6. glRecvDataH[4] = nRecvByteArr[4] '0x80--读指令
  7. glRecvDataH[5] = nRecvByteArr[5] '0x00--数据1
  8. glRecvDataH[6] = nRecvByteArr[6] '0x00--数据2
  9. glRecvDataH[7] = nRecvByteArr[7] '0x00--数据3
  10. glRecvDataH[8] = nRecvByteArr[8] '0x00--数据4
  11. glRecvDataH[9] = nRecvByteArr[9] '0x86--和校验
  12. !SetIntChannelValueByName("接收数据1", glRecvDataH[5])
  13. !SetIntChannelValueByName("接收数据2", glRecvDataH[6])
  14. !SetIntChannelValueByName("接收数据3", glRecvDataH[7])
  15. !SetIntChannelValueByName("接收数据4", glRecvDataH[8])
  16. DIM glSerialLed1 as INTEGER
  17. DIM glSerialLed2 as INTEGER
  18. DIM glSerialLed3 as INTEGER
  19. DIM glSerialLed4 as INTEGER
  20. glSerialLed1 = glRecvDataH[5]
  21. glSerialLed2 = glRecvDataH[6]
  22. glSerialLed3 = glRecvDataH[7]
  23. glSerialLed4 = glRecvDataH[8]
  24. !SetIntChannelValueByName("串口控制灯1", glSerialLed1 )
  25. !SetIntChannelValueByName("串口控制灯2", glSerialLed2 )
  26. !SetIntChannelValueByName("串口控制灯3", glSerialLed3 )
  27. !SetIntChannelValueByName("串口控制灯4", glSerialLed4 )

    一块一块解释:

    第一块:定义接收后变量数组,这里不建议直接使用串口接收的那个数组,一定要再定义一个新的数组,这样可以保证接收的正确后,再做后面的处理。只要经过一步,就要加入一步的变量,这样第一个按步骤检查正确性,第二个容易扩展程序,一步一步互不影响,可以分成块块去做。

    第二块:将串口得到的数据复制到定义的数组中;

    第三块:将接收数据的数据位:5/6/7/8byte放入“接收数据1/2/3/4”中,目的是直接文本显示;

    第四块:定义灯变量;

    第五块:将缓存的数据放入定义的灯变量中;

    第六块:将灯变量输出给LED灯,目的是指示灯显示。

     同时增加设备通道。保存退出。

 第二节:脚本驱动链接屏幕界面

     将脚本的通道类型链接到对应数据对象中。

第三节:屏幕界面设定

     其中LED灯的设置比较特殊:

     仅仅设置数据对象就行了,选择串口控制灯1/2/3/4,至于鼠标怎么点,在框框里点点就出来箭头了,我试了好久才点出来。

 第四节:串口数据准备

     串口发9个数,收9个数。指令里面有个通讯延时。

!DevWriteAndReadByteArr(nSendByteArr,9,nRecvByteArr,9,通讯延时)

     里面设置发送到接收的最大时间差,这点和QT的串口很像,里面设置的200ms。差不多那么高的波特率,返回的数据肯定能接收到完整的帧。想看这个时间怎么确定的小伙伴可以移步:

https://blog.csdn.net/weixin_45426095/article/details/119210830

《QT连载1:readyRead()函数,数据分包不完整解决办法》。

     所以串口助手必须在200ms内回复数据才能正确接收,所以直接在串口助手100ms发一次,发着玩呗,没啥影响。但是如果屏幕链接单片机的话,这个就有问题了,也就是说单片机从接收到屏幕发送的数据指令,到回复屏幕的数据的时间要尽可能的短,这点程序里面就需要很大注意了,如果得到的数据不能正确显示的话,就需要看看是屏幕的问题,还是单片机的问题了。现在用串口助手首先确定屏幕没有问题才好。所以使用串口助手尽快的发送。

    报文:5A A5 03 04 00 00 00 00 07 定时发送的报文

    报文:5A A5 06 80 05 02 00 00 CA 回复的报文

 第五节:测试

    运行,(步骤省略,具体可见前面几章)

     解释:收到数据0x05  0x02 0x00 0x00 四个byte,直接显示到对话框中,而灯是只要数据不为0就亮,所以前两个灯亮,后两个灯不亮。

第六节:存在问题

     接收到的数据0x05 转化为二进制后就是00000101,用一个byte控制一个灯比较费,所以希望是用一个byte控制8个灯,这样可以减小传输数据量,增加装置的可靠性。所以必须利用位来控制灯。所以再加入4个灯,利用0x05的这个5来控制,即00000101中的0101来控制四个灯。按照结果应该是两个灯亮,另两个灯不亮。当然实际上可以控制8个灯,思想是一样的,所以只用四个灯代替,有兴趣的小伙伴可以试试。

第七节:加入bit控制灯程序与界面

  1. DIM glSerialLed5 as INTEGER
  2. DIM glSerialLed6 as INTEGER
  3. DIM glSerialLed7 as INTEGER
  4. DIM glSerialLed8 as INTEGER
  5. glSerialLed5 = !BitAnd(glRecvDataH[5], &H01)
  6. glSerialLed6 = !BitAnd(glRecvDataH[5], &H02)
  7. glSerialLed7 = !BitAnd(glRecvDataH[5], &H04)
  8. glSerialLed8 = !BitAnd(glRecvDataH[5], &H08)
  9. !SetIntChannelValueByName("串口控制灯5", glSerialLed5 )
  10. !SetIntChannelValueByName("串口控制灯6", glSerialLed6 )
  11. !SetIntChannelValueByName("串口控制灯7", glSerialLed7 )
  12. !SetIntChannelValueByName("串口控制灯8", glSerialLed8 )

    成块解释:

    第一块:定义位控制变量,其实定义的是整数变量,但是灯控制只分为数据为0和不为0

    第二块:根据第一块思维,将数据与0x00000001,0x00000010,0x00000100,0x00001000,与一下,这样就去除了其他位,而每个变量只保留了数据的一位,这位等于1的话,整数就不为0,这位为0的话,整数就为0,达到将数据中位取出来的目的。

    第三块:位变成的整数控制灯。

    脚本链接和屏幕界面设计后,运行程序:

    横排:5 和 2对应灯亮;

    竖排:5对应0101,所以第一个和第三个灯亮 。验证了上述说的灯亮的现象。

    改变报文:5A A5 06 80 09 02 00 04 CA

     横排:9 2 4 对应灯亮

     竖排:9为1001,所以第一个灯和第四个灯亮。

 第八节:结论与展望

     至此,昆仑通态屏的全部基础内容告一段落,以上介绍的东西差不多能满足大部分屏幕的制作需要。以后有时间再看看屏幕的中级用法吧,想着还会有高级用法,哈哈。如果需要的话我再去研究屏幕的其他东西,看看还有策略啥的,应该能像PLC一样去编写,这块应该也比较麻烦,但是会了之后也应该是体力劳动。如果有需要源代码和其他高阶东西的小伙伴可以添加微信,我会发送源代码和再次制作需要的连载。微信码放在下面,需要的话可以添加下。

    

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/993712
推荐阅读
相关标签
  

闽ICP备14008679号