17、打造智能汽车仪表盘:从基础到优化

打造智能汽车仪表盘:从基础到优化

在汽车仪表盘系统的搭建过程中,我们逐步完成了多个重要组件的开发,包括倒车摄像头、倒车蜂鸣器和距离传感器,接下来还将对系统进行美化和优化。下面将详细介绍各个组件的实现过程和相关技术要点。

1. 倒车摄像头与端口设置

在访问应用程序时,我们使用端口 5000,但通过右键检查开发者工具中的代码,会发现视频流来自 http://pi-car:8081 。这是因为应用程序运行在端口 5000,而视频流运行在端口 8081,它们是来自树莓派的独立数据流,无需合并。

2. 倒车蜂鸣器
  • 压电元件原理与购买 :压电元件通过电能产生电荷,使材料挤压或拉伸从而发出声音。其大小、供电量和时长都会影响声音输出。在台式电脑启动自检(POST)阶段,压电元件曾用于发出启动提示音。我们可以从亚马逊或当地电子商店购买“5v 压电元件”,建议选择适用于 3v 的元件,单个元件价格约 1 美元,批量购买单价更低。
  • 连接步骤
    1. 压电元件有极性,通常带有预焊的正负极线,若没有,一条腿会标记为负极。将负极连接到树莓派的接地端。
    2. 将正极连接到物理引脚 18(GPIO 引脚 24)。
  • Flask 逻辑实现
    • 单元测试 :在 test_sensors.py 中扩展 TestSensors 类,添加针对不良引脚工厂和其他错误的测试:
@patch("Pi_Car.sensors.Buzzer")
def test_beep_bad_pin_factory(self, mock_buzzer):
    mock_buzzer.side_effect = exc.BadPinFactory
    result = Sensors.beep()
    assert result is None

@patch("Pi_Car.sensors.Buzzer")
def test_beep_other_pin_error(self, mock_buzzer):
    mock_buzzer.side_effect = TypeError
    result = Sensors.beep()
    assert result is None
- **添加导入**:在 `sensors.py` 中添加时间库和 `Buzzer` 类的导入:
import time
from flask import current_app as app
from gpiozero import Button, exc, LightSensor, Buzzer
try:
    from w1thermsensor import W1ThermSensor
except Exception:
    W1ThermSensor = None
- **实现 `beep` 方法**:在 `Sensors` 类中添加静态方法 `beep`:
@staticmethod
def beep(duration=1):
    """
    Issue a single "beep" sound
    :param duration: Time to sustain beep for, in seconds
    :return: None
    """
    app.logger.info("Starting beep")
    app.logger.debug(f"Beep duration: {duration}")
    try:
        buzzer = Buzzer(pin=24)
        buzzer.on()
        time.sleep(duration)
        buzzer.off()
    except exc.BadPinFactory as e:
        app.logger.warning(f"Unable to issue beep in this environment: {e}")
    except Exception as e:
        app.logger.error(f"Unknown problem with beep: {e}")
    app.logger.info("Finished beep")
- **调用 `beep` 方法**:在 `data.py` 的主路由中临时调用 `beep` 方法:
@data_blueprint.route("/")
def show():
    app.logger.info("Starting to retrieve core data")
    temperature = Sensors.get_external_temp()
    boot_status = Sensors.get_boot_status()
    light_status = Sensors.get_light_status()
    reverse_light = Sensors.get_reverse_status()
    fog_light = Sensors.get_fog_light_status()
    result = {
        "temperature": temperature,
        "boot": boot_status,
        "light": light_status,
        "reverse": reverse_light,
        "fog": fog_light,
    }
    Sensors.beep()
    app.logger.info("Finished retrieving core data")
    app.logger.debug(f"Core data: {result}")
    return jsonify(result)
运行本地代码后,提交代码并在树莓派上构建,访问 `http://pi-car:5000` 监听蜂鸣声。若未听到,检查压电元件连接是否正确,查看树莓派应用日志。
3. 距离传感器
  • 检测原理与选择 :检测物体距离的常见方法是传感器发射信号(如声音、光或电磁脉冲),信号从附近物体反射回来,另一个传感器读取返回信号,返回时间越长,物体越远。本项目选择使用 KY - 032 红外传感器模块,它成本低、易于接线和编码,最大检测范围约 15 英寸。
  • 硬件连接步骤
    1. 关闭并断开树莓派电源。
    2. 研究 KY - 032 模块,其包含红外发射和接收对、电路、两个状态 LED、两个电位器和引脚。
    3. 电位器作用:左边电位器逆时针旋转可使传感器达到最大检测范围,右边电位器出厂已预设,无需调整。
    4. 引脚连接:将树莓派接地端连接到模块的 GND 引脚,3.3v 连接到 + 引脚,物理引脚 22(GPIO 引脚 25)连接到 Out 引脚,可忽略 EN 引脚。
    5. 连接电源并启动树莓派。
  • Flask 代码实现
    • 创建读取函数 :在 Sensors 类中创建 get_rear_distance_sensor 函数:
@classmethod
def get_rear_distance_sensor(cls):
    """
    Safely read the reversing sensor
    :return: Boolean - reversing or not, or None
    """
    app.logger.info("Starting to read distance sensor")
    result = cls.get_bool_pin(pin=25)
    if result:
        result = False
    else:
        result = True
    app.logger.debug(f"Rear distance sensor: {result}")
    app.logger.info("Finished reading distance sensor")
    return result
- **更新主路由**:在 `data.py` 的主路由中添加传感器调用并更新结果字典:
@data_blueprint.route("/")
def show():
    app.logger.info("Starting to retrieve core data")
    temperature = Sensors.get_external_temp()
    boot_status = Sensors.get_boot_status()
    light_status = Sensors.get_light_status()
    reverse_light = Sensors.get_reverse_status()
    fog_light = Sensors.get_fog_light_status()
    rear_distance = Sensors.get_rear_distance_sensor()
    result = {
        "temperature": temperature,
        "boot": boot_status,
        "light": light_status,
        "reverse": reverse_light,
        "rear_distance": rear_distance,
        "fog": fog_light,
    }
    Sensors.beep()
    app.logger.info("Finished retrieving core data")
    app.logger.debug(f"Core data: {result}")
    return jsonify(result)
验证代码后提交并构建,访问 `http://pi-car:500` 检查 `rear_distance` 结果,通过遮挡和移开传感器多次刷新页面进行测试。

系统美化与优化

  • 使用库介绍 :为了使仪表盘美观易用,我们将使用 Bootstrap 进行大部分样式和布局设计,使用 Font Awesome 提供开源图标。对于大多数网站,内容分发网络(CDN)可以快速引入这些外部资源,提高用户体验。
  • 发挥创意 :在系统美化阶段,你可以充分发挥创意,打造独特的仪表盘界面。如果你缺乏创意,也可以先制作一个简约的仪表盘作为基础,再进行扩展。

通过以上步骤,我们逐步完成了汽车仪表盘系统的各个组件开发和系统美化的准备工作,为打造一个功能完善、美观易用的汽车仪表盘奠定了基础。

打造智能汽车仪表盘:从基础到优化

4. 系统美化的具体操作
  • 引入 Bootstrap 和 Font Awesome
    要在项目中使用 Bootstrap 和 Font Awesome,我们可以通过 CDN 的方式引入。在 HTML 文件的 <head> 标签中添加以下代码:
<head>
    <!-- 引入 Bootstrap CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
    <!-- 引入 Font Awesome CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
</head>
  • 构建基础布局
    利用 Bootstrap 的网格系统来构建仪表盘的布局。以下是一个简单的示例:
<div class="container">
    <div class="row">
        <!-- 左侧区域 -->
        <div class="col-md-6">
            <h2>传感器数据</h2>
            <ul class="list-group">
                <li class="list-group-item">温度: <span id="temperature"></span></li>
                <li class="list-group-item">启动状态: <span id="boot_status"></span></li>
                <li class="list-group-item">灯光状态: <span id="light_status"></span></li>
                <li class="list-group-item">倒车灯状态: <span id="reverse_light"></span></li>
                <li class="list-group-item">雾灯状态: <span id="fog_light"></span></li>
                <li class="list-group-item">后方距离: <span id="rear_distance"></span></li>
            </ul>
        </div>
        <!-- 右侧区域 -->
        <div class="col-md-6">
            <h2>摄像头画面</h2>
            <img src="http://pi-car:8081" alt="倒车摄像头画面" class="img-fluid">
        </div>
    </div>
</div>
  • 添加交互效果
    可以使用 JavaScript 来实现一些交互效果,比如根据传感器数据更新页面内容。以下是一个简单的示例:
// 获取元素
const temperatureElement = document.getElementById('temperature');
const bootStatusElement = document.getElementById('boot_status');
const lightStatusElement = document.getElementById('light_status');
const reverseLightElement = document.getElementById('reverse_light');
const fogLightElement = document.getElementById('fog_light');
const rearDistanceElement = document.getElementById('rear_distance');

// 定时获取数据
setInterval(() => {
    fetch('/')
      .then(response => response.json())
      .then(data => {
            temperatureElement.textContent = data.temperature;
            bootStatusElement.textContent = data.boot;
            lightStatusElement.textContent = data.light;
            reverseLightElement.textContent = data.reverse;
            fogLightElement.textContent = data.fog;
            rearDistanceElement.textContent = data.rear_distance;
        });
}, 1000);
5. 系统优化
  • 优化蜂鸣器调用
    目前在 data.py 中调用 beep 方法会导致数据加载延迟,因为树莓派需要等待蜂鸣声完成。为了优化这一问题,我们可以使用异步编程。在 Python 中,可以使用 asyncio 库。首先,修改 sensors.py 中的 beep 方法:
import asyncio

@staticmethod
async def beep(duration=1):
    """
    Issue a single "beep" sound
    :param duration: Time to sustain beep for, in seconds
    :return: None
    """
    app.logger.info("Starting beep")
    app.logger.debug(f"Beep duration: {duration}")
    try:
        buzzer = Buzzer(pin=24)
        buzzer.on()
        await asyncio.sleep(duration)
        buzzer.off()
    except exc.BadPinFactory as e:
        app.logger.warning(f"Unable to issue beep in this environment: {e}")
    except Exception as e:
        app.logger.error(f"Unknown problem with beep: {e}")
    app.logger.info("Finished beep")
然后,在 `data.py` 中异步调用 `beep` 方法:
import asyncio

@data_blueprint.route("/")
async def show():
    app.logger.info("Starting to retrieve core data")
    temperature = Sensors.get_external_temp()
    boot_status = Sensors.get_boot_status()
    light_status = Sensors.get_light_status()
    reverse_light = Sensors.get_reverse_status()
    fog_light = Sensors.get_fog_light_status()
    rear_distance = Sensors.get_rear_distance_sensor()
    result = {
        "temperature": temperature,
        "boot": boot_status,
        "light": light_status,
        "reverse": reverse_light,
        "rear_distance": rear_distance,
        "fog": fog_light,
    }
    asyncio.create_task(Sensors.beep())
    app.logger.info("Finished retrieving core data")
    app.logger.debug(f"Core data: {result}")
    return jsonify(result)
  • 优化传感器数据读取
    可以对传感器数据的读取进行优化,减少不必要的读取次数。例如,使用缓存机制,在一定时间内如果数据没有变化,就直接使用缓存的数据。以下是一个简单的缓存实现示例:
import time

class SensorCache:
    def __init__(self):
        self.cache = {}
        self.last_update_time = {}
        self.cache_duration = 1  # 缓存时间,单位:秒

    def get(self, key):
        if key in self.cache and time.time() - self.last_update_time.get(key, 0) < self.cache_duration:
            return self.cache[key]
        return None

    def set(self, key, value):
        self.cache[key] = value
        self.last_update_time[key] = time.time()

sensor_cache = SensorCache()

class Sensors:
    @classmethod
    def get_external_temp(cls):
        cached_temp = sensor_cache.get('temperature')
        if cached_temp is not None:
            return cached_temp
        # 实际读取温度传感器的代码
        temp = ...
        sensor_cache.set('temperature', temp)
        return temp
6. 总结与展望

通过以上一系列的步骤,我们成功地完成了汽车仪表盘系统的开发,包括倒车摄像头、倒车蜂鸣器、距离传感器的实现,以及系统的美化和优化。整个过程涵盖了硬件连接、代码编写、系统优化等多个方面。

未来,我们可以进一步扩展这个系统。例如,添加更多的传感器,如速度传感器、加速度传感器等,以获取更全面的汽车信息。还可以集成智能算法,实现自动停车、碰撞预警等高级功能。同时,不断优化系统的性能和用户体验,让汽车仪表盘更加智能、实用和美观。

以下是整个开发过程的流程图:

graph TD
    A[开始] --> B[倒车摄像头设置]
    B --> C[倒车蜂鸣器实现]
    C --> D[距离传感器安装]
    D --> E[系统美化]
    E --> F[系统优化]
    F --> G[完成]

通过这个流程图,我们可以清晰地看到整个汽车仪表盘系统开发的关键步骤和顺序。希望这篇文章能帮助你打造出一个属于自己的智能汽车仪表盘。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值