python 3下对stm32串口数据做解析
1、最近有个想做一个传感器数据实时显示的上位机,常规的数据打印太频繁了,无法直观的看出数据的变化。
python下的上位机实现起来简单一点,网上找了一些python界面Tkinter相关资料和python串口的demo.测试实现了简单的数据显示。
Mark 一下问题点:
最大的问题点在于对bytes型数据的拼接:之前的串口解析的代码是在python 2.7平台上实现的,
切换到python3.0之后,测试失踪无法通过。幸而找到了大神相助。
python 2.7code:
import os
import time
import sys, traceback
from serial.serialutil import SerialException
from serial import Serial import struct
import binascii class Arduino:
def __init__(self, port="/dev/ttyUSB0", baudrate=115200, timeout=0.5): self.port = port
self.baudrate = baudrate
self.timeout = timeout
self.encoder_count = 0
self.writeTimeout = timeout
self.interCharTimeout = timeout / 30. self.WAITING_FF = 0
self.WAITING_AA = 1
self.RECEIVE_LEN = 2
self.RECEIVE_PACKAGE = 3
self.RECEIVE_CHECK = 4
self.HEADER0 = 0xff
self.HEADER1 = 0xaa
self.REC_CMD = 5
self.count = 0
self.data1 = 0
self.data2 = 0
self.error_flag = 0
self.SUCCESS = 0
self.FAIL = -1 self.receive_state_ = self.WAITING_FF
self.receive_check_sum_ = 0
self.payload_command = ''
self.payload_ack = ''
self.payload_args = ''
self.payload_len = 0
self.byte_count_ = 0
self.receive_message_length_ = 0 self.mutex = threading.Thread.allocate_lock() # An array to cache analog sensor readings
self.analog_sensor_cache = [None] * self.N_ANALOG_PORTS # An array to cache digital sensor readings
self.digital_sensor_cache = [None] * self.N_DIGITAL_PORTS def connect(self):
try:
print "Connecting to Arduino on port", self.port, "..."
self.port = Serial(port=self.port, baudrate=self.baudrate, timeout=self.timeout, writeTimeout=self.writeTimeout)
# The next line is necessary to give the firmware time to wake up.
time.sleep(1)
state_, val = self.get_baud()
if val != self.baudrate:
time.sleep(1)
state_, val = self.get_baud()
if val != self.baudrate:
raise SerialException
print "Connected at", self.baudrate
print "Arduino is ready." except SerialException:
print "Serial Exception:"
print sys.exc_info()
print "Traceback follows:"
traceback.print_exc(file=sys.stdout)
print "Cannot connect to Arduino!"
os._exit(1) def open(self):
self.port.open() def close(self):
self.port.close() def send(self, cmd):
self.port.write(cmd) def receiveFiniteStates(self, rx_data):
if self.receive_state_ == self.WAITING_FF:
#print str(binascii.b2a_hex(rx_data))
if rx_data == '\xff':
self.receive_state_ = self.WAITING_AA
self.receive_check_sum_ =0
self.receive_message_length_ = 0
self.byte_count_=0
self.payload_ack = ''
self.payload_args = ''
self.payload_len = 0
self.count = 0 elif self.receive_state_ == self.WAITING_AA :
if rx_data == '\xaa':
self.receive_state_ = self.REC_CMD
else:
self.receive_state_ = self.WAITING_FF
elif self.receive_state_ == self.REC_CMD:
self.count+=1
if self.count == 1:
self.data1,=struct.unpack("B",rx_data)
elif self.count == 2:
self.data2,=struct.unpack("B",rx_data)
self.receive_state_ = self.RECEIVE_LEN
if self.error_flag == 0 and self.data1 != 0:
self.error_flag = 1
if self.data2 != 0 and self.error_flag == 0:
self.error_flag = 1
elif self.receive_state_ == self.RECEIVE_LEN:
self.receive_message_length_, = struct.unpack("B",rx_data)
self.receive_state_ = self.RECEIVE_PACKAGE
elif self.receive_state_ == self.RECEIVE_PACKAGE:
if self.byte_count_==0:
self.payload_ack = rx_data
else:
self.payload_args += rx_data
self.byte_count_ +=1
#print "byte:"+str(byte_count_) +","+ "rece_len:"+str(receive_message_length_)
if self.byte_count_ >= self.receive_message_length_:
self.receive_state_ = self.RECEIVE_CHECK elif self.receive_state_ == self.RECEIVE_CHECK:
#if(rx_data == (unsigned char)receive_check_sum_)
if 1:
self.receive_state_ = self.WAITING_FF
#print str(binascii.b2a_hex(value))
#left, right, = struct.unpack('hh', value)
#print "left:"+str(left)+", right:"+str(right)
return 1
else:
self.receive_state_ = self.WAITING_FF
else:
self.receive_state_ = self.WAITING_FF;
return 0 def recv(self, timeout=0.5):
timeout = min(timeout, self.timeout)
''' This command should not be used on its own: it is called by the execute commands
below in a thread safe manner. Note: we use read() instead of readline() since
readline() tends to return garbage characters from the Arduino
'''
c = ''
value = ''
attempts = 0
c = self.port.read(1)
#print str(binascii.b2a_hex(c))
while self.receiveFiniteStates(c) != 1:
c = self.port.read(1)
#print str(binascii.b2a_hex(c))
attempts += 1
if attempts * self.interCharTimeout > timeout:
return 0
return 1 def recv_ack(self):
ack = self.recv(self.timeout)
return ack == 'OK' def execute(self, cmd):
self.mutex.acquire() try:
self.port.flushInput()
except:
pass ntries = 1
attempts = 0 try:
self.port.write(cmd)
res = self.recv(self.timeout)
while attempts < ntries and res !=1 :
try:
self.port.flushInput()
self.port.write(cmd)
res = self.recv(self.timeout)
except:
print "Exception executing command: " + str(binascii.b2a_hex(cmd))
attempts += 1
except:
self.mutex.release()
print "Exception executing command: " + str(binascii.b2a_hex(cmd))
return 0 self.mutex.release()
return 1 def get_baud(self):
''' Get the current baud rate on the serial port.
'''
cmd_str=struct.pack("4B", self.HEADER0, self.HEADER1, 0x01, 0x00) + struct.pack("B", 0x01)
if (self.execute(cmd_str))==1 and self.payload_ack == '\x00':
val, = struct.unpack('I', self.payload_args)
return self.SUCCESS, val
else:
return self.FAIL, 0 def get_check_sum(self,list):
list_len = len(list)
cs = 0
for i in range(list_len):
#print i, list[i]
cs += list[i]
cs=cs%255
return cs def stop(self):
''' Stop both motors.
'''
self.drive(0, 0)
在python 3.6 version 中就该修改部分代码:
问题在于bytes类型的拼接:
以下的拼接是正确的:
bytes('','ascii')+bytes([1,2,3,4,5,6,7,8,9])
bytes('','ascii')+bytes([1,2,3,4,5,6,7,8,9])+bytes([1,2,3,4,5,6,7,8,9])
也即是:bytes类型的拼接的初始变量要声明为:bytes('','ascii')
如果声明为其它类型:比如字符串,执行时会直接报错。
即:python2.7代码块中:40行以及94行的声明:
(1)将:40行和94行的
self.payload_args = ''
改为:
self.payload_args = bytes('','ascii')
(2)将:121行赋值命令:
self.payload_args += rx_data
修改为:
self.payload_args += bytes(rx_data)
源码已上传到github:链接
目前单纯实现了串口数据的查询:
python 3下对stm32串口数据做解析的更多相关文章
- stm32串口接收中断协议解析
借鉴了文章:<stm32串口中断接收方式详细比较> 文章地址:http://blog.csdn.net/kevinhg/article/details/40186169 串口的配置这里不做 ...
- 换晶振导致stm32串口数据飞码的解决办法(补充)
今天(2014.4.21)把stm32f107的程序下载到stm32f103的板子上,发现串口收不到数据,突然想起晶振频率没有修改,#define HSE_VALUE ((uint32_t)13 ...
- 换晶振导致stm32串口数据飞码的解决办法
一般来说,stm32f107都是用标配的晶振,比如8MHz. 但是,如果用别的晶振,比如13.56M的晶振,那串口接收还正常吗? 根据试验结果,很可能会飞码.比如说用串口助手发送的是0x35,但是在串 ...
- STM32 ------ 串口 数据位长度 和 奇偶校验位
USART_InitStructure.USART_WordLength 的值是数据位长度+一个奇偶校验位(如果无奇偶校验则不加一)
- python爬虫下正则各种字符串数据匹配
s = '*\/:?"<>|' #这9个字符在Windows系统下是不可以出现在文件名中的str1 = '\巴拉<1"!11[]>1*hgn/p:?|' # ...
- python 下串口数据的读取,解析,和保存-
#!/usr/bin/python # -*-coding: utf-8 -*- import serial import threading import binascii from datetim ...
- Python/Java程序员面试必备常用问题解析与答案
转自AI算法联盟,理解python技术问题,以及一些常见的java面试中经常遇到的问题,这些面试问题分为四类: 是什么(what) 如何做(how) 说区别/谈优势(difference) 实践操作( ...
- 【python cookbook】【数据结构与算法】19.同时对数据做转换和换算
问题:我们需要调用一个换算函数(例如sum().min().max()),但是首先需对数据做转换或者筛选处理 解决方案:非常优雅的方法---在函数参数中使用生成器表达式 例如: # 计算平方和 num ...
- stm32串口接收完整的数据包
参考了文章:<stm32串口中断接收方式详细比较> 文章地址:http://bbs.elecfans.com/jishu_357017_1_1.html 借鉴了第四种中断方式 串口的配置这 ...
随机推荐
- Python学习---JSON学习180130
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.JSON是用字符串来表示Javascript对象: Json字符串就是js对象的一种表现形式(字符串的形式 ...
- Linux 下Shell的学习3-优秀demo
优秀的DEMO cat /etc/init.d/functions -->里面有颜色定义cat /etc/rc.d/rc.sysinit cat /etc/init.d/nfscat /et ...
- 在IIS上发布网站后,在编译时出现CS0016拒绝访问错误
错误如下图所示: 关键性错误信息: 编译器错误消息: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Te ...
- php测试工具
如果是测压力有apache的ab如果要看性能则有xdebug和xhprof.还有linux的strace命令来跟踪程序的执行时的系统调用
- ZT Android Debuggerd的分析及使用方法
Android Debuggerd的分析及使用方法 分类: 移动开发 android framework 2012-12-28 12:00 983人阅读 评论(0) 收藏 举报 目录(?)[+] An ...
- Genymotion安卓模拟器和VirtualBox虚拟机安装、配置、测试(win7_64bit)
1.概述 VirtualBox是一个优秀的虚拟机软件,它可以在电脑上提供另一个操作系统的运行环境,使多个系统同时运行.VirtualBox支持的操作系统包括Windows.Mac OS X.Linux ...
- 021.12 IO流 ObjectStream对象序列化
内容:通过文件存储对象我们遇到的问题,需要保存对象到硬盘中,如何解决这个就是用来解决的 用法:1.创建流对象FileOutputstream2.创建ObjectOutputStream对象与FileO ...
- mac系统终端的color scheme配置和vim配置
一.配置终端 solarized http://ethanschoonover.com/solarized 简单配置脚本: #!/bin/sh git clone git://github.com/a ...
- VM安装CentOs7虚拟机后无法上网之解决方法
最近在研究DC/OS的安装,读了很多安装方法后决定先从docker的安装入手,由于DC/OS的安装必须在CentOs7版本以上,所以就在VM下安装了CentOs7,殊不知安装后并不能上网,于是乎又转到 ...
- 关于使用Filter降低Lucene tf idf打分计算的调研
将query改成filter,lucene中有个QueryWrapperFilter性能比较差,所以基本上都须要自己写filter.包含TermFilter,ExactPhraseFilter,Con ...