从传感器触发的水果质量检测器原型构建:IoT-For-Beginners 制造项目收官实战
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
本篇文章以 4-manufacturing/lessons/4-trigger-fruit-detector/assignment.md 中的收官作业为核心,系统讲解如何在 IoT-For-Beginners 制造项目(Manufacturing)中,把前几课学到的距离传感、边缘 AI 图像分类、云服务与执行器控制整合为一台完整的水果质量检测器原型。读完本文,你将掌握"传感器触发 → 云端编排 → 边缘分类 → 结果存储 → LED 报警"这一端到端 IoT 应用的架构设计与代码拼装方法。
作业目标:把整门课的能力拼成一个原型
第 4 课《从传感器触发水果质量检测》是整个制造项目的最后一课。课程正文 README.md 明确指出,完成本课与作业后记得清理云服务资源,但也提醒必须先完成作业再清理,因为作业需要用到这些服务(清理方法见 clean-up.md)。
作业原文(assignment.md)的任务定义非常凝练:
构建水果质量检测器原型——利用运行在边缘的 AI 模型,基于近距离(proximity)触发图像分类;将分类结果存储到存储服务;并根据水果的成熟度控制一盏 LED。
关键提示是:"你应该能够使用前几课中编写的代码把它拼装起来"。因此这道作业本质上是前四课能力的综合验收:
- 第 1 课训练 Custom Vision 水果检测模型(1-train-fruit-detector);
- 第 2 课在设备上拍照并调用云端的分类服务(2-check-fruit-from-device);
- 第 3 课把分类器部署到边缘设备上离线运行(3-run-fruit-detector-edge);
- 第 4 课用距离传感器触发整个检测流程(本课的三个硬件指南)。
作业只给出"指令 + 评分标准"两层内容,真正的技术细节分散在课程正文、硬件指南与code-proximity源码目录中,本文会把这些素材全部串起来。
先理解架构:Things、Insights、Actions
要拼好这个原型,首先要理解课程正文提出的 IoT 参考架构。IoT 应用可以描述为things(设备)采集数据并产生insights(洞察),洞察再驱动actions(动作)来改进业务流程。
- Things(物):从传感器采集数据的设备,可能借助边缘服务(如图像分类器)解读数据,数据最终发送到 IoT 服务;
- Insights(洞察):来自无服务器应用(如 Azure Functions),或对存储数据的分析;
- Actions(动作):发送给设备的命令,或允许人类决策的数据可视化。
课程给出了通用参考架构图 iot-reference-architecture.png 以及结合本课程已学服务的 Azure 版 iot-reference-architecture-azure.png。对应到本作业:
- Things:你已经写过设备代码采集传感器数据,并用 Custom Vision 在云端和边缘设备上分析图像,数据发送到 IoT Hub;
- Insights:使用 Azure Functions 响应发送到 IoT Hub 的消息,并把数据存入 Azure Storage 供后续分析;
- Actions:基于云端决策向设备发送命令控制执行器,并使用 Azure Maps 可视化数据。
水果质量检测系统的端到端设计
课程给出一个真实场景:加工厂中水果在传送带上运输,目前由工人手工检查并剔除未成熟的水果。你要构建的自动化系统需要:检测到水果到达 → 拍照并用边缘 AI 模型检查 → 结果发送到云端存储 → 若水果未成熟则发出通知。
系统各环节划分如下:
| 环节 | 组成 |
|---|---|
| Things | 检测传送带上水果到达的传感器;拍摄并分类水果的摄像头;运行分类器的边缘设备;通知未成熟水果的设备 |
| Insights | 决定是否需要检查水果成熟度;存储成熟度分类结果;判断是否需要发出未成熟警报 |
| Actions | 向设备发送命令拍照并用图像分类器检查;向设备发送命令提示水果未成熟 |
完整的原型参考架构见 iot-reference-architecture-fruit-quality.png,工作流程为:
- 带接近传感器的 IoT 设备检测到水果到达,向云端发送"检测到水果"的消息;
- 云端的无服务器应用向另一台设备发送命令,让其拍照并分类图像;
- 带摄像头的 IoT 设备拍照,把图像发送给运行在边缘的图像分类器,结果回传云端;
- 云端的无服务器应用存储信息(供后续分析未成熟水果占比);若水果未成熟,则向另一台 IoT 设备发送命令,通过 LED 提醒工厂工人。
课程也指出:整个应用其实可以实现在单台设备上,用 IoT Hub 仅跟踪检测到的未成熟水果数量并配置设备;本课将其拆开是为了演示大规模 IoT 应用的架构思路。在原型阶段,你将在单台设备上实现所有这些逻辑;如果使用微控制器,则需要一台独立的边缘设备运行图像分类器。
触发器:用 VL53L0X 飞行时间距离传感器检测水果到达
水果到达传送带检测位置时,需要某种"触发信号"告诉系统开始分类。最直接的方式是测量水果与传感器之间的距离。
接近传感器通常发射一束电磁辐射(如激光或红外光),然后检测物体反射回来的辐射。从激光发出到信号反弹回来之间的时间,可用于计算到传感器的距离。你可能不知不觉使用过它——大多数智能手机在贴近耳朵时会关闭屏幕,防止误触挂断电话,靠的正是接近传感器。
硬件选型:Grove 飞行时间距离传感器
课程三个硬件指南(wio-terminal-proximity.md、pi-proximity.md、virtual-device-proximity.md)统一使用Grove Time of Flight(VL53L0X)距离传感器:
- 基于激光测距模块检测距离;
- 测量范围10mm ~ 2000mm(1cm ~ 2m),该范围内报告值相当准确;
- 距离超过 1000mm 时报告值固定为8109mm(越界哨兵值);
- 是I²C 传感器,地址固定为
0x29; - 激光测距头在传感器背面(与 Grove 插座相对的一侧),测量时务必使用正确的一面。
树莓派:Python 实现
树莓派版先安装rpi-vl53l0xPip 包(用于操作 VL53L0X 传感器):
pip install rpi-vl53l0x然后在fruit-quality-detector项目中新建distance-sensor.py,完整代码如下(仓库源码见 code-proximity/pi/fruit-quality-detector/distance_sensor.py):
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)要点说明:
from grove.i2c import Bus导入 Grove I²C 总线库,from rpi_vl53l0x.vl53l0x import VL53L0X导入核心传感器库;VL53L0X(bus = Bus().bus)在 Grove I²C 总线上声明传感器实例,begin()启动传感器;- 无限循环中
wait_ready()等待测量值就绪,get_distance()返回以毫米为单位的距离; - 运行方式:
python3 distance_sensor.py(注意文件名是distance-sensor.py,不是app.py)。运行输出示例:
pi@raspberrypi:~/fruit-quality-detector $ python3 distance_sensor.py Distance = 29 mm Distance = 28 mm Distance = 30 mm Distance = 151 mmWio Terminal:Arduino/PlatformIO 实现
微控制器版在 PlatformIO 中新建名为distance-sensor的项目,在platformio.ini中添加传感器库依赖(配置见 code-proximity/wio-terminal/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.1main.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); }要点说明:
setup中先初始化串口,再调用VL53L0X_common_init()和VL53L0X_high_accuracy_ranging_init()完成传感器初始化(高精度测距模式);loop中先memset清零VL53L0X_RangingMeasurementData_t数据结构,再调用PerformSingleRangingMeasurement(&RangingMeasurementData)填充测量结果;- 距离值保存在
RangingMeasurementData.RangeMilliMeter,通过串口监视器输出,每轮delay(1000)即每秒测量一次。
虚拟设备:CounterFit 模拟
无实体硬件的读者可以在 CounterFit 中模拟距离传感器:
pip install counterfit-shims-rpi-vl53l0x该包是rpi-vl53l0x的 shim,模拟 VL53L0X 传感器与 Python 的交互。在 CounterFit 网页应用中创建传感器时:Sensor type选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 中的数值(或启用随机值)即可看到输出变化:
(.venv) ➜ fruit-quality-detector python distance-sensor.py Distance = 37 mm Distance = 42 mm Distance = 29 mm消息设计:在动手前先定义好 JSON 结构
原型中多个组件互相通信,课程用消息流图 fruit-quality-detector-message-flow.png 概括了四类消息:
- 接近传感器把到水果的距离发送到 IoT Hub;
- 控制摄像头的命令从 IoT Hub 下发到摄像头设备;
- 图像分类结果发送回 IoT Hub;
- 控制 LED 报警(水果未成熟)的命令从 IoT Hub 下发到带 LED 的设备。
课程强烈建议在构建应用之前先定义好消息结构——几乎所有有经验的开发者都曾因"发送的数据与预期不符"而耗费数小时甚至数天排查 bug。以温度数据为例,字段命名就存在分歧:
{ "temperature": 20.7 }对比:
{ "temp": 20.7 }还需考虑单位:温度是 °C 还是 °F?如果消费级设备允许用户切换显示单位,必须确保发送到云端的单位保持一致(课程提示可调研:单位问题如何导致造价 1.25 亿美元的 Mars Climate Orbiter 坠毁)。
对于水果质量检测器,每个消息都要思考:数据在哪里分析?决策在哪里做出?例如触发图像分类:设备自己判断"水果足够近"再发消息让 IoT Hub 触发分类,还是发送原始距离测量值让 IoT Hub 决定?课程给出的答案是"看情况而定(it depends)":
- 如果决策在 IoT Hub 做,需要发送多次距离测量值;
- 消息太多会增加 IoT Hub 成本和 IoT 设备带宽(工厂里可能有数百万设备),也会拖慢设备;
- 如果决策在设备端做,则需要提供设备配置机制以便现场调优(这正是第 6 课设备孪生/云端配置的用武之地)。
在单台设备上模拟多个 IoT 设备
原型的服务端流程是"多设备协作",但实际构建时只在手头的一台开发板上实现。课程给出了两种模拟策略:
树莓派 / 虚拟设备(单板计算机):可以同时运行多个应用程序,因此用多个应用模拟多个 IoT 设备——例如把每个"设备"实现为独立的 Python 文件,在不同终端会话中同时运行。这也是接近传感器指南中建议"每个设备一个 Python 文件"的原因。注意:某些硬件被多个应用同时访问时无法正常工作。
Wio Terminal(微控制器):无法同时运行多个应用,必须把多个 IoT 设备的逻辑全部塞进单个应用中。课程建议:
- 为每台 IoT 设备创建一个或多个类(如
DistanceSensor、ClassifierCamera、LEDController),每个类有自己的setup和loop方法,由主setup和loop调用; - 在单个位置统一处理命令,再按需分发到对应的设备类;
- 在主
loop中仔细规划各设备的时间片:例如某个设备每 10 秒处理一次、另一个每 1 秒处理一次,则主loop使用 1 秒延时,每次loop触发需要每秒处理的设备代码,同时用计数器累计循环次数,计数到 10 时再处理另一个设备并重置计数器。
如何拼装:复用前几课代码的完整清单
作业要求"使用前几课写的代码拼装",结合课程正文与评分标准,完整的拼装清单如下:
| 组件 | 来源 | 在原型中的作用 |
|---|---|---|
| 距离传感器代码 | 本课code-proximity(上文三种实现) | 检测水果接近,距离低于预定义阈值时发送消息到 IoT Hub |
| IoT Hub 遥测发送 | 制造项目第 2 课 | 把距离/检测事件作为遥测上报 |
| 云端命令(C2D) | 制造项目第 2/4 课 | Azure Functions 收到事件后向相机设备发送"拍照"命令;分类完成后向 LED 设备发送控制命令 |
| Azure Functions 无服务器应用 | 制造项目第 2 课 / 第 4 课 | 编排:响应 IoT Hub 消息、触发拍照、存储结果、决定是否报警 |
| Azure Storage | 制造项目第 2 课 | 持久化分类结果,供后续分析未成熟水果占比 |
| 摄像头 + Custom Vision 分类 | 第 1/2 课训练模型,第 3 课部署到边缘 | 拍照并调用边缘分类器判断成熟度,结果发回 IoT Hub |
| LED 控制 | 入门课程(第 3 课传感器与执行器) | 收到云端命令后点亮 LED 提醒未成熟水果 |
评分标准(rubric)中的"卓越"档要求同时满足:
- 配置所有服务:成功搭建 IoT Hub、Azure Functions 应用和 Azure Storage;
- 监控接近度并触发相机:能测量距离,物体足够近时向 IoT Hub 发消息,并通过命令触发相机;
- 拍照、分类并发送结果:能拍照、用边缘设备分类、把结果发回 IoT Hub;
- 根据分类结果控制 LED:水果未成熟时能通过命令点亮 LED。
"合格"档允许在边缘分类、命令下发或 LED 控制中缺一项;"需改进"档则对应无法搭建任何联网 IoT 服务、无法测距发消息/触发命令、无法分类图像或无法下发 LED 命令。
从原型到生产:原型之外要考虑的事
课程提醒,这个原型只是最终生产系统的基础。投入生产时的主要差异包括:
- 加固组件:使用能承受工厂噪声、高温、振动和压力的工业级硬件;
- 内部通信:部分组件直接通信、避免绕道云端,仅把需要存储的数据发给云端——具体方式取决于工厂布局,可以直接通信,也可以借助网关设备把部分 IoT 服务运行在边缘;
- 配置选项:每个工厂和应用场景不同,硬件需要可配置。例如接近传感器需要在不同距离检测不同水果,与其把触发分类的距离硬编码,不如通过云端配置(如设备孪生 device twin)下发;
- 自动化剔除:不再用 LED 提醒,而是用自动化设备直接移除未成熟水果。
结语与进一步实践
本作业是 IoT-For-Beginners 制造项目的收官之作:你已掌握"多传感器采集 → 云端无服务器编排 → 边缘 AI 分类 → 存储分析 → 执行器响应"的完整 IoT 应用架构,并用前四课积累的代码在单台设备上模拟出多设备协作的水果质量检测原型。想继续挑战,可以回看课程末尾的 Challenge:把此前各项目(如车辆追踪、温控器)映射到 Things/Insights/Actions 参考架构中,设计一个融合 GPS、温度传感、发动机状态和驾驶员身份识别的更复杂方案,并画出包含所有设备、服务、数据流与安全隐私考量的架构图。完成作业后,请按 clean-up.md 清理云端资源。
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考