项目缘起与硬件平台介绍
本项目源于DigiKey举办的【你晒单,我买单,DigiKey带您畅享好物】第七期试用活动,有幸获得Espressif Systems(乐鑫科技)最新推出的ESP32-P4-EYE开发板。该开发板搭载ESP32-P4芯片,具备强大的AI加速能力和图像处理性能,特别适合边缘AI视觉应用开发。结合板载的摄像头模组和丰富的外设接口,为智能物联网设备原型设计提供了理想平台。
项目概述:智能宠物投喂系统
经常出差,家中宠物面临无法按时投喂问题。放置过多食物,很容易造成污染;过少食物,又会导致宠物的饥饿。为此,我设计并实现了一套基于计算机视觉的智能猫狗识别与自动投喂系统。该项目利用ESP32-P4-EYE开发板的AI算力,通过深度学习模型实时识别监控画面中的猫狗,当确认宠物出现在喂食区域时,自动触发舵机控制机制,精准投放适量食物。系统还具备防重复触发机制,避免宠物长时间逗留导致过度投喂,真正实现"按需投喂"的智能化管理。
添加舵机控制:
使用ESP-DL实现了深度学习识别猫、狗的功能后,接下来就是用舵机控制喂食器的喂食。这里我使用的是SG90舵机。SG90是一个180度舵机,其控制信号是通过脉冲宽度调制(PWM)来实现的。其工作原理是通过PWM信号控制内部电机转动到指定位置。标准PWM控制信号周期为20ms(50Hz),其中高电平脉冲宽度在0.5ms-2.5ms之间对应0-180度的角度变化。当舵机处于0度角时,喂食器是关闭状态。处于90度时喂食器打开,猫粮、狗粮会滚落出来。SG90工作电压为3V~6V,这里从ESP32-P4-EYE侧面的扩展接口中取5V电压供电。使用GPIO10管脚做为PWM信号输出管脚。系统中设置了当检测到有猫、狗出现时,就打开喂食器3秒,然后关闭喂食器,并在10秒内不会再开启。喂食器计划使用3D打印实现,靠舵机驱动食物的添加。
ESP-IDF提供了LED PWM(LEDC)和MCPWM两种方式来产生PWM信号。这里我使用LEDC方式产生PWM信号来驱动舵机。先设置LEDC基础设置,使用50Hz做为PWM的周期。
// 添加舵机
#define SERVO_PIN 10 // 舵机信号引脚
#define LEDC_TIMER LEDC_TIMER_0
#define LEDC_MODE LEDC_LOW_SPEED_MODE
#define LEDC_CHANNEL LEDC_CHANNEL_0
#define LEDC_DUTY_RES LEDC_TIMER_13_BIT // 分辨率:2^13 = 8196
#define LEDC_FREQ_HZ 50 // 50Hz (20ms 周期)
static int32_t servo_opentime = 0; // 舵机动作时间
static bool servo_open = false;
然后在系统启动后,初始化LEDC。
static void ledc_init(void)
{
// Prepare and then apply the LEDC PWM timer configuration
ledc_timer_config_t ledc_timer = {};
ledc_timer.speed_mode = LEDC_LOW_SPEED_MODE;
ledc_timer.duty_resolution = LEDC_DUTY_RES;
ledc_timer.timer_num = LEDC_TIMER;
ledc_timer.freq_hz = LEDC_FREQ_HZ; // Set output frequency at 50 Hz
ledc_timer.clk_cfg = LEDC_AUTO_CLK;
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
// Prepare and then apply the LEDC PWM channel configuration
ledc_channel_config_t ledc_channel = {};
ledc_channel.gpio_num = SERVO_PIN;
ledc_channel.speed_mode = LEDC_LOW_SPEED_MODE;
ledc_channel.channel = LEDC_CHANNEL;
ledc_channel.intr_type = LEDC_INTR_DISABLE;
ledc_channel.timer_sel = LEDC_TIMER;
ledc_channel.duty = 0; // Set duty to 0%
ledc_channel.hpoint = 0;
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}
然后在检测的有猫、狗时,调整PWM信号的高低电平比例,控制舵机动作。
// 开启舵机:当检测到有猫、狗时,舵机旋转到指定角度,并保持该角度3秒。 10秒内再次检测到有猫、狗时,舵机不动作。
static void open_servo(bool check_cat_dog)
{
if (servo_open == true && esp_timer_get_time() / 1000000 - servo_opentime < 3)
return;
if (servo_open == false && esp_timer_get_time() / 1000000 - servo_opentime < 10)
return;
if (servo_open == true && esp_timer_get_time() / 1000000 - servo_opentime < 10)
{
ESP_LOGI(TAG, "Close servo 1");
ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, angle_to_duty(0));
ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
servo_open = false;
return;
}
if (check_cat_dog)
{
ESP_LOGI(TAG, "Open servo 1");
servo_opentime = esp_timer_get_time() / 1000000;
ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, angle_to_duty(90));
ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
servo_open = true;
return;
}
else
{
if (esp_timer_get_time() / 1000000 - servo_opentime >= 3 && servo_open == true)
{
ESP_LOGI(TAG, "Close servo 2");
servo_opentime = esp_timer_get_time() / 1000000;
ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, angle_to_duty(0));
ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
servo_open = false;
}
}
}
效果演示:
摄像头捕捉到橘猫进入检测区域,ESP-DL模型以95%置信度识别为"cat"。屏幕实时渲染出黄色检测框(坐标[x=120, y=150, w=280, h=340]),右上角叠加推理耗时仅18ms。与此同时,舵机已旋转至90度位置,喂食器仓门开启,颗粒状食物正从斜槽滚落。这里快速推理,得益于ESP32-P4的DSP加速优势。串口中也同时会输出图像检测结果。
未检测到宠物时,系统进入低功耗监控模式。屏幕仅显示实时画面,无检测框叠加。舵机保持0度锁定状态,仓门完全闭合。此时LEDC PWM占空比为2.5%(对应0.5ms脉宽),确保舵机静态扭矩锁定,防止粮食自重意外开启仓门。功耗测试显示该状态下整机电流仅85mA,适合长期运行。
项目总结与开发心得
本次开发使用ESP-IDF,乐鑫为我打开了一个机器学习的新世界。在乐鑫官网,提供了大量的已经经过验证的AI范例,学习着这些例程很快就能搭建起自己的应用。但是目前项目只能对猫、狗进行识别,还不能识别到具体的宠物个体,后续还将更进一步增加对宠物个体的识别,用以跟踪、记录宠物的更详细信息。


