micropython+ESP32+直来直往超声波模块

系列文章目录

前言

一、数据传输类型为什么用bytes

二、bytes转为str、int类型

1.bytes转str

2.bytes转int

三、直来直往超声波

1.模块介绍:

2.代码

总结


前言

本文主要提供基于Thonny编译器下的micropython+ESP32串口接收数据的类型转换,并提供一下直来直往超声波模块的代码,代码并不复杂,但是数据类型转换过程很折磨人,ESP32串口传输是bytes类型,经常需要转成str或者int,清明在实验室呆了一天,终于给整出来了,满心欢喜,想着总结分享一下,让初学者能够不被这种问题耽误时间。

一、数据传输类型为什么用bytes

首先来看看bytes是怎么存储数据的:bytes是以二进制形式来存储数据(如下图),"\x"符号可以视为“0x”(我个人是这么理解的),也就是十六进制的开头。至于这些数据到底表示什么内容(字符串、数字、图片、音频等),就取决于解析这段bytes数据的方式了。打个比方;bytes类型就是书上的文字,用来记录计算机内存中的原始数据,解析这段文字具有不同的方式,也就类似于解析bytes数据了。

计算机传输数据时,是以字节为单位传输的,而bytes类型数据和一个字节数据等大,因此采用bytes类型不会造成空间浪费

b1 = b'\xe8\xaf\xad\xb2\x81\xe4\xba\x86'
b2 = b'\x00\x01\x02\x03'

二、bytes转为str、int类型

这里随意在浏览器一搜索,有很多

可以参考大佬方案,比较齐全:Python中int、str、bytes相互转化,还有2进制、16进制表示,你想要的都在这里了_python 'int' and 'bytes-CSDN博客

这里简单整理我自己觉得很好用并且没有报错的:

1.bytes转str

比较好用的是:xxx.decode('utf-8')

此方法成功率高,在thonny中大多数情况下都能使用,将bytes转为str类型,个人理解:其中 decode()就是解码,传输数据时候需要编码encode()成bytes类型,传输完成后解析数据,就可以用decode()解码

#串口接收部分
if uart.any():
    text = uart.read(20)  #最多读取20个字符
    print("text--type")    
    print(type(text))    #打印输出的是bytes类型
    str_test=text.decode('utf-8')
    print(("str_test--type")   
    print(str_test)      #打印输出的是str类型

2.bytes转int

我试了试:比较喜欢用int.from_bytes()函数

需要注意:大佬的int.from_bytes(byte_val, byteorder='big', signed=False) 在thonny中报错,大概意思就是参数问题,直接使用int.from_bytes(byte_val, 'big')就够用了

bytes是要转换的十六进制;

byteorder:选'big'和'little',以上例为例,其中big代表正常顺序,即f1ff。little反之,代表反序fff1;

 signed:选True、Flase表示是否要区分二进制的正负数含义。即是否要对原二进制数进行原码反码 补码操作。

可以参考:python之将byte转换为int类型函数 int.from_bytes 详解与原码反码补码的简单介绍-CSDN博客

byte_val = b'\x00\x10'
  
int_val = int.from_bytes(byte_val, "little")
  
print(int_val)

#输出结果:4096

三、直来直往超声波

1.模块介绍:

我买的是某宝的大鱼电子的直来直往超声波模块,好处是模块自带了MCU,使用简单,发送接收模块上电就能使用

模块通信波特率:115200;发送频率:50Hz;工作电压:5V;测量距离单位:mm

需要注意的是:发送模块没有发送时,接收模块会默认收到 bytes_distance = b'\xa5\x00\xC8',转换成十进制是6800

thonny下收到的bytes数据计算成十进制的方法:

int_distance = int.from_bytes(bytes_distance [1:3],'big')  这里在代码部分讲解

当接收超声波已经接收到发送超声波的数据后,接收超声波模块上的 LED 灯会快速闪烁,会通过串口以 50Hz 的频率发送出距离数据。我用的是定时器接收,定时器时间设置为20ms,正好和接收模块发送给ESP32的频率一样,数据传输不会产生错误,尽量接收频率大于发送频率(我用两块ESP32试了一下串口传输,接收端将接受的数据存入列表,如果接收频率低于发送频率,就容易导致数据上一次数据和下一次数据拼接到一起产生数据错乱)

每次收到一个数据帧,这个数据的格式为 A5 xx xx ,A5是帧头,是用来鉴别数据的 

2.代码

现象:左右超声波接收,而后在终端打印距离

代码如下:

""" 成功了,很开心"""
import time
from machine import Pin, Timer
from machine import UART
from machine import PWM


distance_left = 0
distance_right = 0

# 定义 UART 控制对象
uart1 = UART(1, baudrate=115200, rx=22, tx=23)
uart2 = UART(2, baudrate=115200, rx=18, tx=19)

"""计算左右距离"""
def get_distance():
    global distance_right
    global distance_left
    if uart1.any():  #如果接收到就执行,未接受到就跳过
        buf1 = uart1.read(20)  #最多读取20个字符
        distance_left = int.from_bytes(buf1[1:3],"big")
                
    if uart2.any():
        buf2 = uart2.read(20)  #最多读取20个字符
        distance_right = int.from_bytes(buf2[1:3],"big")
    print("左超声波距离:{}   右超声波距离:{}".format(distance_left,distance_right))
    
    
# 定义定时器对象
timer = Timer(0)
def timer_irq(timer_obj):
    get_distance()
     
# 初始化定时器对象   周期20ms   超声波频率50Hz 20ms
timer.init(mode=Timer.PERIODIC, period=20, callback=timer_irq) 
    
led2 = PWM(Pin(2, Pin.OUT), freq=1000)    

#主循环随便放了个呼吸灯
while True:
    for i in range(0, 1024):
        led2.duty(i)
        time.sleep_ms(1)
        

关于bytes类型切片操作 bytes_distance [1:3]-->截取索引1-3(不包含3)

我犯的错是这样的:误认为每一个字符,都有一个索引

a = b'\xa5\x00\xC8'
print(a.split('\x'))

#输出结果:  b''
#没错,就是空字节

这个其实类似于列表,列表中不同数据是用逗号“,”分开的,而bytes中使用"\x",也就是说,b'\xa5\x00\xC8'中,其实a5是一个整体,00是一个整体,c8是一个整体。可以复制以下代码验证一下,理解理解:

c=b'\xa5\x00\xC8'

print(c[1:3])  

str_buf1 = int.from_bytes(c[1:3],'big')
print(str_buf1)

输出:

b'\x00\xC8'  #c[1:3]

200          #str_buf1


总结

本人大二本科在读,电子信息小白,因此文章一些内容可能不严谨,或者有错误,欢迎大家评论区批评指正。

如果侵权请联系删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值