HomeKit ESP32 Control Light II

快把你家的灯接入HomeKit吧其二(舵机篇)

上一篇文章中已经熟悉了如何烧录程序到ESP32,并且成功的点亮了一盏LED灯,如果你动手能力强的话。
那么上一节就是教会了你做了一个支持HomeKit的灯。

本篇会将上一篇中的LED替换成一个舵机。至于为什么使用舵机,是因为我不想破坏开关的原有结构,想使用一种非侵入式的方法去拓展现有的灯开关。

重新启用环境变量

如果你看完上一篇文章后重启了电脑,或者关闭了子系统,那么就得重新配置一下ESP-IDF的环境变量,也可能还需要重新将设备挂载到子系统上。
使用命令

1
. $HOME/esp/esp-idf/export.sh

即可

控制舵机

0x01 控制信号

要想控制舵机,就得发送正确的指令。我使用的舵机长这个样子:
servo
信号频率为50Hz.所谓的指令就是每个周期内,高电平脉冲的持续时间(宽度/长度)。

视频中红色为实际信号,可以看到,随着高电平的持续时间变长,舵机的角度也越来越大。

持续时间 对应角度
0.50ms
1.50ms 90°
2.50ms 180°

0x02控制相关代码

对于这种由脉冲信号控制的舵机,可以使用PWM来进行控制。查阅官方的指南,可以很容易的找到相关例子,甚至直接有现成的Demo可以使用(不得不说官方的例子真的很详细)。
好了,这下子也不用自己写了(还好不用,不然就得用for循环+延时,手动的凑出脉冲信号来控制了)
直接到mcpwm_servo_control_example.c
复制或者下载即可,为了方便,可以复制到上一篇文章中的led.c中去,不过要记得先把之前所有的内容注释掉,因为以后还要使用到那些代码。
其中

1
2
3
#define SERVO_MIN_PULSEWIDTH 1000 //Minimum pulse width in microsecond
#define SERVO_MAX_PULSEWIDTH 2000 //Maximum pulse width in microsecond
#define SERVO_MAX_DEGREE 90 //Maximum angle in degree upto which servo can rotate

需要修改一下,依据我的舵机参数,将其修改为

1
2
3
#define SERVO_MIN_PULSEWIDTH 500 //Minimum pulse width in microsecond
#define SERVO_MAX_PULSEWIDTH 2500 //Maximum pulse width in microsecond
#define SERVO_MAX_DEGREE 180 //Maximum angle in degree upto which servo can rotate

又因为我的板子没有引出18号引脚,所以还是修改为上篇文章中的2号引脚吧

1
2
3
4
5
static void mcpwm_example_gpio_initialize(void)
{
printf("initializing mcpwm servo control gpio......\n");
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, 18); //Set GPIO 18 as PWM0A, to which servo is connected
}

改为

1
2
3
4
5
6
static void mcpwm_example_gpio_initialize(void)
{
printf("initializing mcpwm servo control gpio......\n");
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, 2); //Set GPIO 2 as PWM0A, to which servo is connected
}
至此,代码就修改完成了。

0x03 烧录进去吧

烧录过程没什么好说的,就是和之前大差不差。

编译好项目以后

1
make -C examples/esp32/led all

先进行earse_flash

1
make -C examples/esp32/led erase_flash

再进行flash。

1
make -C examples/esp32/led flash

0x04 看看效果吧

servo
由于烧录进去的代码只是为了控制舵机,所以是无法被添加到HomeKit里面的。
当烧录完成后,舵机就会缓慢的从0度转到180度,然后快速的回到0度,再次从0度转到180度,然后无限循环。

注:

控制具体转到多少度的代码如下,建议眼熟一下,下篇文章会用到。

1
2
3
4
// 先计算出目标角度对应的高电平持续时间
angle = servo_per_degree_init(count);
// 设置PWM信号
mcpwm_set_duty_in_us(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, angle);

下期预告:快把你家的灯接入HomeKit吧其三(整合篇)

参考资料:

ESP-IDF 编程指南

Espressif IoT Development Framework