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

python上位机串行通信接收字节数据的校验处理-以crc16-modbus为例

在串行通信中,接收到的数据是否正确,一般用CRC校码的方式来完成。上位机向下位机发送数据时,需要加上校验码,同理,下位机向上位机上报数据时,也需要加上校验码。

校验码的计算方法有很多,比较简单的是奇偶校验,相对来说容易计算,且数据传输的可靠度也还不错。比较可靠的方法用CRC校验,CRC的原理在此不详述,有需要的自行在CSDN上找答案。

这里需要说的是,接收到数据后,如何对该数据是否正确进行校验。

一、从串口接收到原始数据的不同表现形式

作为上位机,从串口收到的数据是这样的:

注意看图片的第3行和第4行。第3行是显示的字节码,第4行是转为16进制数显示,两者是不同的。

寻么在做校验时,是以哪个为准呢。

我们打开 字节数据校验码计算器,可以参考CRC(循环冗余校验)在线计算_ip33.com,看计算的结果

貌似是以第4行显示的结果进行的计算,我们收到的原始数据不是这个样子,似乎这种方法不可行。

其实有这个困惑的主要原因,是对字节码数据与16进制数据理解不深不透造成的。我们通过串口助手来重新看一下这个过程。首先我以十六进制的形式进行收发。

可以看到这个数据和程序收到的数据是一致的,对应的16进制数据就是A1 61 00 09 B2,转换成二进制再看一下:

data = b'\xa1a\x00\t\xb2'
binary_str1 = ' '.join(f'{byte:08b}' for byte in data)
display(binary_str1)

得到的结果是:'10100001 01100001 00000000 00001001 10110010'

我们看到他和16进制数据是一一对应的。

以上说了半天,只是为了说明我们接收到的数据的表现形式,以加深我们对校验处理的理解。

二、校验

校验涉及两个问题,一是将接收到的原始数据截取成信息数据和校验码的形式;二是将信息数据用校验码生成工具重新计算生成校验码;三是对比两个校验码,看其是否一致。

def CRC16_Modbus_verification(self, rx_buf: bytes)->bool:"""使用CRC16_Modbus校验接收到的数据是否正确Args:rx_buf (bytes): 从串口接收到的数据,最后两个字节,高字节为crc_l,低字节为crc_hReturns:bool: 0,校验失败,1校验成功"""crc_h,crc_l = self.CRC16_Modbus(rx_buf[:-2])                      # 校验#print('rx_buf[-2:-1]:',rx_buf[-2:-1])if crc_l == rx_buf[-2:-1] and crc_h == rx_buf[-1:]:return 1else:return 0

使用上述函数,直接可以将接收到的字节码输入,自动出来计算结果,以决定数据是否采用。

以上简要描述了接收原始数据的表现形式与校验方法,当然处理这种校验的方法有很多,实际项目中,上位机开发与下位机开发要进行充分的沟通,使用相同的校验算法,这样才能通过串口进行有效通信。

相关文章:

  • 五月份0day/1day/nday漏洞汇总
  • 【计算机毕设】蜗牛兼职网的设计与实现 - 源码免费(私信领取)
  • 如何使用Spring Cache优化后端接口?
  • 笔墨挥毫如游龙 最是经典铁线篆——记著名书法家王子彬
  • python的range() 函数
  • 笔记:Windows故障转移集群下的oracle打补丁
  • 【数据结构】六种排序实现方法及区分比较
  • Java字符串String详解
  • 网络性能测试工具:iperf3介绍
  • 看图猜成语微信小程序源码
  • 利用预测大模型完成办公室饮水机剩余热水量
  • 视频汇聚管理安防监控平台EasyCVR程序报错“create jwtSecret del server class:0xf98b6040”的原因排查与解决
  • 【题解 | 分享】2023年十四届蓝桥杯国赛(Java B组)
  • 这里一定有你不知道的VS调试技巧
  • 【Java】刚刚!突然!紧急通知!垃圾回收!
  • SegmentFault for Android 3.0 发布
  •  D - 粉碎叛乱F - 其他起义
  • Linux中的硬链接与软链接
  • Logstash 参考指南(目录)
  • Mysql数据库的条件查询语句
  • uni-app项目数字滚动
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 半理解系列--Promise的进化史
  • 将 Measurements 和 Units 应用到物理学
  • 悄悄地说一个bug
  • 手机端车牌号码键盘的vue组件
  • 思否第一天
  • 线性表及其算法(java实现)
  • 主流的CSS水平和垂直居中技术大全
  • 追踪解析 FutureTask 源码
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • # C++之functional库用法整理
  • (2)Java 简介
  • (27)4.8 习题课
  • (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类的类构造函数)
  • (Forward) Music Player: From UI Proposal to Code
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (二)WCF的Binding模型
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (原創) 未来三学期想要修的课 (日記)
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET CORE Aws S3 使用
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • /bin/rm: 参数列表过长"的解决办法
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • @Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成
  • [@Controller]4 详解@ModelAttribute
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [20171102]视图v$session中process字段含义