【python】python接收串口json格式数据并解析

首先感谢:https://www.cnblogs.com/mangojun/p/10558069.html
本文参考了该博主部分代码

最近在写一个zigbee的程序,终端发送采用了json格式打包。
上位机使用了树莓派,直接使用python编程,第一次尝试树莓派接收数据,仍旧采用了类似于C语言的数据处理方式。
数据处理过程:
1、首先通过进程,将数据接受进一个bytearray的数组中
2、在数组中查找 { ,因为我的格式比较简单,发送上来的数据都只有一组大括号,所以处理起来相对容易一些。
3、在数组中查找 }
4、若找到 { } ,且右括号的位置在后面,则提取出来json数据,并将这部分数据从数组中清除
5、若找到 { ,没有右括号,则说明还没接收到一个完整的数据
6、若找到 } , 没有左括号,说明 } 前面的数据是错误数据,直接丢弃。

数据处理后,可直接使用json库进行处理,处理时注意采用try的方式,因为只判断了 { } ,可能内部格式存在问题的时候,会出现异常。

# -*- coding: utf-8 -*-
"""
Created on Thu Aug  5 08:43:36 2021

@author: huangcw
"""


import serial
import time
import json
from datetime import datetime
import threading

class SerialPort:
    def __init__(self, port, buand):
        self.data_bytes=bytearray()
        self.is_exit = False
        self.port = serial.Serial(port, buand)
        self.port.close()
        if not self.port.isOpen():
            self.port.open()

    def port_open(self):
        if not self.port.isOpen():
            self.port.open()

    def port_close(self):
        self.port.close()

    def send_data(self):
        self.port.write('')

    def read_data(self):
        """
        从串口读取数据,并放到缓冲区中
        """
        while not self.is_exit:
            count = self.port.inWaiting()
            if count > 0:
                rec_str = self.port.read(count)
                self.data_bytes=self.data_bytes+rec_str
    
    def frame_process(self):
        """
        提取json格式数据,若收到的数据中包含完整的json数据,每调用一次返回一条json数据。
        注意:仅支持一层 { }的json数据格式。
        """
        self.head = -1
        self.tail = -1
        self.head = self.data_bytes.find(b'{')
        self.tail = self.data_bytes.find(b'}')
        if(self.head != -1):  #有json的头
            if(self.tail != -1):    #有尾
                if(self.tail < self.head):  #尾靠前,说明前面不是一个完整的报文,需要扔掉
                    self.data_bytes[0:self.tail+1]=b''
                    return -2
                if(self.tail > self.head): # 有头有尾,且头在尾前面
                    self.rtn = self.data_bytes[self.head:self.tail+1]
                    self.data_bytes[self.head:self.tail+1]=b''
                    return self.rtn
            # 有头没有尾,说明还没有接收完一帧,不处理
            else:
                return -1
        # 没头,说明没接收到一帧,不处理
        else:
            return -1
                
serialPort = 'COM13'  # 串口
baudRate = 115200  # 波特率

if __name__ == '__main__':
    #打开串口
    mSerial = SerialPort(serialPort, baudRate)
        #开始数据读取线程
    t1 = threading.Thread(target=mSerial.read_data)
    t1.setDaemon(True)
    t1.start()
    frame_cnt = 0
    frame_error_cnt = 0
    try:
        while True:
            rtn = mSerial.frame_process()
            if rtn != -1 and rtn != -2:
                frame_cnt = frame_cnt + 1
                print("正确帧:{}  错误帧:{} 新数据:{}".format(frame_cnt,frame_error_cnt,rtn))
            elif rtn == -2:
                frame_error_cnt = frame_error_cnt +1
    except KeyboardInterrupt:
        if mSerial.port_open():
            mSerial.port_close()
            

运行效果:
在这里插入图片描述

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值