IoT-For-Beginners 第 3 课:用传感器与执行器构建一个会感知光线的智能夜灯
IoT-For-Beginners 第 3 课用传感器与执行器构建一个会感知光线的智能夜灯【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners本篇技术指南以IoT-For-Beginners课程第 3 课1-getting-started/lessons/3-sensors-and-actuators/README.md为骨架系统讲解 IoT 设备的两类核心外设——传感器Sensors与执行器Actuators从概念原理模拟/数字信号、ADC/DAC、PWM 脉宽调制到 Raspberry Pi、Wio Terminal、虚拟设备三种硬件平台的完整接线与编程实战最终亲手搭建一个光线不足自动点亮 LED的智能夜灯。读完你将掌握传感器/执行器的分类判断、GPIO 引脚读写方法以及同一套逻辑在 Python 与 CPlatformIO/Arduino两套技术栈中的落地写法。传感器感知物理世界的输入设备传感器是硬件设备用来感知物理世界——即测量周围的一个或多个属性并把信息发送给 IoT 设备。从空气温度这样的自然属性到运动这样的物理交互可测量的对象极其庞杂因此传感器种类繁多。课程中列举了几类常见传感器温度传感器测量空气温度或其所浸入介质的温度。面向爱好者和开发者的产品常把温度、气压、湿度集成到同一个传感器中按钮感知何时被按下光传感器检测光照强度可针对特定颜色、紫外线、红外线或普通可见光摄像头通过拍照或视频流感知世界的视觉表征加速度计在多个方向上感知运动麦克风感知声音可以是总体声级也可以是定向声音。所有传感器有一个共同点它们把感知到的物理量转换为 IoT 设备可以解释的电信号。至于这个电信号如何被解释则取决于传感器本身以及它与 IoT 设备通信所用的协议。传感器类型模拟与数字传感器分为**模拟Analog与数字Digital**两大类区分关键在于输出信号的形态。模拟传感器电压即数据最基础的一类传感器是模拟传感器。IoT 设备向传感器提供电压传感器内部元件调整该电压然后设备测量返回的电压值作为传感值。电压是衡量推动电从一处流向另一处有多大的物理量——例如一节标准 AA 电池是 1.5VV 是伏特的符号它能把 1.5V 的推力从正极送到负极不同硬件需要不同电压比如 LED 在 2~3V 即可点亮而 100W 白炽灯泡需要 240V。一个典型例子是电位器Potentiometer——一个可在两个位置之间旋转的旋钮传感器测量旋转量。假设设备向电位器发送 5V当旋钮在完全关闭位置0时输出 0V当旋钮在完全打开位置11时输出 5V中间位置则输出介于两者之间的电压如下图中点输出约 3.8V。传感器输出的电压被 IoT 设备读取后设备即可据此响应。这个电压可能是任意值也可能映射到标准单位——例如基于热敏电阻thermistor的模拟温度传感器其电阻随温度变化输出电先后可在代码中换算成开尔文K进而转为 °C 或 °F。需要注意课程明确提示不要测试传感器返回电压高于发送电压例如来自外部电源的情况这属于硬件安全边界。模数转换ADC数字世界如何读懂模拟值IoT 设备是数字设备——只能处理 0 和 1无法直接处理模拟值。因此模拟传感器的值需要先转换为数字信号。许多 IoT 设备自带模数转换器ADCAnalog-to-Digital Converter传感器也可以通过连接板上的 ADC 工作。例如在 Seeed Grove 生态中Raspberry Pi 上的模拟传感器接入一个帽子hat的特定端口hat 通过 GPIO 引脚架在 Pi 上该 hat 内置 ADC把电压转换为数字信号后通过 GPIO 引脚送出。课程给出了一个非常具体的换算例子假设一个模拟光传感器接在 3.3V 的 IoT 设备上返回 1V。这个 1V 在数字世界没有意义需要按设备和传感器的量程换算——Seeed Grove 光传感器输出 0~1023 的数值对于运行在 3.3V 下的该传感器1V 输出对应数值300。IoT 设备无法直接处理模拟值 300因此 Grove hat 会把它转换为 300 的二进制表示0000000100101100再交给设备处理。从编程视角看这一切通常由传感器附带的库完成开发者无需亲自处理换算Grove 光传感器在 Python 里调用light属性、在 Arduino 里调用analogRead都能直接得到 300 这样的整数值。数字传感器直接输出 0 和 1数字传感器同样通过电压变化感知世界区别在于它们输出数字信号——要么只测量两种状态要么内置 ADC 完成转换。数字传感器正变得越来越普遍正是为了免去在连接板或设备上额外使用 ADC 的麻烦。最简单的数字传感器是按钮/开关只有开、关两种状态的传感器。IoT 设备上的 GPIO 引脚可以直接把信号读成 0 或 1如果返回电压与发送电压相同则读为 1否则读为 0无需转换。电压永远不会绝对精确传感器元件总有电阻所以存在容差——例如 Raspberry Pi 的 GPIO 工作在 3.3V把高于 1.8V 的返回信号读为 1低于 1.8V 读为 0。按钮的两种情形一目了然3.3V 进入按钮按钮断开输出 0V → 读为 03.3V 进入按钮按钮闭合输出 3.3V → 读为 1。更高级的数字传感器会先读取模拟值再用板载 ADC转换为数字信号。例如数字温度传感器与模拟传感器一样使用热电偶、一样测量当前温度下热电偶电阻导致的电压变化但不同的是它不再返回模拟值依赖设备或连接板转换而是由传感器内置的 ADC 完成转换再把一串 0 和 1 发送给 IoT 设备——发送方式与按钮的数字信号一致1 代表满电压、0 代表 0V。输出数字数据让传感器可以承载更复杂、更详细的数据甚至是加密数据以保障安全。典型例子是摄像头它捕获图像并以 JPEG 等压缩格式的数字数据发送给 IoT 设备还能逐帧发送完整图像或压缩视频流来实现视频直播。执行器把电信号变成物理动作执行器与传感器恰好相反——把 IoT 设备的电信号转换为与物理世界的交互例如发光、发声、驱动电机。常见执行器包括LED通电时发光扬声器根据收到的信号发声从基础蜂鸣器到能播放音乐的音频扬声器步进电机把信号转换为精确的旋转量例如把旋钮转过 90°继电器可用电信号通断的开关允许 IoT 设备的小电压去控制更大的电压屏幕更复杂的执行器在多段显示器上展示信息从简单 LED 显示屏到高分辨率视频监视器。执行器类型模拟与数字与传感器类似执行器也分模拟、数字两类。模拟执行器电压决定交互强度模拟执行器接收模拟信号并转换为某种交互交互强度随供电电压变化。最直观的例子是可调光灯具供给灯的电压越高灯越亮。与传感器侧同理IoT 设备本身只输出数字信号因此要发送模拟信号设备需要数模转换器DACDigital to Analog Converter——可以内置于设备也可以在连接板上。DAC 把设备的 0 和 1 转换为执行器可用的模拟电压。课程同样提示不要测试设备发送的电压高于执行器承受能力的情形。脉宽调制PWM用数字脉冲模拟模拟信号除 DAC 外把数字信号转成模拟信号的另一个方案是脉宽调制PWMPulse-Width Modulation——发送大量极短的数字脉冲让整体效果表现得像模拟信号。课程用电机调速完整演示了 PWM 的数学原理150 RPM 场景用一个 5V 电源控制电机。发送 0.02 秒的 5V 高电平脉冲电机可转 1/10 圈36°再发送 0.02 秒的 0V 低电平一个开-关周期 0.04 秒循环往复。这样每秒有 25 个 5V 脉冲各转 1/10 圈电机每秒转 2.5 圈即 150 转/分钟rpm25 pulses per second x 0.1 rotations per pulse 2.5 rotations per second 2.5 rotations per second x 60 seconds in a minute 150rpm当 PWM 信号一半时间开、一半时间关时称为50% 占空比duty cycle——占空比即信号处于开状态的时间百分比。75 RPM 场景保持 0.04 秒的周期不变把高电平脉冲减半到 0.01 秒、低电平增加到 0.03 秒。每秒仍是 25 个脉冲但每个脉冲只转 1/20 圈于是电机每秒转 1.25 圈即 75rpm——只靠改变数字脉冲的宽度就把模拟电机速度减半了25 pulses per second x 0.05 rotations per pulse 1.25 rotations per second 1.25 rotations per second x 60 seconds in a minute 75rpm可以思考如何让电机在低速时保持旋转平滑是用少量长脉冲加长停顿还是大量极短脉冲加极短停顿另外值得一提的是某些传感器也利用 PWM 把模拟信号转换为数字信号。数字执行器两态控制与内置 DAC数字执行器要么像数字传感器一样由高低电压控制两种状态要么内置 DAC 可以把数字信号转换为模拟信号。最简单的数字执行器是LED设备发送数字 1 时输出高电压点亮 LED发送数字 0 时电压降至 0V、LED 熄灭。还能想到哪些简单的两态执行器例如螺线管solenoid——一种电磁铁通电后可以拨动门闩实现门锁的开/关。更高级的数字执行器如屏幕要求按特定格式发送数字数据通常自带库让开发者更容易发送正确的控制数据。实战构建一个智能夜灯本课的实战目标是把理论与实践结合读取光传感器采集的光线强度当光线过低时驱动 LED 执行器点亮——一个典型的传感器 → 决策 → 执行器闭环。课程为三种硬件平台提供了完整的分步指南与配套源码硬件平台传感器接入指南执行器接入指南配套源码目录Arduino — Wio Terminalwio-terminal-sensor.mdwio-terminal-actuator.mdcode-sensor/wio-terminal、code-actuator/wio-terminal单板计算机 — Raspberry Pipi-sensor.mdpi-actuator.mdcode-sensor/pi、code-actuator/pi单板计算机 — 虚拟设备CounterFitvirtual-device-sensor.mdvirtual-device-actuator.mdcode-sensor/virtual-device、code-actuator/virtual-device夜灯的整体工作流程可概括为下图循环读取光照值 → 判断是否低于阈值 → 控制 LED 开/关。方案一Raspberry Pi Grove 光传感器与 LED硬件接线传感器侧Grove 光传感器基于光电二极管photodiode把光转换为电信号输出 0~1023 的整数表示相对光照量不对应 lux 等标准单位。将 Grove 线缆一端插入传感器模块只有一种方向另一端在 Pi断电状态下接到 Grove Base hat 上的模拟插座A0GPIO 引脚旁边那一排从右数第二个。传感器编程完整代码见 code-sensor/pi/nightlight/app.pyimport time from grove.grove_light_sensor_v1_2 import GroveLightSensor light_sensor GroveLightSensor(0) while True: light light_sensor.light print(Light level:, light) time.sleep(1)GroveLightSensor(0)创建连接A0模拟引脚的实例light属性读取 0~1023 的模拟值并打印末尾time.sleep(1)降低轮询频率、减少设备功耗。在 Pi 上执行python3 app.py后遮挡/移开传感器即可看到数值变化piraspberrypi:~/nightlight $ python3 app.py Light level: 634 Light level: 634 Light level: 230 Light level: 104 Light level: 290硬件接线执行器侧Grove LED 模块带有多色 LED 可选。注意 LED 是二极管只能单向导通需把较圆一侧的引脚接入模块外侧标的插孔、较扁一侧负极接入靠近模块中心的插孔用十字螺丝刀逆时针把亮度旋钮拧到最大然后同样在断电状态下把 Grove 线缆另一端接到 Base hat 的数字插座D5GPIO 引脚旁那一排从左数第二个。夜灯逻辑伪代码Check the light level. If the light is less than 300 Turn the LED on Otherwise Turn the LED off夜灯编程完整代码见 code-actuator/pi/nightlight/app.pyimport time from grove.grove_light_sensor_v1_2 import GroveLightSensor from grove.grove_led import GroveLed light_sensor GroveLightSensor(0) led GroveLed(5) while True: light light_sensor.light print(Light level:, light) if light 300: led.on() else: led.off() time.sleep(1)关键点GroveLed(5)创建连接D5数字引脚的实例阈值300light 300时调用led.on()发送数字 1 点亮 LED否则led.off()发送数字 0 熄灭知识卡片Grove Base hat 上所有插座引脚号唯一——引脚 0、2、4、6 是模拟引脚5、16、18、22、24、26 是数字引脚向执行器发送数字值时0 对应 0V1 对应设备最大电压Pi Grove 场景下为 3.3Vif/else必须与print(Light level:, light)同级缩进确保位于while循环内。运行后遮挡光传感器LED 会在光照 ≤300 时点亮、300 时熄灭。若 LED 不亮检查是否接反方向、亮度旋钮是否开到最大。方案二Wio TerminalArduino PlatformIOWio Terminal 的光传感器内置于机身透过背面的透明塑料窗口可见见 wio-terminal-sensor.md 中的images/wio-light-sensor.png。由于课程此前用 PlatformIO 创建了 nightlight 工程传感器编程只需两步在setup函数末尾配置引脚传感器接入pinMode(WIO_LIGHT, INPUT);WIO_LIGHT是连接板载光传感器的 GPIO 引脚号设为INPUT表示从该引脚读取数据。随后清空loop函数并写入int light analogRead(WIO_LIGHT); Serial.print(Light value: ); Serial.println(light); delay(1000);analogRead从板载光传感器读取 0~1023 的模拟值通过串口打印delay(1000)与 Python 版的time.sleep(1)作用相同。重新连接 Wio Terminal 上传代码后打开 Serial Monitor 即可看到数值随遮挡变化。执行器侧Grove LED 模块接入 Wio Terminal 右侧 Grove 插座面对屏幕时远离电源键的那个该插座支持模拟/数字左侧插座仅支持 I²C 与数字设备。在setup末尾配置pinMode(D0, OUTPUT);D0是右侧 Grove 插座的数字引脚设为OUTPUT表示向引脚写入数据以驱动执行器。在loop的delay之前加入控制逻辑完整实现见 code-actuator/wio-terminal/nightlight/src/main.cppif (light 300) { digitalWrite(D0, HIGH); } else { digitalWrite(D0, LOW); }digitalWrite(D0, HIGH)发送 1 点亮 LEDLOW发送 0 熄灭。知识卡片发送数字值时 LOW 对应 0V、HIGH 对应设备最大电压Wio Terminal 为 3.3V。完整工程的setup会先以Serial.begin(9600)初始化串口并等待就绪PlatformIO 工程配置见 platformio.inienv:seeed_wio_terminalplatform atmelsam、board seeed_wio_terminal、framework arduino。方案三虚拟设备CounterFit没有实体硬件也没关系——课程提供基于CounterFit的虚拟 IoT 硬件方案。在 CounterFit Web 应用中创建虚拟光传感器Sensors面板的Create sensor中选择Light类型Units保持NoUnitsPin设为0点击Add见 virtual-device-sensor.md 中的images/counterfit-create-light-sensor.png与images/counterfit-light-sensor.png。Python 代码与 Pi 版几乎一致只是导入来自 CounterFit 的 shim 库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)CounterFitConnection.init(127.0.0.1, 5000)把虚拟设备连接到本机 5000 端口的 CounterFit 服务。运行后初始数值为 0可在 CounterFit 中通过两种方式改变读取值在Value框输入数字并点Set该数字即传感器返回值勾选Random复选框并设置Min/Max后点Set每次读取都会得到区间内的随机数。虚拟 LED在Actuators面板的Create actuator中选择LED、Pin设为5、点Add创建后还可用Color取色器修改 LED 颜色见 virtual-device-actuator.md 中的images/counterfit-create-led.png与images/counterfit-led.png。完整夜灯代码见 code-actuator/virtual-device/nightlight/app.py逻辑与 Pi 版完全一致GroveLed(5)绑定引脚 5光照 300 时led.on()、否则led.off()。运行后通过调节 CounterFit 中光传感器的Value/Random设置跨越 300 阈值即可看到虚拟 LED 亮灭切换。小结三种平台、同一套心智模型把三个方案放在一起对比可以发现底层逻辑完全同构环节Raspberry Pi (Python)Wio Terminal (C)虚拟设备 (Python)传感器初始化GroveLightSensor(0)pinMode(WIO_LIGHT, INPUT)analogRead(WIO_LIGHT)GroveLightSensor(0)CounterFit shim读取光照light_sensor.lightanalogRead(WIO_LIGHT)light_sensor.light执行器初始化GroveLed(5)pinMode(D0, OUTPUT)GroveLed(5)CounterFit shim控制 LEDled.on()/led.off()digitalWrite(D0, HIGH/LOW)led.on()/led.off()节流time.sleep(1)delay(1000)time.sleep(1)延伸挑战与作业前两课的挑战是盘点家里、学校或工作场所的 IoT 设备并判断其基于微控制器还是单板计算机本课的挑战在此基础上更进一步为每台设备列出它们连接的传感器和执行器并说明每个传感器/执行器在该设备上的用途。课程还配有正式作业 assignment.md研究传感器与执行器以及课前后测验适合作为复习自检。如需更深入地补充电学与电路、各类温度传感器、LED 工作原理的背景知识可参考课程文末的 Review Self Study 建议。下一课将在此基础上把夜灯的数据接入互联网进入连接互联网主题。【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考