基于传感器触发的 IoT 水果质量检测系统架构实战:IoT-For-Beginners 第 4 课
2026/9/14 3:51:23 网站建设 项目流程

基于传感器触发的 IoT 水果质量检测系统架构实战:IoT-For-Beginners 第 4 课

【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners

导读

本篇文章围绕 IoT-For-Beginners 课程体系「Manufacturing(制造业)」项目中的第 4 课(4-trigger-fruit-detector/README.md)展开,讲解如何把一个单一设备的数据采集应用,扩展为「多设备 + 多云服务 + 执行器响应」的复杂 IoT 应用:通过距离传感器触发图像分类、在边缘运行 AI 模型、将结果上报云端存储,并根据成熟度控制 LED 告警。读完本文,你将掌握参考架构(Things / Insights / Actions)的设计方法、近距传感器的接入与编程(Wio Terminal、Raspberry Pi 与虚拟设备三套方案)、多设备消息结构定义,以及如何用开发套件模拟多个 IoT 设备并平滑演进到生产环境。

复杂 IoT 应用的架构设计

真实的 IoT 应用很少是「一台设备采集数据并上传云端」这么简单,更多时候是多台设备协同工作:通过传感器采集物理世界的数据、基于数据做决策、再通过执行器或可视化与物理世界交互。

一个通用的抽象模型可以概括为三个角色:

  • Things(物):设备从传感器采集数据,可能借助边缘服务(例如图像分类器)解释数据,并将数据发送到 IoT 服务;
  • Insights(洞察):由无服务器应用或对存储数据的分析产生;
  • Actions(行动):可以是下发给设备的命令,也可以是供人类决策的数据可视化。

一个典型的例子:发动机(Thing)上报温度数据,系统评估发动机是否按预期工作(Insight),从而主动调整维护计划的优先级(Action)。

参考 IoT 架构

参考架构(reference architecture)是一种可用于设计新系统的范例架构。当你从零搭建 IoT 系统时,可以遵循它,并将自己的设备与服务代入对应位置:

  • Things:设备采集传感器数据,可结合边缘服务(如图像分类器)解读数据,再发送到 IoT 服务;
  • Insights:来自无服务器应用,或对已存储数据的分析;
  • Actions:下发给设备的命令,或帮助人类决策的数据可视化。

把本课程已覆盖的组件代入参考架构(见上图中的 Azure 版本):

  • Things:你已经编写了从传感器采集数据的设备代码,并用 Custom Vision 在云端和边缘设备上分析图像,数据发送到 IoT Hub;
  • Insights:你使用 Azure Functions 响应发送到 IoT Hub 的消息,并将数据存储到 Azure Storage 供后续分析;
  • Actions:你根据云端决策向设备下发命令来控制执行器,并使用 Azure Maps 进行数据可视化。

这一模式可以按需扩缩——无论增加多少设备与服务,结构都可以保持成立。

数据与安全

在定义系统架构时,需要始终考虑数据与安全:

  • 设备发送和接收哪些数据?
  • 这些数据应如何加密与保护(传输中、存储时)?
  • 设备和云服务的访问应如何控制?

思考你自己拥有的 IoT 设备:其中多少数据属于个人隐私、应当保密?哪些数据根本不应该存储?

设计一个水果质量检测系统

现在把 Things / Insights / Actions 的想法应用到水果质量检测器上,设计一个完整的端到端应用。

业务场景:加工厂里水果在传送带上运送,目前靠人工检查并挑出未成熟的水果。为了降低成本,工厂希望实现自动化——水果到达传送带时被检测到,拍照后用运行在边缘的 AI 模型检查,结果发送到云端存储,如果水果未成熟则给出通知以便移除。

将系统拆解为三层:

| | | | - | - | |Things| 检测水果到达传送带的探测器
拍照并分类水果的相机
运行分类器的边缘设备
通知未成熟水果的设备 | |Insights| 决定是否检查水果成熟度
存储成熟度分类结果
判断是否需要发出未成熟告警 | |Actions| 向设备发送命令拍照并用图像分类器检查
向设备发送命令告警「水果未成熟」 |

原型应用架构

上图是原型应用的参考架构,工作流程如下:

  1. 带近距传感器的 IoT 设备检测到水果到达,向云端发送「已检测到水果」消息;
  2. 云端无服务器应用向另一台设备发送命令,让其拍照并分类图像;
  3. 带相机的 IoT 设备拍照,发送给运行在边缘的图像分类器,结果再发回云端;
  4. 云端无服务器应用存储该信息供后续分析(例如统计未成熟水果占比);若水果未成熟,则向另一台 IoT 设备发送命令,通过 LED 告警工厂工人。

💁 这个完整的 IoT 应用也可以实现为单台设备:把所有启动图像分类、控制 LED 的逻辑内建其中,IoT Hub 仅用于统计检测到的未成熟水果数量并配置设备。本课特意将其拆开,是为了演示大规模 IoT 应用的设计思路。

在原型实现中,所有逻辑都在一台设备上完成;如果使用微控制器,则需要一台独立的边缘设备运行图像分类器。前几课学到的大部分技能在这里都能复用。

从传感器触发水果质量检测

IoT 设备需要一个触发信号来指示「水果可以开始分类了」。一种方案是测量水果在传送带上的位置:通过测量到传感器的距离,判断水果是否到达了正确位置。

近距传感器(proximity sensor)用于测量传感器到物体之间的距离。它们通常发射一束电磁辐射(如激光或红外光),然后检测从物体上反弹回来的辐射。通过计算激光束发出到信号返回的时间差,即可算出到传感器的距离。

💁 你很可能已经在不知不觉中使用过近距传感器:多数智能手机在贴耳通话时会关闭屏幕,防止耳垂误触挂断电话——这正是近距传感器检测到屏幕附近有物体后禁用触摸功能。

任务:用距离传感器触发水果质量检测

按照对应硬件的指南,用近距传感器检测物体:

  • Arduino - Wio Terminal
  • 单板计算机 - Raspberry Pi
  • 单板计算机 - 虚拟设备
硬件:Grove 飞行时间(Time of Flight)距离传感器

三套方案使用的都是 Grove Time of Flight 距离传感器(VL53L0X):

  • 采用激光测距模块检测距离;
  • 测量范围为10mm ~ 2000mm(1cm ~ 2m),该范围内读数比较准确,超过 1000mm 时报告值为8109mm
  • 激光测距仪位于传感器背面(与 Grove 插座相反的一侧);
  • 这是一款I²C 接口传感器。

连接方式

  • Wio Terminal:断开电源后,将 Grove 线缆插入 Wio Terminal 左侧的 Grove 插座(面向屏幕时最靠近电源键、同时支持数字与 I²C 的插座);
  • Raspberry Pi:断电后,将 Grove 线缆插入 Grove Base HAT 上标有I²C的插座(底部一行、与 GPIO 引脚相对的一端、紧邻摄像头排线槽)。
方案一:Raspberry Pi(Python + rpi-vl53l0x)

先安装 Python 包(基于 code-proximity/pi/fruit-quality-detector/distance_sensor.py):

pip install rpi-vl53l0x

在项目fruit-quality-detector中新建distance-sensor.py(用不同 Python 文件分别模拟多个 IoT 设备,再同时运行,是模拟多设备的简便方式),代码如下:

import time from grove.i2c import Bus from rpi_vl53l0x.vl53l0x import VL53L0X distance_sensor = VL53L0X(bus = Bus().bus) distance_sensor.begin() while True: distance_sensor.wait_ready() print(f'Distance = {distance_sensor.get_distance()} mm') time.sleep(1)
  • grove.i2c.Bus提供 Grove I²C 总线访问,VL53L0X是针对传感器核心硬件的 Python 库;
  • wait_ready()等待传感器准备好一个可读的值,get_distance()返回以毫米为单位的距离;
  • 运行方式:python3 distance_sensor.py(注意文件名是distance-sensor.py,不要用app.py)。

预期输出示例:

Distance = 29 mm Distance = 28 mm Distance = 30 mm Distance = 151 mm
方案二:虚拟 IoT 设备(CounterFit)

在虚拟环境下安装 CounterFit 的距离传感器 shim(它模拟了rpi-vl53l0x包):

pip install counterfit-shims-rpi-vl53l0x

在 CounterFit Web 应用中创建传感器:Create sensor面板选择Distance类型,Units保持Millimeter;由于是 I²C 传感器,将地址设置为0x29(物理 VL53L0X 传感器硬编码此地址)。代码(基于 code-proximity/virtual-iot-device/fruit-quality-detector/distance_sensor.py):

from counterfit_connection import CounterFitConnection CounterFitConnection.init('127.0.0.1', 5000) import time from counterfit_shims_rpi_vl53l0x.vl53l0x import VL53L0X distance_sensor = VL53L0X() distance_sensor.begin() while True: distance_sensor.wait_ready() print(f'Distance = {distance_sensor.get_distance()} mm') time.sleep(1)

在 CounterFit 中修改距离值或使用随机值,即可看到读数变化:

Distance = 37 mm Distance = 42 mm Distance = 29 mm
方案三:Wio Terminal(PlatformIO + Seeed VL53L0X 库)

新建 PlatformIO 项目distance-sensor,在 platformio.ini 中添加库依赖:

[env:seeed_wio_terminal] platform = atmelsam board = seeed_wio_terminal framework = arduino lib_deps = seeed-studio/Grove Ranging sensor - VL53L0X @ ^1.1.1

main.cpp完整实现(基于 code-proximity/wio-terminal/distance-sensor/src/main.cpp):

#include <Arduino.h> #include "Seeed_vl53l0x.h" Seeed_vl53l0x VL53L0X; void setup() { Serial.begin(9600); while (!Serial) ; // Wait for Serial to be ready delay(1000); VL53L0X.VL53L0X_common_init(); VL53L0X.VL53L0X_high_accuracy_ranging_init(); } void loop() { VL53L0X_RangingMeasurementData_t RangingMeasurementData; memset(&RangingMeasurementData, 0, sizeof(VL53L0X_RangingMeasurementData_t)); VL53L0X.PerformSingleRangingMeasurement(&RangingMeasurementData); Serial.print("Distance = "); Serial.print(RangingMeasurementData.RangeMilliMeter); Serial.println(" mm"); delay(1000); }

要点:

  • VL53L0X_common_init()初始化传感器,VL53L0X_high_accuracy_ranging_init()启用高精度测距模式;
  • PerformSingleRangingMeasurement()将测量结果填充到VL53L0X_RangingMeasurementData_t结构体中,通过RangeMilliMeter字段读取毫米距离;
  • 编译上传后,用串口监视器即可看到与 Raspberry Pi 方案相同的输出(Distance = 29 mm等)。

💁 三套方案的完整代码分别位于4-manufacturing/lessons/4-trigger-fruit-detector/code-proximity/下的pi/virtual-iot-device/wio-terminal/目录。

水果质量检测器所用的数据

原型检测器包含多个相互通信的组件,消息流向如下:

  • 近距传感器测量到水果的距离并发送到 IoT Hub;
  • 控制相机的命令从 IoT Hub 下发到相机设备;
  • 图像分类结果发送回 IoT Hub;
  • 控制 LED 告警的命令从 IoT Hub 下发到带 LED 的设备。

在开始构建应用之前,最好先定义清楚这些消息的结构——几乎所有有经验的开发者都曾因「实际发送的数据与预期不符」而排查数小时甚至数天的 bug。

例如发送温度信息时,JSON 字段命名如何定义?用temperature还是常见缩写temp

{ "temperature": 20.7 }

对比:

{ "temp": 20.7 }

还要考虑单位:温度是 °C 还是 °F?如果用户用消费级设备并切换了显示单位,必须保证发送到云端的单位保持一致。

回到水果质量检测器:你会如何定义每条消息?在哪里分析数据、决定发送什么数据?例如用近距传感器触发图像分类时——决策在哪里做?是设备判断「水果足够近」然后发送消息让 IoT Hub 触发分类?还是设备只上报距离测量值、由 IoT Hub 决策?

答案取决于具体场景,每个用例都不一样。这正是 IoT 开发者需要理解系统本身、使用方式与所测数据的原因:

  • 如果由 IoT Hub 决策,就需要发送多条距离测量值;
  • 消息过多会增加 IoT Hub 的成本与 IoT 设备的带宽占用(工厂里可能有数百万台设备),还可能拖慢设备本身;
  • 如果在设备端决策,则需要提供配置手段来微调机器参数。

用开发者设备模拟多个 IoT 设备

构建原型时,你的 IoT 开发套件需要扮演多个设备:既要发送遥测,也要响应命令。

在 Raspberry Pi 或虚拟 IoT 硬件上模拟多设备

单板计算机(如 Raspberry Pi)可以同时运行多个应用程序,因此可以通过**创建多个应用(每个「IoT 设备」一个应用)**来模拟多设备。例如,把每个设备实现为独立的 Python 文件,在不同终端会话中分别运行。

💁 注意:某些硬件在被多个同时运行的应用程序访问时可能无法正常工作。

在微控制器上模拟多设备

微控制器模拟多设备要复杂得多:与单板计算机不同,你无法同时运行多个应用,必须把所有设备的逻辑放进同一个应用中。以下建议可让这一过程更顺利:

  • 每个 IoT 设备对应一个或多个类——例如DistanceSensorClassifierCameraLEDController,每个类有自己的setuploop方法,由主setuploop函数调用;
  • 在单一位置处理命令,再按需分发到对应的设备类;
  • 在主loop函数中要考虑每个设备的时序。例如,一个设备类需要每 10 秒处理一次,另一个需要每 1 秒处理一次,那么主loop使用 1 秒延时:每次loop调用触发需要每秒处理的设备代码,并用计数器累计循环次数,计数达到 10 时再处理另一个设备(然后重置计数器)。

迈向生产环境

原型将成为最终生产系统的基础。投入生产时的主要差异包括:

  • 加固组件:使用为工厂噪声、高温、振动与压力而设计的硬件;
  • 内部通信:部分组件直接通信,避免每次都绕道云端,只把需要存储的数据发送到云端。具体方式取决于工厂布局——可以是直接通信,也可以通过网关设备在边缘运行部分 IoT 服务;
  • 配置选项:每个工厂与用例各不相同,硬件需要可配置。例如近距传感器可能需要在不同距离检测不同水果,不应硬编码触发分类的距离,而应能通过云端配置(例如使用设备孪生(device twin));
  • 自动化水果移除:不再用 LED 提示未成熟水果,而是由自动化设备直接将其移除。

✅ 思考:除了以上几点,生产设备与开发套件还有哪些差异?

挑战与课后作业

挑战:回顾之前的项目,它们如何融入上文展示的参考架构?任选一个已完成的项目,设计一个比原项目更复杂、融合多种能力的方案,画出架构图并列出所需的所有设备与服务。例如:一个结合 GPS 与传感器的车辆追踪设备(监控冷藏卡车温度、发动机启停时间、司机身份)——涉及哪些设备、哪些服务、传输哪些数据、有哪些安全与隐私考量?

作业(详见 assignment.md):构建水果质量检测器——综合运用之前所有课程所学:基于近距检测触发图像分类(AI 模型运行在边缘)、将分类结果存入存储、根据水果成熟度控制 LED。评分标准包括:能否配置好 IoT Hub / Azure Functions / Azure Storage 全套云服务;能否在物体进入预设距离时向 IoT Hub 发送消息并通过命令触发相机;能否拍摄图像、用边缘设备分类并上报结果;能否根据分类结果通过命令控制 LED 开关。

🗑 注意:这是本项目的最后一课。完成本课与作业后,请记得清理云服务资源(作业需要用到这些服务,请先完成作业),清理步骤参见 clean-up.md。

延伸学习建议

  • 深入了解 IoT 架构设计,可参考 Azure IoT 参考架构文档(Microsoft Learn 上的 IoT reference architecture);
  • 了解设备孪生,可阅读 IoT Hub 文档中关于理解与使用设备孪生的章节;
  • 了解 OPC-UA——工业自动化中使用的机器对机器通信协议。

结合本课内容,你可以把此前各课中分散的能力——传感器数据采集(Things)、Azure Functions 与 Azure Storage 处理与存储(Insights)、命令下发与 LED 控制(Actions)、Custom Vision 图像分类(云端 + 边缘)——统一编排到一个完整的水果质量检测原型中,并理解它在真实工厂场景下的生产化演进路径。

【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询