IoT-For-Beginners 数字农业实战:用 CounterFit 虚拟硬件读取土壤湿度(ADC 模拟传感器入门)
2026/9/16 22:08:30 网站建设 项目流程

IoT-For-Beginners 数字农业实战:用 CounterFit 虚拟硬件读取土壤湿度(ADC 模拟传感器入门)

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

本指南对应 IoT-For-Beginners 课程「2-farm」第 2 课「检测土壤湿度」中的虚拟物联网硬件路线。你将学习如何在不购买任何实体硬件的前提下,用 CounterFit 在本地模拟一个 Grove 电容式土壤湿度传感器,用与 Raspberry Pi 完全一致的 Python 代码读取 10 位 ADC 模拟量,并掌握后续作物自动灌溉项目所需的土壤湿度采集能力。

课程定位:为什么要检测土壤湿度

本课位于 2-farm 数字农业模块的第 2 课。上一课已经介绍了通过测量环境温度来预测植物生长,而土壤湿度是另一项决定植物生长质量的关键指标:土壤中水分过少,植物根系无法吸收足够的水分;水分过多,根系又无法获得足够氧气,最终导致根系死亡、植物无法摄取养分。因此,对农民而言,既不能太湿也不能太干的土壤状态才是最优解,而 IoT 设备的作用就是持续测量土壤湿度,帮助农民只在需要时浇水,为下一课「自动化植物灌溉」打下基础。

在动手之前,先理解土壤湿度传感器的两种常见实现:

  • 电阻式(Resistive):两根探针插入土壤,电流从一根探针出发、在另一根探针处测量电流衰减,从而得到土壤电阻。水是良导体,土壤含水量越高,电阻越低。
  • 电容式(Capacitive):测量土壤这块「介质」存储电荷的能力(电容)。土壤湿度变化会引起电容变化,并被转换为 IoT 设备可读取的电压。土壤越湿,输出电压越低。

本课使用的 Grove 电容式土壤湿度传感器属于模拟传感器,它返回电压来表示湿度。为了让电压变成代码里的数字,虚拟设备使用一个模拟的10 位 ADC(模数转换器),将电压映射为 1~1,023 的整数值(课程作业中亦按 0~1,023 描述该范围)。

虚拟硬件方案:CounterFit 模拟 Grove 传感器

在 1-getting-started 第 1 课中,你已经在本地安装了 Python、VS Code 和 CounterFit 相关 Pip 包。CounterFit 是一个在本机运行的模拟 IoT 硬件应用:它在浏览器中提供传感器/执行器的模拟界面,你的 Python 代码通过counterfit-shims-grove垫片层(shim)以「在真实 Grove 生态上编程」完全相同的方式访问这些虚拟设备。

💡 采用这种方案的好处是:整个练习与「Raspberry Pi + 实体 Grove 电容式土壤湿度传感器」的接线与代码保持一致——同一个读取逻辑,既能在虚拟环境运行,也能无缝迁移到真实硬件。

任务一:在 CounterFit 中添加土壤湿度传感器

在开始写代码前,先把虚拟传感器注册到 CounterFit 应用中:

  1. 在电脑上新建一个名为soil-moisture-sensor的文件夹,其中只包含一个app.py文件;为它创建 Python 虚拟环境,并安装 CounterFit 系列 Pip 包。若需要回顾项目创建与安装过程,可参考 第 1 课虚拟设备指南(关键安装命令为pip install CounterFitpip install counterfit-connectionpip install counterfit-shims-grove)。
  2. 确保 CounterFit 网页应用正在运行(默认监听127.0.0.1:5000)。
  3. 创建土壤湿度传感器:
    • Sensors面板的Create sensor区域,打开Sensor type下拉框,选择Soil Moisture
    • Units保持NoUnits不变(该传感器输出的是 ADC 原始读数,没有物理单位);
    • 确保Pin0
    • 点击Add按钮,在 Pin 0 上创建 Soil Moisture 传感器。

创建完成后,传感器会出现在传感器列表中:

编写土壤湿度传感器程序

任务二:编写 app.py

  1. 在 VS Code 中打开soil-moisture-sensor应用文件夹。

  2. 打开app.py,在文件顶部加入连接 CounterFit 的代码:

    from counterfit_connection import CounterFitConnection CounterFitConnection.init('127.0.0.1', 5000)

    CounterFitConnection.init('127.0.0.1', 5000)将应用连接到本机 5000 端口上运行的 CounterFit 服务。注意:这条初始化调用必须出现在任何 shim 类实例化之前,否则虚拟硬件连接尚未建立。

  3. 继续添加所需的库导入:

    import time from counterfit_shims_grove.adc import ADC
    • import time导入time模块,稍后用于控制读取间隔;
    • from counterfit_shims_grove.adc import ADC从 Grove 垫片库导入ADC类,用于与 CounterFit 中可连接的虚拟模拟数字转换器交互。
  4. 创建ADC类实例:

    adc = ADC()
  5. 添加一个无限循环:从该 ADC 的 Pin 0 读取数值并打印到控制台,每次读取后休眠 10 秒:

    while True: soil_moisture = adc.read(0) print("Soil moisture:", soil_moisture) time.sleep(10)

    adc.read(0)中的参数0与第 1 步在 CounterFit 中设置的 Pin 值一一对应——这也是为什么创建传感器时必须把 Pin 设为 0。

本课的完整示例代码存放在 code/virtual-device/soil-moisture-sensor/app.py,与上文逐行一致。

任务三:运行并模拟不同湿度

  1. 在 CounterFit 应用中修改传感器值,CounterFit 提供两种方式:

    • 固定值:在传感器的Value输入框中输入数字,点击Set按钮,传感器即返回该数值;
    • 随机值:勾选Random复选框,设置MinMax,点击Set。此后每次传感器被读取时,都会返回 Min 与 Max 之间的随机数——这对模拟「土壤湿度随时间波动」的场景非常有用。
  2. 运行 Python 应用:

    (.venv) ➜ soil-moisture-sensor $ python app.py

    控制台将不断输出土壤湿度读数:

    Soil moisture: 615 Soil moisture: 612 Soil moisture: 498 Soil moisture: 493 Soil moisture: 490 Soil Moisture: 388

    在上面的示例输出中,可以看到随着虚拟「浇水」值被调低,读数从 615 逐渐下降到 388——这正是电容式传感器「土壤越湿、电压越低」特性的数字化体现。

原理纵深:同一套代码,三种硬件

从源码结构看,本课虚拟设备的读取 API 刻意与真实硬件保持一致,便于日后平滑迁移:

维度虚拟设备(本课)Raspberry PiWio Terminal
导入from counterfit_shims_grove.adc import ADCfrom grove.adc import ADC无(Arduino 内建)
读取adc.read(0)adc.read(0)(接 A0 口)analogRead(A0)
间隔time.sleep(10)time.sleep(10)delay(5000)
对应文档virtual-device-soil-moisture.mdpi-soil-moisture.mdwio-terminal-soil-moisture.md

对照可见:

  • Raspberry Pi 版grove.adc.ADC通过 Grove Base Hat 上集成的 ADC 读取 A0 模拟口,再经 I²C 总线送回 Pi 的 GPIO 引脚(Pi 本身只有数字引脚,模拟值靠 Base Hat 的 ADC 转换)。
  • Wio Terminal 版:参考 main.cpp,直接在setup()pinMode(A0, INPUT),在loop()analogRead(A0),读取间隔为 5 秒。
  • 虚拟设备版counterfit_shims_grove.adc.ADC是 Grove 库的垫片实现,read(0)底层从 CounterFit 服务拉取 Pin 0 的模拟量。由于接口签名一致,本课的while True循环无需任何改动即可换用grove.adc跑在真实树莓派上。

这段 10 位 ADC 读数(0~1,023)本质上只是「土壤的电压映射」,并不是可直接使用的物理湿度值。要把它变成「含水量百分比」,就需要对传感器做校准。

拓展:校准传感器,把 ADC 读数变成真实湿度

课程作业 assignment.md 给出了一套标准校准流程。核心思想是重量法(gravimetric soil moisture):用传感器读数对照实验室测得的真实含水量,拟合出换算关系。

校准步骤(需要多次重复,每次使用不同湿度的土壤):

  1. 用土壤湿度传感器读取一次读数并记录下来;
  2. 取一份土壤样本并称重,记录湿重 W_wet;
  3. 烘干土壤——最佳方式是用 110°C(230°F)的烤箱烘数小时(实验室精度要求 48~72 小时),或用阳光晾晒直到土壤完全干燥、呈粉末状;
  4. 再次称重,记录干重 W_dry。

重量含水量的计算公式为:土壤湿度% = (W_wet − W_dry) / W_dry × 100

例如:湿样重 212g,干样重 197g,则 (212 − 197) / 197 × 100 ≈7.6%

完成至少 3 个样本后,将「土壤湿度%」对「传感器读数」绘制散点图并拟合一条最佳拟合线,之后任意一个新读数都能通过这条线换算成真实含水量。校准结果的验收标准参见 assignment.md 中的 Rubric 表格(至少 3 个校准样本为优秀档)。

小结

在本课中,你完成了三件事:

  1. 在 CounterFit 中添加并配置了一个 Grove 电容式土壤湿度模拟传感器(Pin 0,无单位);
  2. counterfit_connection+counterfit_shims_grove.adc.ADC编写了与 Raspberry Pi 完全一致的土壤湿度读取程序,验证了「固定值」与「Random 随机值」两种模拟模式;
  3. 理解了 10 位 ADC 读数与真实湿度之间的差距,以及用重量法校准传感器的完整流程。

这套「模拟传感器 → 读取 ADC 原始值 → 校准换算」的能力链,正是下一课「自动化植物浇水」中判断「该不该浇水」的核心数据来源——届时你会用相同的土壤湿度读数去控制继电器和抽水泵,构建完整的数字农业闭环。

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

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

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

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

立即咨询