IoT-For-Beginners 实战:在虚拟 IoT 硬件上构建夜灯——使用 CounterFit 创建并编程光敏传感器
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
本篇文章是微软开源课程 IoT-For-Beginners 第三课《传感器与执行器》虚拟硬件路线(Virtual device)的核心实操章节:你将在不使用任何实体元器件的情况下,通过 CounterFit 虚拟硬件模拟器 在电脑上创建一个光敏传感器,并用 Python 代码读取环境光强。学完本文,你将掌握 CounterFit 中虚拟模拟传感器(analog sensor)的添加、参数配置、代码驱动与动态调参的完整流程,为后续组合 LED 执行器、组装完整的"夜灯"应用打好基础。
课程背景:夜灯项目与虚拟硬件路线
本教程属于 1-getting-started/lessons/3-sensors-and-actuators 一课。该课的目标是借助"传感器 + 执行器"两个核心概念,搭建一个经典 IoT 应用——夜灯(nightlight):持续读取环境光强,当光线过暗时点亮 LED。
为了降低硬件门槛,本课提供三条硬件路线:Wio Terminal(Arduino 单片机)、Raspberry Pi(树莓派单板机)以及虚拟设备(Virtual device)。本篇文章聚焦虚拟设备路线:不购买任何硬件,而是通过本地运行 CounterFit 应用来模拟传感器与执行器,用与树莓派上几乎一致的 Python 代码驱动它们。此前你需要先完成虚拟环境的搭建与 CounterFit 的连接(详见 虚拟单板机入门,其中包含 Python 虚拟环境配置与pip install CounterFit、counterfit-connection、counterfit-shims-grove三个包的安装步骤)。
虚拟硬件:光敏传感器的原理
夜灯需要一个传感器,即光敏传感器(light sensor)。
在真实物理设备中,光敏传感器的核心通常是光电二极管(photodiode)——一种能把光照转换成电信号的半导体器件。光敏传感器属于模拟传感器(analog sensor):它返回一个表示"相对光照量"的整数值。需要特别强调的是,这个数值不映射到任何标准计量单位(例如勒克斯 lux),它只是一个相对的、量纲化的读数,只对"变化趋势"有意义——光照增强则数值增大,光照减弱则数值减小。
理解这一点对后续编程至关重要:例如在后续夜灯逻辑中,我们只需判断"读数是否小于某个阈值(如 300)"来决定开关灯,而不必关心这个数字对应的物理照度。
💡 更广泛的模拟/数字传感器分类(电位器、按钮、数字温度传感器等)可参考 本课 README 中的 "Sensor types" 章节,其中还介绍了模拟量到数字量转换(ADC)的原理。
在 CounterFit 中添加光敏传感器
要在代码中读取光敏值,第一步是在 CounterFit 应用中创建这个虚拟传感器。
操作步骤
确保 CounterFit 应用正在运行:如果上一部分任务结束后已关闭,请先启动它(在 VS Code 终端中执行
counterfit命令,应用会在浏览器中打开并监听127.0.0.1:5000)。如果此前终端被占用,请新建一个 VS Code 终端,确保其处于激活的 Python 虚拟环境中(提示符前缀出现(.venv))。创建光敏传感器:
- 在左侧Sensors(传感器)面板的Create sensor(创建传感器)区域中,展开Sensor type(传感器类型)下拉框,选择Light;
- 将Units(单位)保持为NoUnits(无单位),这与上文"读数无标准计量单位"的原理一致;
- 确认Pin(引脚)设置为0;
- 点击Add(添加)按钮,即在 Pin 0 上创建了一个光敏传感器。
创建成功后,光敏传感器会出现在下方的传感器列表中,可随时修改其参数:
编程驱动光敏传感器
设备创建完成后,即可在代码中通过 CounterFit 的 Grove shim 库读取它的值。打开你在上一部分创建的nightlight项目中的app.py文件,按以下步骤编写。
第 1 步:导入所需库
在app.py顶部与其他import语句一起加入:
import time from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensorimport time导入 Python 标准库time模块,稍后用于休眠控制(降低设备功耗);from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor从 CounterFit 的 Grove shim Python 库中导入GroveLightSensor类。这个库封装了与 CounterFit 应用中光敏传感器交互的底层代码——你以操作真实 Grove 传感器相同的方式编写代码,实际数据则由 CounterFit 虚拟提供。
📦 除了上述导入,完整的可运行代码还需要连接 CounterFit 的连接库。仓库中的完整示例(code-sensor/virtual-device/nightlight/app.py)顶部还包含:
from counterfit_connection import CounterFitConnection CounterFitConnection.init('127.0.0.1', 5000)这两行初始化与本地 CounterFit 应用的连接(地址
127.0.0.1即本机 localhost,端口5000),它们来自上一节"连接虚拟硬件"任务的已有代码。
第 2 步:创建传感器实例
在文件底部(或在连接初始化之后)添加:
light_sensor = GroveLightSensor(0)这行代码创建GroveLightSensor类的一个实例,并连接到引脚 0——即 CounterFit Grove 引脚上挂载光敏传感器的位置。这里传入的引脚号必须与你在 CounterFit 界面中配置的Pin保持一致(本例为 0)。
第 3 步:编写无限循环轮询光强
在实例声明之后添加一个无限循环,持续读取光敏值并输出到控制台:
while True: light = light_sensor.light print('Light level:', light)light_sensor.light是GroveLightSensor类的light属性,负责从引脚读取模拟量数值;- 读取到的值通过
print打印到控制台,格式为Light level: <值>。
🔧 从源码结构看,
light属性是对"从模拟引脚读取值"这一操作的封装:真实 Grove 光敏传感器通过 Grove HAT 上的 ADC 把电压转换为 0~1023 的整数值,shim 库则负责与 CounterFit 应用通信并返回同样的语义——对应用层代码而言,两者读取方式完全一致。
第 4 步:加入休眠,降低功耗
在while循环末尾加入一秒的短暂休眠:
time.sleep(1)光照水平不需要被持续不间断地检查,time.sleep(1)让每次轮询间隔 1 秒,从而降低设备的功耗(对于真实电池供电设备这一点尤为重要)。
第 5 步:运行程序
在 VS Code 终端中(确保虚拟环境已激活),运行:
python3 app.py控制台会开始输出光强读数,初始状态(尚未在 CounterFit 中设置值)读数通常为 0。
动态调整传感器读数:Value 与 Random 两种模式
程序运行期间,你可以在 CounterFit 应用中实时改变传感器返回的值,观察控制台输出的变化,这相当于在真实硬件旁调节环境光。CounterFit 提供两种方式:
- 固定值模式:在光敏传感器的Value(值)输入框中输入一个数字,点击Set(设置)按钮。此后每次读取,传感器都会返回这个固定数字。
- 随机值模式:勾选Random(随机)复选框,填写Min(最小值)与Max(最大值),再点击Set。此后每次读取,传感器都会返回
Min与Max之间的一个随机整数——非常适合模拟不断变化的光照环境,也便于后续测试夜灯逻辑在阈值附近翻转的行为。
改变Value或Random设置后,新数值会立即反映在控制台输出中。典型输出如下:
(.venv) ➜ GroveTest python3 app.py Light level: 143 Light level: 244 Light level: 246 Light level: 253💁 完整代码位于仓库 code-sensor/virtual-device 目录。
从仓库源码验证完整实现
仓库中提供了本节的完整可运行代码,位于 code-sensor/virtual-device/nightlight/app.py,内容如下:
import time from counterfit_connection import CounterFitConnection from counterfit_shims_grove.grove_light_sensor_v1_2 import GroveLightSensor CounterFitConnection.init('127.0.0.1', 5000) light_sensor = GroveLightSensor(0) while True: light = light_sensor.light print('Light level:', light) time.sleep(1)可以看到,代码与本文逐步讲解的片段完全对应,额外增加了与 CounterFit 建立连接的两行。它与你随后要实现的夜灯版本(code-actuator/virtual-device/nightlight/app.py)共用同一个GroveLightSensor(0)与轮询骨架——下一节只需在此基础上叠加 LED 执行器即可。
下一步:组合 LED 构成完整夜灯
至此,夜灯的"眼睛"(光敏传感器)已经就绪。接下来只需添加"手"——一个 LED 执行器,并用阈值判断点亮或熄灭它:
if light < 300: led.on() else: led.off()- LED 是数字执行器(digital actuator),只有开(发送数字信号 1)与关(发送 0)两种状态;
- 阈值 300 对应"光线过暗"的判定条件:光强读数低于 300 时点亮 LED,否则熄灭。
这一部分(在 CounterFit 中创建引脚 5 上的 LED、驱动夜灯逻辑、以及在浏览器中观察 LED 随光强明灭)的完整步骤,请继续阅读 虚拟设备——执行器篇:构建夜灯。对照两份文档,你将完整走通"传感器采集 → 逻辑判断 → 执行器响应"这条 IoT 设备端核心链路,全程无需任何物理硬件。
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考