TA的每日心情 | 开心 2024-9-19 10:25 |
|---|
签到天数: 2 天 连续签到: 1 天 [LV.1]初来乍到
童生
- 积分
- 87
|
本帖最后由 eefocus_3897960 于 2025-2-28 23:53 编辑
一、项目名称:基于树莓派的汽车安全防护系统
二、项目概述:随着汽车保有量的增加,交通事故频发,尤其在倒车、变道、盲区等场景下安全隐患突出。传统车载安全系统(如倒车雷达)存在检测范围有限、抗干扰能力弱等问题。本项目基于树莓派4B/5主控平台,结合超声波传感器(近距离探测)、毫米波雷达(中远距离探测)、LED灯(光提示)和蜂鸣器(声音警告),设计一套低成本、高精度、多层次的汽车主动安全防护系统,实现环境感知-数据分析-实时预警-人机交互的闭环控制,降低碰撞风险。三、作品实物图: 四、项目代码 - import RPi.GPIO as GPIO
- import time
- # 硬件引脚定义
- TRIG_PIN = 23 # 超声波Trig引脚(GPIO23/物理引脚16)
- ECHO_PIN = 24 # 超声波Echo引脚(GPIO24/物理引脚18)
- BUZZER_PIN = 18 # 蜂鸣器控制引脚(GPIO18/物理引脚12)
- LED_PIN = 25 # LED控制引脚(GPIO25/物理引脚22)
- # 初始化设置
- def setup():
- GPIO.setmode(GPIO.BCM) # 使用BCM编号
- GPIO.setup(TRIG_PIN, GPIO.OUT) # Trig引脚输出模式
- GPIO.setup(ECHO_PIN, GPIO.IN) # Echo引脚输入模式
- GPIO.setup(BUZZER_PIN, GPIO.OUT)
- GPIO.setup(LED_PIN, GPIO.OUT)
-
- # 初始化关闭蜂鸣器和LED
- GPIO.output(BUZZER_PIN, False)
- GPIO.output(LED_PIN, False)
- # 超声波测距函数
- def get_distance():
- # 发送触发信号
- GPIO.output(TRIG_PIN, True)
- time.sleep(0.00001) # 持续10微秒
- GPIO.output(TRIG_PIN, False)
- # 记录回波时间
- timeout = 0.1 # 100ms超时时间(约对应5.8米)
- t_start = time.time()
- while GPIO.input(ECHO_PIN) == 0:
- if (time.time() - t_start) > timeout:
- return -1 # 超时返回错误
- pulse_start = time.time()
- t_start = time.time()
- while GPIO.input(ECHO_PIN) == 1:
- if (time.time() - t_start) > timeout:
- return -1 # 超时返回错误
- pulse_end = time.time()
- # 计算距离(单位:厘米)
- pulse_duration = pulse_end - pulse_start
- distance = pulse_duration * 34300 / 2 # 声速343m/s=34300cm/s
- return round(distance, 1)
- # 报警控制函数
- def alert_control(distance):
- if distance < 50 and distance > 0: # 有效报警范围
- # 蜂鸣器高频鸣叫(0.1秒间隔)
- GPIO.output(BUZZER_PIN, True)
- GPIO.output(LED_PIN, True)
- time.sleep(0.1)
- GPIO.output(BUZZER_PIN, False)
- GPIO.output(LED_PIN, False)
- time.sleep(0.1)
- else:
- GPIO.output(BUZZER_PIN, False)
- GPIO.output(LED_PIN, False)
- # 主程序
- def main():
- setup()
- try:
- while True:
- dist = get_distance()
- print(f"当前距离: {dist}cm")
- alert_control(dist)
- time.sleep(0.2) # 每次测量间隔200ms
- except KeyboardInterrupt:
- GPIO.cleanup()
- if __name__ == "__main__":
- main()
复制代码- import serial
- import RPi.GPIO as GPIO
- import time
- from struct import unpack
- # 硬件配置
- BUZZER_PIN = 18
- LED_PIN = 25
- SERIAL_PORT = "/dev/ttyAMA0" # 树莓派5 UART默认设备
- BAUD_RATE = 256000
- # LD2451协议常量
- HEADER = bytes([0xF4, 0xF3, 0xF2, 0xF1])
- ALERT_DISTANCE = 10.0 # 报警阈值(单位:米)
- def setup():
- GPIO.setmode(GPIO.BCM)
- GPIO.setup(BUZZER_PIN, GPIO.OUT)
- GPIO.setup(LED_PIN, GPIO.OUT)
- GPIO.output(BUZZER_PIN, False)
- GPIO.output(LED_PIN, False)
- def parse_binary_data(data):
- """
- 解析二进制数据帧
- 返回:目标列表,每个目标为字典格式
- """
- targets = []
- try:
- # 校验帧头
- if data[0:4] != HEADER:
- return []
-
- # 获取数据长度(小端序)
- data_len = unpack('<H', data[4:6])[0]
-
- # 校验数据完整性
- if len(data) < 6 + data_len + 1: # Header+Len+Data+Checksum
- return []
-
- # 计算校验和
- checksum = sum(data[0:6+data_len]) & 0xFF
- if checksum != data[6+data_len]:
- print(f"校验错误: 计算值{checksum} vs 接收值{data[6+data_len]}")
- return []
-
- # 解析目标数据(每24字节一个目标)
- target_count = data_len // 24
- for i in range(target_count):
- start = 6 + i*24
- end = start + 24
- target_bytes = data[start:end]
-
- # 解析结构体
- x, y, speed, _, distance, energy, status = unpack(
- '<hhhHHHBB', target_bytes[:16] # 仅解析前16字节关键数据
- )
-
- # 单位转换
- target = {
- 'x': x / 1000.0, # mm → m
- 'y': y / 1000.0,
- 'speed': speed / 1000.0, # mm/s → m/s
- 'distance': distance / 1000.0,
- 'energy': energy,
- 'status': '运动' if (status & 0x01) == 0 else '静止'
- }
- targets.append(target)
- return targets
-
- except Exception as e:
- print(f"解析异常: {e}")
- return []
- def alert_control(enable):
- GPIO.output(BUZZER_PIN, enable)
- GPIO.output(LED_PIN, enable)
- def main():
- setup()
- try:
- with serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=1) as ser:
- # 发送进入Binary模式指令(可选)
- ser.write(bytes([0xF4, 0xF3, 0xF2, 0xF1, 0x04, 0x00, 0x02, 0xAA, 0x55]))
-
- buffer = bytes()
- while True:
- buffer += ser.read_all()
-
- # 查找帧头
- while len(buffer) >= 6:
- header_pos = buffer.find(HEADER)
- if header_pos == -1:
- buffer = bytes()
- break
-
- # 截取完整帧
- if len(buffer) >= header_pos + 6:
- data_len = unpack('<H', buffer[header_pos+4:header_pos+6])[0]
- total_len = 4 + 2 + data_len + 1 # Header+Len+Data+Checksum
- if len(buffer) >= header_pos + total_len:
- frame = buffer[header_pos:header_pos+total_len]
- buffer = buffer[header_pos+total_len:]
- targets = parse_binary_data(frame)
-
- # 报警逻辑
- min_dist = min((t['distance'] for t in targets) if targets else 999
- alert_control(min_dist < ALERT_DISTANCE)
- print(f"最近目标: {min_dist:.2f}m 报警状态: {min_dist < ALERT_DISTANCE}")
-
- else:
- break
-
- time.sleep(0.05)
-
- except KeyboardInterrupt:
- GPIO.cleanup()
- if __name__ == "__main__":
- main()
复制代码 五、项目文档
|
|