
开源协议
:CC BY-NC-SA 4.0
描述
* 1、项目功能介绍
一切的起因都是从家里那颗发财树被我浇水浇过头开始……
为了能精准知道什么时候该浇水,我开始研究起了土壤湿度计。
土壤湿度计从原理上主要分为两种:电导率测量和电容值测量。
| 测量方式 | 优点 | 缺点 |
|---|---|---|
| 电导率法 | 电路简单 | 电极易氧化,需使用抗腐蚀金属,成本偏高 |
| 电容法 | 传感器可绝缘,寿命长,线性度好 | 传统方案功耗偏高 |
电容测量本身传感器可以做到完全绝缘,因此在寿命上优于电导率方式,同时线性度也更加优秀。
传统方案的痛点
市面上常见的电容式土壤湿度计,大多依赖 RC 振荡电路 产生方波,通过频率变化来推测土壤湿度。然而振荡电路的缺点在于功耗偏高,大部分方案的功耗在 10~100mA 级别,难以长时间依靠电池供电运行。
本项目核心目标:在保持电容测量优势的前提下,大幅降低系统功耗。
核心创新方案
电容测量除了 RC 振荡法之外,还有另一种方式:恒流恒定时间充电法—— 以恒定电流对电容充电固定时间,然后通过电压计算电容值。
CH584 芯片内置了该功能,支持 10~100pF 的电容测量范围。通过合理的 PCB 设计,可以使等效电容值刚好落在这个区间内,从而实现精准的土壤湿度测量。
功耗与工作策略
为了尽可能延长设备续航时间,同时保证使用体验,采用了以下工作策略:
| 工作项 | 频率 | 说明 |
|---|---|---|
| 蓝牙广播 | 每 2 秒 一次 | 低功耗蓝牙广播,用于数据上报 |
| 湿度测量 | 每 5 秒 一次 | 电容采样 + 湿度换算 |
| 电池电压测量 | 每 10 秒 一次 | 监测电池电量 |
广播数据包含:
- 电容采样后的原始 ADC 值
- 电池电压值
- 转换后的湿度百分比
- 转换后的电量百分比
得益于 CH584 优秀的功耗管理,整个电路平均功耗仅 22μA,一颗 200mAh 的 CR2032 纽扣电池可以连续使用1整年,大幅降低设备维护频率。

土壤标定流程
首次使用时,需进行土壤标定。通过发送蓝牙指令,可以分别标定两个基准点:
- "全干土壤" → 对应 0% 湿度
- "全湿土壤" → 对应 100% 湿度
固件记录这两个基准值后,后续土壤湿度通过线性插值计算得出。最后可以为设备重命名,就能与不同花盆中的其他设备区分开了。

*2、项目属性
首次公开;项目完全原创;项目未曾在其他比赛中获奖;项目未参加过答辩。
* 3、开源协议
本项目以CC BY-NC-SA 4.0协议发放
*4、硬件部分
这个湿度计核心部分其实就是CH584F最小系统,USB\LDO\TVS只是为了没有烧录器的人下载程序用,去掉不影响设备运行。
触摸传感器本质上也是电容测量,所以只需要设计一个合适的“触摸区域”,就能直接利用芯片进行土壤湿度检测。
*5、软件部分
开发环境
软件使用 MSR2 开发环境进行开发,编译后的固件可以直接通过 沁恒 ISP 软件从 USB 口烧录进芯片。
软件流程
通过TMOS定时(每5秒)触发数据更新,每次广播时更新数据值。
线性插值计算
标定完成后,土壤湿度通过以下公式计算:
湿度(%) = (1 - (ADC_当前 - ADC_湿土) / (ADC_干土 - ADC_湿土)) × 100%
广播数据包
在mainApp.cpp里,
static uint8_t advertDataV[31] = {/* flags */0x02, 0x01, 0x06, //00-020x09, 0x16, //03-040xF0, 0x77, 0x00, 0x00, 0x77, 0x0F, 0x00, 0x00, //05-12/* device name *///13 14 150x10-4, 0x09, 'L', 't', 't', 'E', 'S', 'T', 'M', 'o', 'n', 'V', '1'
};
void adverCB(uint32_t timeUs){if(cfgMgr.NameModifyed != 0){advertDataV[13] = cfgMgr.config.NameStrLen+1;tmos_memcpy(advertDataV +15, cfgMgr.config.NameStr, cfgMgr.config.NameStrLen);advertDataSize = 15+cfgMgr.config.NameStrLen;cfgMgr.NameModifyed = 0;}
advertDataV[7] = curKval&0xFF;advertDataV[8] = (curKval>>8)&0xFF;advertDataV[9] = curAdcV&0xFF;advertDataV[10] = (curAdcV>>8)&0xFF;advertDataV[11] = cfgMgr.CalcWetVal(curKval);advertDataV[12] = cfgMgr.CalcBatVal(curAdcV);
GAP_UpdateAdvertisingData(Peripheral_TaskID_Real, TRUE, advertDataSize, advertDataV);
}
advertDataV的03-12为自定义数据,其中 advertDataV[05] = 0xF0, advertDataV[06] = 0x77 作为识别标记,后续紧跟2字节湿度ADC值,2字节电压mV值,1字节湿度百分比,1字节电量百分比。
后续如有需要蓝牙网关识别,主要就依赖这段数据。
参数修改
还是在mainApp.cpp里,void newDatain(uint8_t * inData,int len)负责处理蓝牙写入的指令处理。
代码都有完整注释,可以直接看到每一个指令。
写入指令为 0x75 0x35 负载长度 命令字 负载数据
0x75 0x35 为识别头,负载长度即负载数据的字节数。
命令字目前只有3个:
switch (bcmdBuffer[3]) //命令字{case 1: //修改蓝牙名{if(bcmdBuffer[2] < 2){//蓝牙名无效}else{if(bcmdBuffer[2] > 15){bcmdBuffer[2] = 15;}cfgMgr.SetBleName(bcmdBuffer+4,bcmdBuffer[2]);}}break;case 2: //设置为满湿度{cfgMgr.SetWetADC(curKval);}break;
case 3: //设置为干燥值{cfgMgr.SetDryADC(curKval);}break;}
*6、BOM清单
见后面自动生成的BOM,所有元件均已验证,可直接使用。
*7、大赛LOGO验证

* 8、演示您的项目并录制成视频上传
设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。










