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串口数据做解析的更多相关文章

  1. stm32串口接收中断协议解析

    借鉴了文章:<stm32串口中断接收方式详细比较> 文章地址:http://blog.csdn.net/kevinhg/article/details/40186169 串口的配置这里不做 ...

  2. 换晶振导致stm32串口数据飞码的解决办法(补充)

    今天(2014.4.21)把stm32f107的程序下载到stm32f103的板子上,发现串口收不到数据,突然想起晶振频率没有修改,#define HSE_VALUE    ((uint32_t)13 ...

  3. 换晶振导致stm32串口数据飞码的解决办法

    一般来说,stm32f107都是用标配的晶振,比如8MHz. 但是,如果用别的晶振,比如13.56M的晶振,那串口接收还正常吗? 根据试验结果,很可能会飞码.比如说用串口助手发送的是0x35,但是在串 ...

  4. STM32 ------ 串口 数据位长度 和 奇偶校验位

    USART_InitStructure.USART_WordLength 的值是数据位长度+一个奇偶校验位(如果无奇偶校验则不加一)

  5. python爬虫下正则各种字符串数据匹配

    s = '*\/:?"<>|' #这9个字符在Windows系统下是不可以出现在文件名中的str1 = '\巴拉<1"!11[]>1*hgn/p:?|' # ...

  6. python 下串口数据的读取,解析,和保存-

    #!/usr/bin/python # -*-coding: utf-8 -*- import serial import threading import binascii from datetim ...

  7. Python/Java程序员面试必备常用问题解析与答案

    转自AI算法联盟,理解python技术问题,以及一些常见的java面试中经常遇到的问题,这些面试问题分为四类: 是什么(what) 如何做(how) 说区别/谈优势(difference) 实践操作( ...

  8. 【python cookbook】【数据结构与算法】19.同时对数据做转换和换算

    问题:我们需要调用一个换算函数(例如sum().min().max()),但是首先需对数据做转换或者筛选处理 解决方案:非常优雅的方法---在函数参数中使用生成器表达式 例如: # 计算平方和 num ...

  9. stm32串口接收完整的数据包

    参考了文章:<stm32串口中断接收方式详细比较> 文章地址:http://bbs.elecfans.com/jishu_357017_1_1.html 借鉴了第四种中断方式 串口的配置这 ...

随机推荐

  1. Java学习---下载文件并且对文件编码

    import java.io.IOException; import java.net.URLEncoder; import sun.misc.BASE64Encoder; public class ...

  2. December 11th 2016 Week 51st Sunday

    If a thing is worth doing it is worth doing well. 如果事情值得做,那就做好. If it is worth doing, then it is wor ...

  3. Spring Security 静态资源访问

    在搞 Spring Security 的时候遇到了一个小坑,就是静态资源加载的问题. 当我们继承了 WebSecurityConfigurerAdapter的时候,会去重写几个方法.去设定我们自己要过 ...

  4. JS:二维数组排序和获取子级元素

    JS:二维数组排序和获取子级元素 1. 二维数组排序 1.按数值排序 var arr = [[1, 2, 3], [7, 2, 3], [3, 2, 3]]; 如果我们要按每个子数组的第一列来排序要如 ...

  5. archer 安装

    archer 项目地址: https://github.com/jly8866/archer 安装docker版本 Pull Docker docker pull hhyo/archer 启动服务do ...

  6. C++中在子类实现父类的方法调用

  7. the longest distance of a binary tree

    版权声明:欢迎查看本博客.希望对你有有所帮助 https://blog.csdn.net/cqs_2012/article/details/24880735 the longest distance ...

  8. 2、Android-UI(RecyclerView)

    2.6.滚动控件-RecylerView ListView虽然使用的效果很好但是也是有缺点的 不使用一些技巧来提升它的运行效率,性能就非常差 扩展性也不是很好 只能实现数据的纵向滚动效果 实现横向滚动 ...

  9. druid相关资料

    官方资料直达地址: Druid 首页 https://github.com/alibaba/druid/wiki/%E9%A6%96%E9%A1%B5 Druid 常见问题 https://githu ...

  10. 【转】实现Http Server的三种方法

    一.使用SUN公司在JDK6中提供的新包com.sun.net.httpserver JDK6提供了一个简单的Http Server API,据此我们可以构建自己的嵌入式Http Server,它支持 ...