首页 > 分享 > ESP32 应用实践:基于 ULP 的超低功耗浇花设备

ESP32 应用实践:基于 ULP 的超低功耗浇花设备

1. 背景和目的

ULP Co-processor 是 ESP32 内置的一颗功耗极低的协处理器设备,无论主 CPU 是处于正常运行模式或是 Deep-Sleep 模式, ULP 协处理器都可以独立运行。ULP 协处理器具有特色的内置了 ADC 控制器和 I2C 控制器,支持正常模式和 Deep-Sleep 模式,并支持唤醒主 CPU 和向主 CPU 发送中断等特性,更多特性及介绍详见乐鑫的ESP32技术参考手册。

2. 方案阐述

最终方案应用见视频: http://v.youku.com/v_show/id_XMzE4MTU5NjY5Ng==.html

ULP 协处理器大部分时间处于睡眠状态,定时唤醒后,通过 SAR_ADC 检测土壤湿度,如土壤干燥则控制 RTC_GPIO 执行浇水动作,如检测到传感器异常后闪烁 LED 并唤醒主 CPU 。这个 ULP 例子消耗电流平均为 4.7uA 左右。

3. 硬件部分

为了实现上述功能,我们需要可以测芯片电流的 ESP32_ULP_EBV1 开发板(使用其他开发板亦可,只不过无法的看到芯片 Deep-Sleep 时耗流情况),一个叉状电极用于插入土壤,一个 5V 继电器模块,一个 5V 小水泵

3.1 硬件原理图

硬件原理图使用 Kicad 设计,检测土壤湿度原理是通过 47k 电阻和土壤中的电阻分压,测得 ADC 值后推算出土壤的湿度。另外,湿润的土壤到干燥的土壤电阻值一般测得阻值数据是 20K - 100k 左右。

需要注意:ESP32_ULP_EBV1 这个板子 GPIO34 有 10K 上拉电阻 R41 ,我们把它去掉了,因为 ADC 采集不需要这个电阻,并且还会造成漏电流。

s_7

3.2 硬件实物 3.3整体连接图

这里写图片描述

4.软件部分

ESP32 的 C 语言编译环境安装和配置参照 链接地址,另外 ULP 协处理器目前只支持汇编编程,所以还需要安装汇编工具链,下面介绍汇编工具链的安装和配置。

4.1 汇编环境的配置

ULP 协处理器配置汇编编译工具链,只需两步即可安装配置完毕,下面给出 ubuntu 操作系统下配置的步骤,或者点击 链接地址 获得更多 ULP 编程信息

第一步, 下载工具链 binutils-esp32ulp toolchain 链接地址, 解压到需要安装的目录第二步,添加工具链的 bin 目录到系统环境变量 PATH 中。例如我的解压目录是 /opt/esp32ulp-elf-binutils 那么添加 export PATH=/opt/esp32ulp-elf-binutils/bin:$PATH 这一行到 /home 目录的隐藏文件 .bashrc 文件最后一行,保存关闭文件并使用命令 source .bashrc 使上述环境变量生效

至此,汇编编译环境就安装好了。

根据 4.4 节可获取包含 ulp_watering_device 的完整 SDK ,在 ulp_watering_device/ 目录下依次运行如下命令:

$ make defconfig $ make all -j8 && make flash monitor12

将自动调用汇编工具链编译汇编代码,并烧录运行。

4.2 管脚使用 管脚功能GPIO4RELAY_CTLGPIO34SAR_ADCGPIO26SENSOR_ERROR_LED 4.3 程序流程图

ESP32 上电后,配置 ULP 协处理器相关的 RTC GPIO 和唤醒周期后进入休眠,ULP 协处理器醒来后,通过 ADC 指令获取土壤电阻分压 ADC 值,如果检测到 SENSOR 异常,则唤醒 CPU 闪烁 LED 指示灯,用户可自定义其他的出错处理(例如链接云上报数据);如果检测到湿度区间合适则什么都不做继续睡眠降低功耗;如果湿度值低于设定阈值则打开 RTC GPIO 控制水泵浇水。
10

4.4 代码分析

本例子的代码保存在 GitHub 仓库 espressif/esp-iot-solution 中,可通过 git 命令获取代码

$ git clone https://github.com/espressif/esp-iot-solution $ cd esp-iot-solution $ git submodule update --init --recursive123

本 demo 代码位于 esp-iot-solution/examples/ulp_watering_device 下

下面给出部分的汇编代码
汇编代码主要分成三大部分:ADC 采样、RTC GPIO 操作以及 Polling CPU 唤醒,第一部分给出 ADC 采样的汇编代码,主要意图是多次采样 ADC 以及计算平均值

///* ulp read adc example: using ADC in deep sleep on ulp co-processor */ /* increment sample counter */ move r3, sample_counter ld r2, r3, 0 add r2, r2, 1 st r2, r3, 0 /* do measurements using ADC */ /* r0 will be used as accumulator */ move r0, 0 /* initialize the loop counter */ stage_rst measure: /* measure and add value to accumulator */ adc r1, 0, adc_channel + 1 add r0, r0, r1 /* increment loop counter and check exit condition */ stage_inc 1 jumps measure, adc_oversampling_factor, lt /* divide accumulator by adc_oversampling_factor. Since it is chosen as a power of two, use right shift */ rsh r0, r0, adc_oversampling_factor_log /* averaged value is now in r0; store it into last_result */ move r3, last_result st r0, r3, 0

123456789101112131415161718192021222324252627

第二部分汇编代码,主要是操作 RTC GPIO 用来打开或者关闭水泵,以及 SENSOR 出错的处理

.global start_water start_water: /* Disable hold of RTC_GPIO10 output */ WRITE_RTC_REG(RTC_IO_TOUCH_PAD0_REG,RTC_IO_TOUCH_PAD0_HOLD_S,1,0) /* Set the RTC_GPIO10 output HIGH to signal that ULP is now up */ WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG,RTC_GPIO_OUT_DATA_W1TS_S+10,1,1) /* Enable hold on RTC_GPIO10 output */ WRITE_RTC_REG(RTC_IO_TOUCH_PAD0_REG,RTC_IO_TOUCH_PAD0_HOLD_S,1,1) /* stop water and go sleep */ jump exit /* start pump and go sleep wait next wake up checking ADC value */ .global stop_water stop_water: /* Disable hold of RTC_GPIO10 output */ WRITE_RTC_REG(RTC_IO_TOUCH_PAD0_REG,RTC_IO_TOUCH_PAD0_HOLD_S,1,0) /* Set the RTC_GPIO10 output LOW (clear output) to signal that ULP is now going down */ WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG,RTC_GPIO_OUT_DATA_W1TC_S+10,1,1) /* Enable hold on RTC_GPIO10 output */ WRITE_RTC_REG(RTC_IO_TOUCH_PAD0_REG,RTC_IO_TOUCH_PAD0_HOLD_S,1,1) jump exit /* stop water and go sleep */ .global sensor_err sensor_err: /* Disable hold of RTC_GPIO10 output */ WRITE_RTC_REG(RTC_IO_TOUCH_PAD0_REG,RTC_IO_TOUCH_PAD0_HOLD_S,1,0) /* Set the RTC_GPIO10 output LOW (clear output) to signal that ULP is now going down */ WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG,RTC_GPIO_OUT_DATA_W1TC_S+10,1,1) /* Enable hold on RTC_GPIO10 output */ WRITE_RTC_REG(RTC_IO_TOUCH_PAD0_REG,RTC_IO_TOUCH_PAD0_HOLD_S,1,1) jump wake_up /* sensor error waku up */

123456789101112131415161718192021222324252627282930313233343536373839404142

最后,第三部分的汇编代码是用来 Polling CPU 是否可以被唤醒

/* value within range, end the program */ .global exit exit: halt .global wake_up wake_up: /* Check if the system can be woken up */ READ_RTC_REG(RTC_CNTL_DIAG0_REG, 19, 1) and r0, r0, 1 jump exit, eq /* Wake up the SoC, end program */ wake WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0) halt

12345678910111213141516

5. 电流部分

ULP 协处理器的主频是 8MHz, ULP 协处理器在正常工作时,瞬时电流消耗为 1.4 - 2.2 mA 左右。理想的 ULP 协处理器用法是较长的周期性进入 Deep-Sleep 和短暂的醒来工作来换取功耗平衡。
此例子为了演示效果,我们的设定 ULP 协处理器睡眠周期设置为 3 S,醒来工作的周期不足 1ms, 用电流表测得电流值维持在 4.7uA

6.总结部分

ULP 协处理器十分强大,内置 ADC 和 I2C 接口,能够在低功耗模式下做出更为复杂的应用,但应尽可能的使其进入 DeepSleep 状态降低功耗。

相关知识

基于ESP32的开源定时浇花系统
Arduino 智能花草看护系统 ESP32开发板
基于物联网的户外环境检测装置(STM32、APP、WIFI)
基于物联网的集散控制系统在温室群环境监测控制中的应用
【IoT开发】基于机智云物联网的智能浇花教程
探索DA28F160S5:高效、低待机功耗的开关电源芯片
如何用ESP32做一个智能检测花盆
基于物联网的智能浇花系统
机劳去病——基于YOLOv5模型的病虫害数智化诊断终端系统
基于物联网的温室远程监测器设计

网址: ESP32 应用实践:基于 ULP 的超低功耗浇花设备 https://m.huajiangbk.com/newsview478129.html

所属分类:花卉
上一篇: 九月花事简略
下一篇: 基于单片机stm32的智能浇花系