IoT-For-Beginners 实战:用接近传感器触发水果质量检测——复杂 IoT 应用架构设计与原型实现
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
导读
本篇技术指南以 IoT-For-Beginners 课程项目 "制造(Manufacturing)" 模块的最后一课为核心,讲解如何从"单个设备采集数据"升级为"多设备协作的复杂 IoT 应用":围绕一个工厂水果质量检测系统,梳理Things(事物)→ Insights(洞察)→ Actions(动作)的参考架构,并动手用 VL53L0X 激光测距(Time of Flight)接近传感器作为触发源,驱动摄像头拍照、边缘端 AI 分类、云端存储与 LED 告警的完整链路。读完本文,你将掌握复杂 IoT 应用的分层架构设计方法、接近传感器的三种开发平台接入方式(Wio Terminal / Raspberry Pi / 虚拟设备),以及消息结构定义、多设备模拟与生产化迁移的关键权衡。
一、复杂 IoT 应用架构设计:Things、Insights 与 Actions
IoT 应用很少只是一个"采集数据并上传云端"的孤立设备。更多时候,它是多个设备协同工作:用传感器从物理世界采集数据、基于这些数据做出决策,再通过执行器(actuator)或可视化反过来影响物理世界。
官方课程用一个通用模型来概括这种应用(见 课程原文):
- Things(事物):各种设备从传感器采集不同数据,可能还会与边缘服务(例如图像分类器)交互来解读数据,随后把数据发送给 IoT 服务;
- Insights(洞察):来自无服务器应用(serverless),或对已存储数据执行的统计分析;
- Actions(动作):下发给设备的命令,或让人类做出决策的数据可视化。
课程给出的经典例子是发动机:发动机(Thing)发送温度数据;这些数据被用来评估发动机是否按预期工作(Insight);洞察结果被用来主动调整发动机的维护优先级(Action)。这个模式可以根据需要任意伸缩——增加更多设备和更多服务即可扩展规模。
参考 IoT 架构
上图就是本课程给出的参考架构(reference architecture):一种在设计新系统时可以套用的模板架构。当你构建新 IoT 系统时,可以按此模板替换成自己的设备和云服务。对照本课程前序内容,各组件在 Azure 生态中的落点如下:
- Things:为传感器采集数据编写设备端代码;用 Custom Vision 在云端和边缘设备上分析图像;数据发送到 IoT Hub;
- Insights:用 Azure Functions 响应发往 IoT Hub 的消息,并把数据存入 Azure Storage 供后续分析;
- Actions:基于云端决策向设备发送命令来控制执行器,并用 Azure Maps 可视化数据。
数据与安全贯穿始终
在定义系统架构时,必须持续考虑数据与安全三个问题:
- 设备发送和接收哪些数据?
- 这些数据应如何加密与保护?
- 设备和云服务的访问权限应如何控制?
这些问题的答案直接影响消息格式、传输协议(如 第 4 课网络协议 涉及的 MQTT/AMQP)、设备身份认证方式以及云端存储策略,属于架构设计阶段就要敲定的约束,而不是开发收尾时才补的功课。
二、设计水果质量检测系统:把架构落到工厂场景
把 Things/Insights/Actions 应用到水果质量检测器上,就得到一个端到端的大系统。假设场景:加工厂里水果在传送带上运送,目前靠人工目检并挑出未熟水果;为了降低成本,工厂主希望自动化。
系统要求是:水果到达传送带时被检测到 → 拍照 → 边缘端 AI 模型检查 → 结果发到云端存储 → 若未熟则发出通知。按课程给出的表,系统职责划分如下:
| 角色 | 内容 | | - | - | |Things| 检测传送带上水果到达的探测器
拍照并分类水果的摄像头
运行分类器的边缘设备
通知未熟水果的设备 | |Insights| 决定是否检查水果成熟度
存储成熟度分类结果
判断是否需要发出未熟水果告警 | |Actions| 向设备发送命令,拍照并用图像分类器检查
向设备发送命令,告警"水果未熟" |
原型化你的应用
原型参考架构包含四个相互协作的环节:
- 带接近传感器的 IoT 设备检测到水果到达,向云端发消息;
- 云端的无服务器应用向另一设备发送命令,让它拍照并分类图像;
- 带摄像头的 IoT 设备拍照,把图片交给边缘端图像分类器,结果发回云端;
- 云端的无服务器应用存储这些信息供后续分析(统计未熟水果比例);若水果未熟,则向另一 IoT 设备发命令,用LED通知工厂工人。
需要说明的是:这套完整应用理论上可以用单个设备实现(把启动图像分类、控制 LED 的逻辑全部内建,只用 IoT Hub 记录未熟水果数量并配置设备)。本课之所以拆分成多设备,是为了演示大规模 IoT 应用的协作概念。原型阶段,你要把所有这些逻辑实现在一个设备上;若使用微控制器,则需要用单独的边缘设备来跑图像分类器。
三、用传感器触发质量检测:VL53L0X 接近传感器实战
IoT 设备需要某种触发器来指示"水果已就位、可以分类了"。一个自然方案是:通过测量与传感器的距离,判断水果是否到达传送带上的正确位置。
接近传感器通过发射电磁辐射束(激光或红外光),再检测被物体反射回来的辐射,利用"发射到返回"的时间差计算距离。你可能早就用过它:大多数智能手机在通话时贴近耳朵会自动熄灭屏幕,防止误触挂断电话,靠的正是接近传感器。
硬件: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 线插入传感器插座;
- Pi断电状态下,把另一端接到 Grove Base Hat 上标有I²C的插座(底部一排、与 GPIO 引脚相对的一端、靠近摄像头排线槽);
- 上电启动。
代码实现一:Wio Terminal(PlatformIO / Arduino)
仓库中完整的可运行工程位于 code-proximity/wio-terminal,核心要点如下。
新建名为distance-sensor的 PlatformIO 工程,在 platformio.ini 中加入 Seeed 官方 VL53L0X 库依赖:
[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 中声明传感器实例并初始化:
#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(); }VL53L0X_common_init()完成 I²C 通信初始化,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); }先清零数据结构,再调用PerformSingleRangingMeasurement填充测量值,RangeMilliMeter字段即距离(毫米)。烧录后打开串口监视器,把物体靠近传感器即可看到读数变化:
Distance = 29 mm Distance = 28 mm Distance = 30 mm Distance = 151 mm代码实现二:Raspberry Pi(Python)
完整代码见 code-proximity/pi/fruit-quality-detector/distance_sensor.py。先在fruit-quality-detector工程中安装依赖:
pip install rpi-vl53l0x然后新建distance-sensor.py(课程特意强调:多个模拟 IoT 设备各自放在独立的 Python 文件中,可同时运行):
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)Bus().bus取自 Grove 的 I²C 总线库;wait_ready()阻塞等待一次测量就绪,get_distance()返回毫米级距离。运行python3 distance_sensor.py后控制台输出类似:
pi@raspberrypi:~/fruit-quality-detector $ python3 distance_sensor.py Distance = 29 mm Distance = 28 mm Distance = 30 mm Distance = 151 mm代码实现三:虚拟 IoT 设备(CounterFit 仿真)
无实体硬件时,可以用 CounterFit 在桌面端模拟接近传感器,代码见 code-proximity/virtual-iot-device/fruit-quality-detector/distance_sensor.py。
在已激活虚拟环境的终端安装 shim 包(该 shim 通过模拟
rpi-vl53l0x的 API 与 CounterFit 通信):pip install counterfit-shims-rpi-vl53l0x在 CounterFit Web 应用中创建传感器:Sensors面板 →Create sensor框 → Sensor type 选Distance、Units 保持Millimeter;由于 VL53L0X 是 I²C 传感器,真实硬件的地址硬编码为
0x29,仿真时也要把地址设为0x29,然后点Add。编写并运行代码:
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)运行
python distance-sensor.py,然后在 CounterFit 中改动传感器数值(或使用随机值)观察输出:(.venv) ➜ fruit-quality-detector python distance-sensor.py Distance = 37 mm Distance = 42 mm Distance = 29 mm
四、水果质量检测器的数据结构设计
原型检测器中有多个组件互相通信,消息流向如下:
- 接近传感器测量到水果的距离,发送给 IoT Hub;
- 控制摄像头的命令由 IoT Hub 下发到摄像头设备;
- 图像分类结果发送回 IoT Hub;
- 控制 LED 告警的命令由 IoT Hub 下发到带 LED 的设备。
在开始开发前就定义好消息结构是课程强调的工程实践——几乎所有有经验的开发者都曾因为"实际发送的数据"与"期望收到的数据"不一致而排查数小时乃至数周。举例来说,发送温度信息时 JSON 怎么定义?
{ "temperature": 20.7 }还是用常见缩写:
{ "temp": 20.7 }除了字段名,还要考虑单位:是 °C 还是 °F?如果消费者设备测量温度且用户切换了显示单位,你必须保证上传到云端的单位始终保持一致。
决策放在设备端还是云端?
以"接近传感器触发图像分类"为例:IoT 设备测到了距离,但决策在哪里做?是设备判断"水果足够近了"然后通知 IoT Hub 触发分类?还是设备只上报测距值、由 IoT Hub 决定?课程的结论是:视情况而定(it depends),每个用例都不同,这正是 IoT 开发者需要理解系统使用方式与数据特征的原因:
- 若决策由 IoT Hub 做,设备需要发送多次距离测量;
- 消息过多会增加 IoT Hub 成本与设备带宽开销(工厂里可能有数百万台设备),还会拖慢设备本身;
- 若决策在设备端做,则需要提供设备配置途径来微调触发阈值。
五、用开发设备模拟多个 IoT 设备
原型需要你的开发套件"一人分饰多角":同时发送遥测、响应命令。
单板计算机(Raspberry Pi / 虚拟硬件)
单板计算机能同时运行多个应用,因此可以创建多个应用、每个代表一个 IoT 设备。最简单的方式:每个设备一个 Python 文件,在不同终端会话中同时运行。注意:部分硬件在被多个应用同时访问时无法正常工作。
微控制器(Wio Terminal)
微控制器无法同时运行多个应用,必须把所有 IoT 设备的逻辑整合进单个应用。课程给出三条降低复杂度的建议:
- 按设备建类:例如
DistanceSensor、ClassifierCamera、LEDController,每类自带setup和loop方法,由主setup/loop调用; - 集中处理命令:命令统一在一个地方接收,再按需分发给对应设备类;
- 在主
loop中统筹时序:例如一个设备类每 10 秒处理一次、另一个每 1 秒处理一次,那么主loop用 1 秒延时;每次loop调用都处理"每秒设备"的代码,同时用计数器累计循环次数,计数到 10 时处理"每 10 秒设备"并将计数器清零。
这一节的设计思想与本课原型作业直接对应(详见 assignment.md)。
六、从原型走向生产
原型是最终生产系统的基础,两者之间有以下关键差异:
- 加固组件(Ruggedized components):生产环境使用能承受工厂噪声、高温、振动与冲击的工业级硬件;
- 内部通信(Internal communications):部分组件直接互相通信,避免每次都绕道云端,只把需要存储的数据发到云端。实现方式取决于工厂布局——既可以是组件间直连,也可以是用网关设备在边缘运行部分 IoT 服务(这正是 第 3 课"边缘运行水果检测器" 的延伸场景);
- 可配置项(Configuration options):每家工厂、每个用例都不同,硬件必须可配置。例如接近传感器可能需要在不同距离识别不同水果,触发分类的距离阈值不应硬编码,而应能通过云端配置——例如使用Device Twin(设备孪生)机制下发;
- 自动化剔除(Automated fruit removal):生产线上用自动化装置直接剔除未熟水果,而不是靠 LED 提示工人。
七、课程挑战与作业
挑战:回顾此前完成的项目,思考它们如何映射到本文的参考架构。选一个项目,设计一个融合多种能力的更复杂方案并画出架构,标注需要的全部设备、服务、传输数据及安全隐私考量。课程给出的参考例子是:一个把 GPS 与传感器结合的车辆跟踪设备,监测冷藏车温度、发动机启停时间与司机身份——思考涉及哪些设备、哪些服务、传输哪些数据、有哪些安全隐私问题。
课后作业(完整要求与评分细则见 assignment.md):搭建水果质量检测器原型——用接近传感器触发图像分类(AI 模型在边缘运行)、把分类结果存入存储、依据水果成熟度控制 LED。评分标准涵盖四个维度:
| 标准 | 优秀 | 合格 | 待改进 |
|---|---|---|---|
| 配置所有服务 | 成功配置 IoT Hub、Azure Functions 应用与 Azure 存储 | 只配好 IoT Hub,Functions 或存储缺一 | 未能配置任何 IoT 云服务 |
| 监测接近度,物体进入预设距离后上报 IoT Hub,并通过命令触发摄像头 | 能测距、近距离时上报 IoT Hub,且命令成功触发摄像头 | 能测距并上报,但命令未能送达摄像头 | 无法测距上报,或无法触发命令 |
| 拍摄图像、分类并把结果发到 IoT Hub | 能拍照、用边缘设备分类并上报结果 | 能分类但未用边缘设备,或结果未能上报 | 完全无法分类 |
| 依据分类结果通过命令开/关 LED | 水果未熟时能通过命令点亮 LED | 命令到达设备但 LED 未受控 | 无法发送控制 LED 的命令 |
🗑 这是本项目的最后一课。完成本课与作业后,别忘了清理你的云服务——请先完成作业(作业需要这些服务),再参照 clean-up.md 中的清理指引释放资源。
小结
本课把"多设备协作的复杂 IoT 应用"从概念落到可运行的原型:先以Things→Insights→Actions参考架构拆解水果质量检测系统,再用 VL53L0X 激光接近传感器作为触发器打通"检测到货 → 云端调度 → 拍照分类 → 结果存储 → LED 告警"的完整消息链路,并对比了 Wio Terminal(Arduino/PlatformIO)、Raspberry Pi(Python)与 CounterFit 虚拟设备三种实现路径。无论最终跑在哪种硬件上,先定义消息契约、再权衡设备端/云端决策边界、最后按生产环境要求设计可配置性,都是把 IoT 原型做扎实的核心方法论。
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考