Embedded_game/002_B_Car/主程序/试题/len_B_0423.py
2025-01-02 12:48:11 +08:00

742 lines
29 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding:utf-8 -*-
# @Author len
# @Create 2023/11/23 11:28
import math
import sensor, image, time, lcd
import binascii
from Maix import GPIO
from machine import Timer, PWM, UART, Timer
from fpioa_manager import fm
import KPU as kpu
class Mainlen():
def __init__(self):
'''初始化摄像头和 LCD 显示屏'''
lcd.init() # lcd初始化
self.canera_init() # 摄像头初始化
# sensor.set_auto_gain(0, gain_db=17) # 设置摄像头的自动增益功能
# 映射串口引脚
fm.register(6, fm.fpioa.UART1_RX, force=True)
fm.register(7, fm.fpioa.UART1_TX, force=True)
# 初始化串口
self.uart = UART(UART.UART1, 115200, read_buf_len=4096)
# 循迹
# --------------感光芯片配置 START -------------------
self.IMG_WIDTH = 240
self.IMG_HEIGHT = 320
# 直线灰度图颜色阈值
self.LINE_COLOR_THRESHOLD = [(0, 60)] # 找黑色
self.LINE_COLOR_BAISE = [(60, 255)] # 找白色
self.ROIS = { # 找黑色
# 'left': (0, 0, 320, 50), # 纵向取样-左侧
# 'right': (0, 190, 320, 50), # 纵向取样-右侧
'left': (0, 0, 180, 50), # 纵向取样-左侧
'right': (0, 190, 180, 50), # 纵向取样-右侧
'up': (240, 0, 80, 240), # 横向取样-上方
'middle_up': (160, 0, 80, 240), # 横向取样-中上
'middle_down': (80, 0, 80, 240), # 横向取样-中下
'down': (0, 0, 80, 240), # 横向取样-下方
}
# 红黄绿的阈值
# 颜色识别阈值 (L Min, L Max, A Min, A Max, B Min, B Max) LAB模型
# 下列阈值元组用来识别 红、绿、蓝三种颜色,可通过调整数据阈值完成更多颜色的识别。
# self.thresholds = [(59, 100, 40, 127, 5, 127), # 红色阈值
# (90, 100, -5, 2, -4, 20), # 黄色阈值
# (87, 100, -59, 127, -10, 127),] # 绿色阈值
self.thresholds = [(56, 99, 13, 63, -18, 37, "红色"), # 红色阈值
(69, 100, -7, 14, 1, 46, "黄色"), # 黄色阈值
(55, 100, -51, -16, -9, 83, "绿色")] # 绿色阈值
self.is_need_send_data = False # 是否需要发送数据的信号标志
self.QRFlag = 0
# 主函数 run
def startMain(self):
Flag_track = False # 循迹标识
Flag_qr = False # 二维码标识
Flag_qr_2 = False # 标识B
Flag_light = False # 交通灯标识
Flag_Camera_wheel = False # 摄像头转弯
while True:
data = self.uart.read(8)
# print(data)
# print(len(data))
# if (len(data) >= 8):
if data is not None:
if (data[1] == 0x02) and (data[7] == 0xBB) and self.verify_checksum(data):
# 巡线与控制舵机
if data[2] == 0x91:
if data[3] == 0x01: # 启动循迹
sensor.set_pixformat(sensor.GRAYSCALE) # 设置像素格式为灰色
Flag_track = True
print("开始循迹")
elif data[3] == 0x02: # 停止循迹
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565
Flag_track = False
print("停止循迹")
elif data[3] == 0x03: # 调整舵机
print("调整舵机")
self.Servo(data)
elif data[3] == 0x04: # 启动摄像头转弯
print("摄像头转弯")
Flag_Camera_wheel = True
elif data[3] == 0x05: # 停止摄像头转弯
print("停止摄像头转弯")
Flag_Camera_wheel = False
else:
pass
# 识别任务
elif data[2] == 0x92:
if data[3] == 0x01: # 识别二维码
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565
Flag_qr = True
print("开始识别二维码")
elif data[3] == 0x02: # 停止识别二维码
Flag_qr = False
print("停止识别二维码")
elif data[3] == 0x03: # 识别交通灯
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565
Flag_light = True
print("开始识别交通灯")
elif data[3] == 0x04: # 停止识别交通灯
Flag_light = False
print("停止识别交通灯")
elif data[3] == 0x06: # 调整摄像头阈值
print("调整摄像头阈值")
self.canera_ash()
elif data[3] == 0x09:
print("开始识别第二个二维码")
Flag_qr_2 = True
elif data[3] == 0x10:
print("停止识别第二个二维码")
Flag_qr_2 = False
else:
pass
img = sensor.snapshot() # 获取图像
if Flag_track: # 循迹
print("循迹")
self.tracking(img)
elif Flag_Camera_wheel: # 摄像头转弯
print("摄像头转弯")
self.Camera_wheel(img)
elif Flag_qr and (self.QRFlag <3): # 二维码
print("识别二维码")
self.discem_QR(img)
Flag_qr = False
elif Flag_light: # 红绿灯
print("识别红绿灯")
self.discem_light()
# Flag_light = False
elif Flag_qr_2:
print("识别第二个二维码")
self.discem_QR_2(img)
Flag_qr_2 = False
lcd.display(img) # 在LCD显示
# 摄像头转弯
def Camera_wheel(self, img):
canvas = img.copy()
roi_blobs_result = {} # 在各个ROI中寻找色块的结果记录
for roi_direct in self.ROIS.keys():
roi_blobs_result[roi_direct] = {
'cx': 0,
'cy': 0,
'w': 0,
'blob_flag': False
}
for roi_direct, roi in self.ROIS.items():
blobs = canvas.find_blobs(self.LINE_COLOR_THRESHOLD, roi=roi, merge=True)
if len(blobs) != 0:
largest_blob = max(blobs, key=lambda b: b.pixels())
if largest_blob.area() > 1000:
roi_blobs_result[roi_direct]['cx'] = largest_blob.cy()
roi_blobs_result[roi_direct]['cy'] = largest_blob.cx()
roi_blobs_result[roi_direct]['w'] = largest_blob.h()
roi_blobs_result[roi_direct]['blob_flag'] = True
x, y, width, height = largest_blob[:4]
img.draw_rectangle((x, y, width, height), color=(255))
else:
# blobs=canvas.find_blobs(LINE_COLOR_THRESHOLD, roi=roi, merge=True, pixels_area=10)
continue
blobs_zuo = canvas.find_blobs(self.LINE_COLOR_THRESHOLD, roi=(0, 0, 180, 50), merge=True) # 车载摄像头屏幕左下部找黑色
blobs_you = canvas.find_blobs(self.LINE_COLOR_THRESHOLD, roi=(0, 190, 180, 50), merge=True) # 车载摄像头屏幕右下部找黑色
print(blobs_zuo)
print(blobs_you)
if len(blobs_zuo) != 0:
zuo = blobs_zuo[0][4]
else:
zuo = 0
if len(blobs_you) != 0:
you = blobs_you[0][4]
else:
you = 0
print(zuo, you)
if zuo >= 8000 or you >= 8000:
print("黑线")
wire = 0x01
else:
print("白线")
wire = 0x00
# print()
self.uart.write(bytes([0x55]))
self.uart.write(bytes([0x02]))
self.uart.write(bytes([0x93]))
self.uart.write(bytes([0x03])) # 线
self.uart.write(bytes([wire])) # 黑白线
self.uart.write(bytes([0x03]))
self.uart.write(bytes([0x03]))
self.uart.write(bytes([0xbb]))
# 初始化摄像头阈值
def canera_init(self):
# 摄像头模块初始化
sensor.reset() # 复位和初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565
# sensor.set_pixformat(sensor.GRAYSCALE) # 设置像素格式为灰色
sensor.set_framesize(sensor.QVGA) # 设置帧大小为QVGA320×240
sensor.set_vflip(1) # 后置模式
sensor.skip_frames(30) # # 跳过前30帧
# 调整摄像头阈值
def canera_ash(self):
sensor.reset() # 复位和初始化摄像头
sensor.set_vflip(1) # 将摄像头设置成后置方式(所见即所得)
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为彩色 RGB565
# sensor.set_pixformat(sensor.GRAYSCALE) # 设置像素格式为灰色
sensor.set_framesize(sensor.QVGA) # 设置帧大小为 QVGA (320x240)
# sensor.set_windowing((224, 224)) # 设置摄像头的窗口大小
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
sensor.set_auto_gain(0, 0)
sensor.skip_frames(time=200) # 等待设置生效
# 红绿灯
def discem_light(self):
# 初始化
results = []
start_time = time.time()
while time.time() - start_time < 3: # 循环持续三秒
img = sensor.snapshot()
img = img.crop((160, 0, 80, 224))
# print(img.width()) # 320
# print(img.height()) #240
# img = img.crop((0, 0, 160, 224))
max_blob = None
max_blob_size = 0
max_blob_color = ""
max_blob_color_index = 0
# 找圆
# circles = img.find_circles(threshold=3500, x_margin=10, y_margin=10, r_margin=10,
# r_min=2, r_max=100, r_step=2)
for index, threshold in enumerate(self.thresholds):
# 查找每种颜色的色块
blobs = img.find_blobs([threshold[:-1]], pixels_threshold=150, area_threshold=150, merge=True)
if blobs:
# 找到最大的色块
blob = max(blobs, key=lambda b: b.pixels())
if blob.pixels() > max_blob_size:
max_blob = blob
max_blob_size = blob.pixels()
max_blob_color = threshold[-1] # 颜色标签
max_blob_color_index = index
# print(circles)
# # 画圆
# for c in circles:
# area = (c.x() - c.r(), c.y() - c.r(), 2 * c.r(), 2 * c.r())
# img.draw_rectangle(area, color=(255, 255, 255))
# 绘制最大色块的矩形和中心十字,并输出颜色
if max_blob:
results.append((max_blob_color, max_blob_color_index)) # 存储识别结果
img.draw_rectangle(max_blob[0:4])
img.draw_cross(max_blob[5], max_blob[6])
print("最大色块的颜色是:", max_blob_color, max_blob_color_index)
# 初始化计数字典
color_count = {}
for color, index in results:
if (color, index) in color_count:
color_count[(color, index)] += 1
else:
color_count[(color, index)] = 1
# 找出出现次数最多的颜色和下标
if color_count:
most_common_color, most_common_index = max(color_count, key=color_count.get)
print("出现最多的颜色:", most_common_color, "在下标位置:", most_common_index)
else:
most_common_index = 1
print("没有识别到有效的颜色块")
# 串口发送交通灯信息
# send_data = [
# 0x55,
# 0x02,
# 0x92,
# 0x03,
# most_common_index,
# 0xbb]
# print("红绿灯指令", send_data, "******************", bytes(send_data))
# self.UsartSend(bytes(send_data))
self.uart.write(bytes([0x55]))
self.uart.write(bytes([0x02]))
self.uart.write(bytes([0x92]))
self.uart.write(bytes([0x03])) # 红绿灯
self.uart.write(bytes([most_common_index])) # 红绿灯结果
self.uart.write(bytes([0x03]))
self.uart.write(bytes([0x03]))
self.uart.write(bytes([0xbb]))
self.canera_init() # 恢复摄像头
# 二维码
def discem_QR(self, img):
# self.Tise_servo(10)
res_QR = img.find_qrcodes() # 寻找二维码
timeflag = 0
while timeflag < 30:
img = sensor.snapshot() # 获取图像
TS_QR = img.find_qrcodes() # 再次寻找二维码
for qr in TS_QR:
if all(qr.payload() != existing_qr.payload() for existing_qr in res_QR):
res_QR.append(qr)
timeflag += 1
time.sleep(0.001)
# print(timeflag)
print(len(res_QR))
if len(res_QR): # 识别到
for res in range(len(res_QR)):
count = 0
if_end = 0x01
result = res_QR[res].payload()
print(result)
if len(result) == 8: # 车牌
result = self.extract_numbers_and_letters_combined(result)
count = 1
elif self.if_formula(result): # 公式
count = 2
# continue
if res == len(res_QR) - 1:
if_end = 0x00
# if_end = 0x00
print("count: ", count)
print("if_end: ", if_end)
# 串口发送二维码信息
self.uart.write(bytes([0x55]))
self.uart.write(bytes([0x02]))
self.uart.write(bytes([0x92]))
self.uart.write(bytes([0x06]))
self.uart.write(bytes([count]))
self.uart.write(bytes([if_end]))
self.uart.write(bytes([len(result)]))
for qr_data in result:
self.uart.write(bytes([ord(qr_data)]))
print(bytes([ord(qr_data)]))
self.uart.write(bytes([0xbb]))
time.sleep(1)
else: # 未识别
self.uart.write(bytes([0x55]))
self.uart.write(bytes([0x02]))
self.uart.write(bytes([0x92]))
self.uart.write(bytes([0x06]))
self.uart.write(bytes([0xff]))
self.uart.write(bytes([0x00]))
self.uart.write(bytes([0x00]))
self.uart.write(bytes([0xbb]))
# time.sleep(1)
def discem_QR_2(self, img):
# self.Tise_servo(10)
res_QR = img.find_qrcodes() # 寻找二维码
timeflag = 0
while timeflag < 30:
img = sensor.snapshot() # 获取图像
TS_QR = img.find_qrcodes() # 再次寻找二维码
for qr in TS_QR:
if all(qr.payload() != existing_qr.payload() for existing_qr in res_QR):
res_QR.append(qr)
timeflag += 1
time.sleep(0.001)
# print(timeflag)
print(len(res_QR))
if len(res_QR) == 2:
qr_txt = [res_QR[0].payload(), res_QR[1].payload()]
# 调用函数处理示例列表
result_list = self.extract_differences(qr_txt)
# 串口发送二维码信息
self.uart.write(bytes([0x55]))
self.uart.write(bytes([0x02]))
self.uart.write(bytes([0x92]))
self.uart.write(bytes([0x07]))
self.uart.write(bytes([0x01]))
# self.uart.write(bytes([if_end]))
#
# self.uart.write(bytes([len(result_list)]))
for qr_data in result_list:
self.uart.write(bytes([ord(qr_data)]))
print(bytes([ord(qr_data)]))
self.uart.write(bytes([0xbb]))
time.sleep(1)
# for res in range(len(res_QR)):
# count = 0
# if_end = 0x01
# result = res_QR[res].payload()
# print(result)
#
# if len(result) == 8: # 车牌
# result = self.extract_numbers_and_letters_combined(result)
# count = 1
#
# elif self.if_formula(result): # 公式
# count = 2
# # continue
#
# if res == len(res_QR) - 1:
# if_end = 0x00
# # if_end = 0x00
# print("count: ", count)
# print("if_end: ", if_end)
else: # 未识别
self.uart.write(bytes([0x55]))
self.uart.write(bytes([0x02]))
self.uart.write(bytes([0x92]))
self.uart.write(bytes([0x07]))
self.uart.write(bytes([0xff]))
self.uart.write(bytes([0x00]))
self.uart.write(bytes([0x00]))
self.uart.write(bytes([0xbb]))
# time.sleep(1)
# 提取字符和数字
def extract_numbers_and_letters_combined(self, text):
combined_str = ''
for char in text:
# 检查字符是否是数字0-9或字母A-Z 或 a-z
if ('0' <= char <= '9') or ('A' <= char <= 'Z') or ('a' <= char <= 'z'):
combined_str += char
return combined_str
def extract_differences(self, QR_txt):
"""
该函数接收一个包含两个二维码字符串的列表,提取尖括号内的有效信息,
并根据给定规则返回两个二维码之间的差异数据。
"""
# 提取两个二维码中尖括号内的数据
qr_data = [qr[qr.find("<") + 1:qr.find(">")] for qr in QR_txt]
# # 检查提取的数据是否确切地为15个字节长
# if not all(len(data) == 15 for data in qr_data):
# return "错误尖括号内的数据不是15个字节长。"
# 对比数据并找出差异
differences = [[], []] # differences[0] 用于存储 QR1 != QR2 的差异,反之亦然
for a, b in zip(qr_data[0], qr_data[1]):
if a != b:
differences[0].append(a)
differences[1].append(b)
# 按要求返回合并后的差异数据
char_list = differences[0] + differences[1]
return ''.join(char_list)
def if_formula(self, text):
# 允许的字符:数字、运算符和括号
allowed_chars = "0123456789+-*/%^(). abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
# 检查字符是否合法
for char in text:
if char not in allowed_chars:
return False
# 括号匹配检查
bracket_count = 0
for char in text:
if char == '(':
bracket_count += 1
elif char == ')':
bracket_count -= 1
if bracket_count < 0: # 右括号多于左括号
return False
if bracket_count != 0: # 左括号和右括号数量不匹配
return False
return True
# 移除字符串内的中文
def remove_chinese_chars(self, text):
"""移除字符串中的中文字符,并返回新的字符串"""
# 定义中文字符的Unicode范围
chinese_char_ranges = [
('\u4e00', '\u9fff'), # 基本汉字
('\u3400', '\u4dbf'), # 扩展A
('\u20000', '\u2a6df'), # 扩展B
# 可以根据需要添加更多的中文范围
]
# 移除中文字符
return ''.join(char for char in text if not any(start <= char <= end for start, end in chinese_char_ranges))
# 循迹
def tracking(self, img):
print("循迹")
roi_blobs_result = self.find_blobs_in_rois(img)
down_center, state_crossing, deflection_angle = self.state_deflection_angle(roi_blobs_result)
dsd = self.data_format_wrapper(down_center, state_crossing, deflection_angle)
self.UsartSend(dsd)
print("下发指令:", dsd)
# 寻找色块 在ROIS中寻找色块获取ROI中色块的中心区域与是否有色块的信息
def find_blobs_in_rois(self, img):
canvas = img.copy()
roi_blobs_result = {} # 在各个ROI中寻找色块的结果记录
for roi_direct in self.ROIS.keys():
roi_blobs_result[roi_direct] = {
'cx': 0,
'cy': 0,
'w': 0,
'blob_flag': False
}
for roi_direct, roi in self.ROIS.items():
blobs = canvas.find_blobs(self.LINE_COLOR_THRESHOLD, roi=roi, merge=True)
if len(blobs) != 0:
largest_blob = max(blobs, key=lambda b: b.pixels())
if largest_blob.area() > 1000:
roi_blobs_result[roi_direct]['cx'] = largest_blob.cy()
roi_blobs_result[roi_direct]['cy'] = largest_blob.cx()
roi_blobs_result[roi_direct]['w'] = largest_blob.h()
roi_blobs_result[roi_direct]['blob_flag'] = True
x, y, width, height = largest_blob[:4]
img.draw_rectangle((x, y, width, height), color=(255))
else:
# blobs=canvas.find_blobs(LINE_COLOR_THRESHOLD, roi=roi, merge=True, pixels_area=10)
continue
blobs_baise = canvas.find_blobs(self.LINE_COLOR_BAISE, roi=(0, 0, 60, 240),
merge=True) # 车载摄像头屏幕下部找白色#宽度200修改为240#用途寻卡y示例中40修改为0
blobs_dixing = canvas.find_blobs(self.LINE_COLOR_BAISE, roi=(125, 0, 60, 240),
merge=True) # 车载摄像头屏幕中间找白色 #宽度200修改为240y示例中40修改为0
blobs_zuo = canvas.find_blobs(self.LINE_COLOR_THRESHOLD, roi=(0, 0, 180, 50), merge=True) # 车载摄像头屏幕左下部找黑色
blobs_you = canvas.find_blobs(self.LINE_COLOR_THRESHOLD, roi=(0, 190, 180, 50), merge=True) # 车载摄像头屏幕右下部找黑色
if len(blobs_baise) != 0:
print("*********进入循环第1步*******")
largest_baise = max(blobs_baise, key=lambda b: b.pixels())
wx, wy, wwidth, wwheight = largest_baise[:4]
arc = wwidth * wwheight
if arc >= 11000:
print("*********进入循环第2步*******")
if len(blobs_dixing) != 0:
print("*********进入循环第3步*******")
largest_dixing = max(blobs_dixing, key=lambda b: b.pixels())
wx, wy, wwidth, wwheight = largest_dixing[:4]
arc = wwidth * wwheight
if arc >= 11000:
print('kapian') # 首先中部区域识别到白色进入判断地形还是卡片,接着判断下部,如果为白色判断为卡片。
self.UsartSend(self.data_format_wrapper(0, 1, 0)) # 地形停止命令
if len(blobs_zuo) != 0 and len(blobs_you) != 0:
print("ka十字路口")
self.UsartSend(self.data_format_wrapper(1, 1, 0)) # 地形停止命令
else:
print('dixing')
print(roi_blobs_result) # 返回的是黑色色块,各区域中心位置
self.UsartSend(self.data_format_wrapper(0, 1, 0)) # 地形停止命令
return roi_blobs_result # 返回的是黑色色块,各区域中心位置
# 计算偏转状态值
def state_deflection_angle(self, roi_blobs_result):
'''
说明:偏转状态值返回
'''
# ROI区域权重值
# ROIS_WEIGHT = [1, 1, 1, 1]
ROIS_WEIGHT = [1, 0, 0, 1]
state_crossing = False
deflection_angle = 0 # 偏转角
down_center = 0 # 中下值
center_num = 0 # 中间值
# print(roi_blobs_result)
# 偏转值计算ROI中心区域X值
centroid_sum = roi_blobs_result['up']['cx'] * ROIS_WEIGHT[0] + roi_blobs_result['middle_up']['cx'] * \
ROIS_WEIGHT[1] \
+ roi_blobs_result['middle_down']['cx'] * ROIS_WEIGHT[2] + roi_blobs_result['down']['cx'] * \
ROIS_WEIGHT[3]
if roi_blobs_result['up']['blob_flag']:
center_num += ROIS_WEIGHT[0]
if roi_blobs_result['middle_up']['blob_flag']:
center_num += ROIS_WEIGHT[1]
if roi_blobs_result['middle_down']['blob_flag']:
center_num += ROIS_WEIGHT[2]
if roi_blobs_result['down']['blob_flag']:
center_num += ROIS_WEIGHT[3]
center_pos = centroid_sum / (ROIS_WEIGHT[0] + ROIS_WEIGHT[1] + ROIS_WEIGHT[2] + ROIS_WEIGHT[3])
deflection_angle = (self.IMG_WIDTH / 2) - center_pos
# 判断两侧ROI区域检测到黑色线
if roi_blobs_result['left']['blob_flag'] and roi_blobs_result['right']['blob_flag']:
# 判断两侧ROI区域检测到黑色线处于图像下方1/3处
if roi_blobs_result['left']['cy'] <= ((self.IMG_HEIGHT / 3)) or roi_blobs_result['right']['cy'] <= (
(self.IMG_HEIGHT / 3)):
# 当最下方ROI区域的黑线宽度大于140像素检测到路口
if roi_blobs_result['down']['w'] > 140:
down_center = 1 # 自行修改处 判断识别到十字路口
print("输出了十字路口标识")
return down_center, state_crossing, deflection_angle
# 控制舵机
def Tise_servo(self, angle):
# 判断舵机控制方向
if angle < 0:
# 限制舵机角度,防止过大损坏舵机
if angle > 80:
angle = 80
angle = -angle
elif angle > 0:
# 限制舵机角度,防止过大损坏舵机
if angle > 35:
angle = 35
angle = angle
# PWM通过定时器配置接到IO17引脚
tim_pwm = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
S1 = PWM(tim_pwm, freq=50, duty=0, pin=17)
S1.duty((angle + 90) / 180 * 10 + 2.5)
def Servo(self, data):
'''
功能180度舵机angle:-90至90 表示相应的角度
360连续旋转度舵机angle:-90至90 旋转方向和速度值。
【duty】占空比值0-100
'''
angle = data[5]
# 判断舵机控制方向
if data[4] == ord('-'):
# 限制舵机角度,防止过大损坏舵机
if angle > 80:
angle = 80
angle = -angle
elif data[4] == ord('+'):
# 限制舵机角度,防止过大损坏舵机
if angle > 35:
angle = 35
angle = angle
# PWM通过定时器配置接到IO17引脚
tim_pwm = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PWM)
S1 = PWM(tim_pwm, freq=50, duty=0, pin=17)
S1.duty((angle + 90) / 180 * 10 + 2.5)
# 检验校验和
def verify_checksum(self, data):
if len(data) != 8:
return False
# 计算校验和data[2]、data[3]、data[4] 和 data[5] 的和然后对256取模
calculated_checksum = (data[2] + data[3] + data[4] + data[5]) % 256
# 比较计算出的校验和与data[6]是否相等
if calculated_checksum == data[6]:
return True
else:
return False
# 串口发送
def UsartSend(self, str_data):
'''
串口发送函数
'''
print(str_data)
self.uart.write(str_data)
# 判断符号
def get_symbol(self, num):
'''
根据数值正负,返回数值对应的符号
正数: + 负数‘- 主要为了方便C语言解析待符号的数值。
'''
print("num = ", num)
if num >= 0:
return ord('+')
else:
return ord('-')
# 封装数据
def data_format_wrapper(self, down_center, state_crossing, deflection_angle):
'''
根据通信协议封装循迹数据
TODO 重新编写通信协议 与配套C解析代码
'''
send_data = [
0x55,
0x02,
0x91,
down_center, # 底部色块中心是否在中点附近#底部色块十字路口
1 if state_crossing else 0, # 是否越障 无用
self.get_symbol(deflection_angle), # 偏航角符号 print输出是43 + 45- +向左转调整 -向右转调整
abs(int(deflection_angle)), # 偏航角
0xbb]
return bytes(send_data)
# 运行程序
myMain = Mainlen()
myMain.startMain()