python 3下对stm32串口数据做解析

1、最近有个想做一个传感器数据实时显示的上位机,常规的数据打印太频繁了,无法直观的看出数据的变化。

python下的上位机实现起来简单一点,网上找了一些python界面Tkinter相关资料和python串口的demo.测试实现了简单的数据显示。

 

Mark 一下问题点:

最大的问题点在于对bytes型数据的拼接:之前的串口解析的代码是在python 2.7平台上实现的,

切换到python3.0之后,测试失踪无法通过。幸而找到了大神相助。

python 2.7code:

  1 import os
  2 import time
  3 import sys, traceback
  4 from serial.serialutil import SerialException
  5 from serial import Serial
  6 
  7 import struct
  8 import binascii
  9 
 10 
 11 class Arduino:
 12     def __init__(self, port="/dev/ttyUSB0", baudrate=115200, timeout=0.5):
 13         
 14         self.port = port
 15         self.baudrate = baudrate
 16         self.timeout = timeout
 17         self.encoder_count = 0
 18         self.writeTimeout = timeout
 19         self.interCharTimeout = timeout / 30.
 20 
 21         self.WAITING_FF = 0
 22         self.WAITING_AA = 1
 23         self.RECEIVE_LEN = 2
 24         self.RECEIVE_PACKAGE = 3
 25         self.RECEIVE_CHECK = 4
 26         self.HEADER0 = 0xff
 27         self.HEADER1 = 0xaa
 28         self.REC_CMD = 5
 29         self.count   = 0
 30         self.data1   = 0
 31         self.data2   = 0
 32         self.error_flag = 0
 33         self.SUCCESS = 0
 34         self.FAIL = -1
 35 
 36         self.receive_state_ = self.WAITING_FF
 37         self.receive_check_sum_ = 0
 38         self.payload_command = ''
 39         self.payload_ack = ''
 40         self.payload_args = ''
 41         self.payload_len = 0
 42         self.byte_count_ = 0
 43         self.receive_message_length_ = 0
 44     
 45         self.mutex = threading.Thread.allocate_lock()
 46             
 47         # An array to cache analog sensor readings
 48         self.analog_sensor_cache = [None] * self.N_ANALOG_PORTS
 49         
 50         # An array to cache digital sensor readings
 51         self.digital_sensor_cache = [None] * self.N_DIGITAL_PORTS
 52     
 53     def connect(self):
 54         try:
 55             print "Connecting to Arduino on port", self.port, "..."
 56             self.port = Serial(port=self.port, baudrate=self.baudrate, timeout=self.timeout, writeTimeout=self.writeTimeout)
 57             # The next line is necessary to give the firmware time to wake up.
 58             time.sleep(1)
 59             state_, val = self.get_baud()
 60             if val != self.baudrate:
 61                 time.sleep(1)
 62                 state_, val  = self.get_baud()   
 63                 if val != self.baudrate:
 64                     raise SerialException
 65             print "Connected at", self.baudrate
 66             print "Arduino is ready."
 67 
 68         except SerialException:
 69             print "Serial Exception:"
 70             print sys.exc_info()
 71             print "Traceback follows:"
 72             traceback.print_exc(file=sys.stdout)
 73             print "Cannot connect to Arduino!"
 74             os._exit(1)
 75 
 76     def open(self): 
 77         self.port.open()
 78 
 79     def close(self): 
 80         self.port.close() 
 81     
 82     def send(self, cmd):
 83         self.port.write(cmd)
 84 
 85     def receiveFiniteStates(self, rx_data):
 86         if self.receive_state_ == self.WAITING_FF:
 87             #print str(binascii.b2a_hex(rx_data))
 88             if rx_data == '\xff':
 89                 self.receive_state_ = self.WAITING_AA
 90                 self.receive_check_sum_ =0
 91                 self.receive_message_length_ = 0
 92                 self.byte_count_=0
 93                 self.payload_ack = ''
 94                 self.payload_args = ''
 95                 self.payload_len = 0
 96                 self.count = 0
 97 
 98         elif self.receive_state_ == self.WAITING_AA :
 99              if rx_data == '\xaa':
100                  self.receive_state_ = self.REC_CMD
101              else:
102                  self.receive_state_ = self.WAITING_FF
103         elif self.receive_state_ == self.REC_CMD:
104              self.count+=1
105              if self.count == 1:
106                 self.data1,=struct.unpack("B",rx_data)
107              elif self.count == 2:
108                   self.data2,=struct.unpack("B",rx_data)
109                   self.receive_state_ = self.RECEIVE_LEN
110                   if self.error_flag == 0 and self.data1 != 0:
111                      self.error_flag = 1
112                   if self.data2 != 0 and self.error_flag == 0:
113                      self.error_flag = 1   
114         elif self.receive_state_ == self.RECEIVE_LEN:
115              self.receive_message_length_, = struct.unpack("B",rx_data)
116              self.receive_state_ = self.RECEIVE_PACKAGE
117         elif self.receive_state_ == self.RECEIVE_PACKAGE:
118              if self.byte_count_==0:
119                  self.payload_ack = rx_data
120              else:
121                  self.payload_args += rx_data
122              self.byte_count_ +=1
123              #print "byte:"+str(byte_count_) +","+ "rece_len:"+str(receive_message_length_)
124              if self.byte_count_ >= self.receive_message_length_:
125                  self.receive_state_ = self.RECEIVE_CHECK
126 
127         elif self.receive_state_ == self.RECEIVE_CHECK:
128             #if(rx_data == (unsigned char)receive_check_sum_)
129             if 1:
130                 self.receive_state_ = self.WAITING_FF
131                 #print str(binascii.b2a_hex(value))
132                 #left, right, = struct.unpack('hh', value)
133                 #print "left:"+str(left)+", right:"+str(right)
134                 return 1 
135             else:
136                 self.receive_state_ = self.WAITING_FF
137         else:
138             self.receive_state_ = self.WAITING_FF;
139         return 0
140 
141     def recv(self, timeout=0.5):
142         timeout = min(timeout, self.timeout)
143         ''' This command should not be used on its own: it is called by the execute commands   
144             below in a thread safe manner.  Note: we use read() instead of readline() since
145             readline() tends to return garbage characters from the Arduino
146         '''
147         c = ''
148         value = ''
149         attempts = 0
150         c = self.port.read(1)
151         #print str(binascii.b2a_hex(c))
152         while self.receiveFiniteStates(c) != 1:
153             c = self.port.read(1)
154             #print str(binascii.b2a_hex(c))
155             attempts += 1
156             if attempts * self.interCharTimeout > timeout:
157                 return 0
158         return 1
159             
160     def recv_ack(self):
161         ack = self.recv(self.timeout)
162         return ack == 'OK'
163 
164     def execute(self, cmd):
165         self.mutex.acquire()
166         
167         try:
168             self.port.flushInput()
169         except:
170             pass
171         
172         ntries = 1
173         attempts = 0
174         
175         try:
176             self.port.write(cmd)
177             res = self.recv(self.timeout)
178             while attempts < ntries and res !=1 :
179                 try:
180                     self.port.flushInput()
181                     self.port.write(cmd)
182                     res = self.recv(self.timeout)
183                 except:
184                     print "Exception executing command: " + str(binascii.b2a_hex(cmd))
185                 attempts += 1
186         except:
187             self.mutex.release()
188             print "Exception executing command: " + str(binascii.b2a_hex(cmd))
189             return 0
190         
191         self.mutex.release()
192         return 1
193 
194     def get_baud(self):
195         ''' Get the current baud rate on the serial port.
196         '''
197         cmd_str=struct.pack("4B", self.HEADER0, self.HEADER1, 0x01, 0x00) + struct.pack("B", 0x01)
198         if (self.execute(cmd_str))==1 and self.payload_ack == '\x00':
199            val, = struct.unpack('I', self.payload_args)
200            return  self.SUCCESS, val 
201         else:
202            return self.FAIL, 0
203 
204     def get_check_sum(self,list):
205         list_len = len(list)
206         cs = 0
207         for i in range(list_len):
208             #print i, list[i]
209             cs += list[i]
210         cs=cs%255
211         return cs
212         
213     def stop(self):
214         ''' Stop both motors.
215         '''
216         self.drive(0, 0)
View Code

在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)
View Code

 源码已上传到github:链接

目前单纯实现了串口数据的查询:

 

转载于:https://www.cnblogs.com/sshbit/p/10283185.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 1. 首先需要在stm32f中配置串口通信模块,包括波特率、数据位、停止位、校验位等参数。 2. 在python中使用pyserial库进行串口通信,需要指定串口号、波特率等参数。 3. 在python中发送数据stm32f,可以使用serial.write()函数,将数据以字节形式发送到串口。 4. 在stm32f中接收数据,可以使用串口中断或者轮询方式读取串口接收缓冲区中的数据。 5. 在stm32f中对接收到的数据进行处理,可以根据协议进行解析,例如将数据转换成数字或者字符串等格式。 6. 在stm32f中根据接收到的数据进行相应的控制操作,例如控制LED灯的亮灭、驱动电机等。 ### 回答2: Python串口通信控制STM32F是一种常见的应用场景,主要是通过将PythonSTM32F进行连接,实现实时控制和数据传输。下面详细介绍一下Python串口通信控制STM32F的实现步骤。 第一步,配置STM32F的串口参数,通常是使用STM32CubeMX进行配置,并生成对应的代码。在生成的代码中,可以找到STM32F的串口接收和发送函数的代码,这些函数将用于接收和发送数据。 第二步,配置Python串口参数。Python串口通信控制STM32F通常使用pyserial库实现,pyserial是Python的一个串口通信库,可以使用pip进行安装。在使用pyserial时,需要指定串口的参数,例如波特率、数据位、停止位、校验位等。 第三步,编写Python控制程序。编写Python程序实现与STM32F的串口通信和数据传输。具体来说,需要在Python程序中设置串口参数,建立串口,接收STM32F发送过来的数据,对数据进行处理,然后发送控制命令给STM32F。 第四步,编写STM32F程序。编写STM32F程序实现接收Python发送的数据,根据数据进行控制和处理,然后将处理结果返回给Python。 第五步,测试程序功能。在将PythonSTM32F进行连接后,需要进行测试程序功能,确保数据传输和控制命令的正确性。可以使用Python串口测试工具对程序进行测试,确保正确性和稳定性。 总之,Python串口通信控制STM32F是一种非常常见的应用场景,在工业自动化和机器人控制等领域具有广泛的应用前景。需要掌握一定的PythonSTM32F编程技能,以及串口通信的知识,才能实现成功。 ### 回答3: 最近,我在研究如何使用Python控制STM32F的串口通信。在这个过程中,我需要先了解一些基本的知识,如何设置串口参数和如何发送/接收数据。 首先,我下载了PySerial模块,这是一个用于串口通信的Python库。在使用这个库之前,我需要先了解一些常用的串口参数,如波特率,数据位,停止位和校验位。这些参数是设置串口通信的必要条件,如果不设置或者设置错误,将会导致通信失败。 使用PySerial库时,首先需要通过Serial类定义串口对象,并通过设置参数来初始化它。例如,下面的代码设置了波特率为9600,数据位为8位,无校验位和一个停止位。我们需要替换端口参数,'COM4'是windows系统下的串口端口。 ```python import serial ser = serial.Serial("COM4", 9600, 8, 'N', 1) ``` 设置完参数后,我们可以开始发送数据。通过串口对象的write函数,我们可以将需要发送的数据发送到串口上。例如,下面的代码将字符串“Hello World”发送到串口上: ```python ser.write(b’Hello World’) ``` 接收串口数据也是类似的。我们可以通过串口对象的read函数读取串口上的数据。例如,下面的代码将从串口上接收10个字节的数据,并将它们打印出来: ```python data = ser.read(10) print(data) ``` 最后,控制STM32F的串口通信需要在MCU的代码中加入串口接收和发送函数。在MCU的代码中,我们可以使用HAL库的函数来实现串口通信。例如,下面的代码设置了波特率为9600,数据位为8位,无校验位和一个停止位。同时,串口接收和发送函数也已经定义好了。 ```c #include “stm32f4xx_hal.h” UART_HandleTypeDef huart2; void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 9600; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef* huart) { if (huart == &huart2) { // 进行串口数据接收处理 } } void HAL_UART_TxCpltCallback(UART_HandleTypeDef* huart) { if (huart == &huart2) { // 进行串口数据发送处理 } } void UART_SendData(UART_HandleTypeDef* huart, uint8_t *pData, uint16_t Size) { HAL_UART_Transmit_IT(huart, pData, Size); } void UART_ReceiveData(UART_HandleTypeDef* huart, uint8_t *pData, uint16_t Size) { HAL_UART_Receive_IT(huart, pData, Size); } ``` 通过上述的代码Python串口通信代码的组合,我们可以实现控制STM32F的串口通信。比如,我们可以通过串口发送变量来控制STM32F的LED灯闪烁。具体法是在MCU代码中加入LED控制函数,不断读取串口数据并根据接收到的数据改变LED灯的状态。而在Python代码中,则可以发送控制命令来控制LED灯的闪烁。这样,我们便可以用Python来控制STM32F的功能,也可以通过PythonSTM32F之间的串口通信来实现数据的传输。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值