python与串口通信
激光雷达通信协议解析
- 串口基本属性:
波特率:230400
数据:8位数据,一位停止位,无校验位 - 数据协议解析
单数据包结构及字节偏移:


数据包如图所示,数据为小段存储。距离信息解析
- 每包数据的第8到55个字节是雷达测得的距离信息,每三个字节为一组,表示一个采样点的距离(第三个字节为强度信息,计算距离时不用)。
距离信息的MSB的高两位为数据有效标志位,01为有效,10无效,可用以下方式判断:if SLx.MSB & 0xC0 == 64:#采样点有效 - 距离的计算:
SLx.Distance = ((SLx.MSB & 0x3F) << 8) | SLx.LSB
- 角度信息解析
- 每包数据的第6、7字节为起始角信息,第56/57字节为终止角信息。
- 起始角和终止角的计算:
firstangle = ((cache[5] << 8 | cache[4])-0xA000)/64 lastangle = ((cache[55] << 8 | cache[54])-0xA000)/64 - 假设激光雷达的角速度是不变的,那么就可以得到16个采样点每个点的角度信息:
if firstangle<lastangle: delta_angle=lastangle-firstangle else: delta_angle=360+lastangle-firstangle while j<16: self.A.append(firstangle+j*delta_angle/15) j+=1python与激光雷达串口通信
- 设置串口波特率,调用串口函数进行初始化。
from machine import Pin, UART def __init__(self,baudRate=115200,handler=None): self.port=UART(1, baudrate=baudRate, tx=17, rx=16) - 使用
UART.read(1)函数从串口读取1字节数据,此时需注意判断所读取的数据是否为 空。def Read(self,length=1024,strict=True):#数据读取,长度为length cache=[] if not strict: while self.port.any() and len(cache)<length:#缓存区数据和cache数据长度小于len cache.append(ord(self.port.read(1))) else: while len(cache)<length: tmp=self.port.read(1) if tmp!=None: cache.append(ord(tmp)) return cache - 从串口 逐个 读取1字节数据,来判断数据包头的位置(包头为0xaa55,小端存储),以便后续的信息提取。
while(count<num): if(data_1[0]==0x55): data_2=self.usart.Read(1) if(data_2[0]==0xaa): self.ori_data_get() count+=1 else: data_1=data_2 else: data_1=self.usart.Read(1) - 得到包头后,再读取一包数据的剩余的58个数据,并进行极坐标的计算。
注意用if cache[7+3*i]&0xc0==64:来判断该采样点的数据是否有效。如全部有效将会得到16个距离信息和16个角度信息。def ori_data_get(self): length=58 cache=[] while len(cache)<length: tmp=self.usart.Read(1) cache.append(tmp[0]) self.pole_data_cal(cache)#获取剩余的58个数据 def pole_data_cal(self,cache): i=0 firstangle = ((cache[5] << 8 | cache[4])-0xA000)/64 lastangle = ((cache[55] << 8 | cache[54])-0xA000)/64 if firstangle<lastangle: delta_angle=lastangle-firstangle else: delta_angle=360+lastangle-firstangle#计算角度差 while i<16: if cache[7+3*i]&0xc0==64:#判断该采样点的数据是否有效 dis=((cache[7+i*3]&0x3f)<<8)|cache[6+i*3]#计算有效点的距离 self.D.append(dis) self.A.append(firstangle+i*delta_angle/15) i+=1 - 将获得的极坐标数据转化为平面直角坐标数据。 注意角度和弧度的转换
x=distance_num[i]*cos(angle_num[i]*3.1415926/180) y=distance_num[i]*sin(angle_num[i]*3.1415926/180)雷达的显示
- st7753s屏幕的坐标范围为 128×160,为了将雷达数据显示在屏幕上且以屏中心为原点,进行如下线性变换。
x_new=int(round(xy1[0]/15))+64
y_new=int(round(xy1[1]/15))+80 - 雷达每次数据采集转过的角度约为 10° ,为了采集一周的数据,可将雷达采集次数设置为 36 ,即每采集36次清除屏幕数据一次。由于雷达会有无效数据点的存在,我们可以将采集次数设置为 72 以保证数据的完整性。
- 完整的.py代码如下:
def show_radar(self):#在屏幕上显示雷达数据 while True: self.lcd.clear()#清屏 for i in range(72): xy=self.radar.xandy_data()#获取雷达数据 #self.lcd.clear() for i in range(len(xy)): xy1=xy[i] x_new=int(round(xy1[0]/15))+64 y_new=int(round(xy1[1]/15))+80#将雷达数据线性变换到屏幕上的点 self.lcd.pixel(x_new,y_new,1) self.lcd.show()#显示
作者:admin 创建时间:2024-03-20 15:22
最后编辑:rd.you 更新时间:2024-07-17 11:01
最后编辑:rd.you 更新时间:2024-07-17 11:01