引言
为什么要写这个,是因为自己在使用esp8266的pwm调节灯光亮度时遇到一个问题。最后终于解决。
所用器材和平台:
1.一个nodemcu开发板
2.一个LED灯(为了接线方便,我把usb小LED灯的usb插头拆了)
3.云平台:机智云平台SOC方案
4.固件编译环境AiThinker_IDE,
烧录工具flash_download_tools_v3.6.6
缩略:
esp8266的pwm函数功能就不一一介绍了,开发手册上都讲得很清楚,esp8266官网里查找即可。
想达到的目标功能:
达到手机可以开关LED灯并且可以调节亮度,当亮度为0时灯必须熄灭。
初始思路:
LED灯的一个引脚连接NodeMCU的3.3V,LED灯的另一个引脚连接NodeMCU的PWM引脚。
最后发现这样连接引脚有问题:关灯,灯不会熄灭啊啊啊啊啊。
不过最后解决啦啊哈哈哈哈。
过程:
在机智云平台创建了两个数据点,第一个是布尔类型的控制灯的开关,第二个是数值类型的控制灯的亮度。
编译固件
刚开始使用的固件代码是机智云官方的SOC方案代码。
在实现可以手机控制开关LED灯的基础上,我添加了机智云库里
的pwm.h头文件
到gizwits_product.c文件这里
同理,在user_main.c中最上边,也是添加上pwm.h头文件(方法同上,图省略)。
因为我设置的pwm引脚是GPIO4。
uint32 io_info[][3] ={{PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4,4}};
就是这样配置。函数中参数就不一一介绍了,开发手册很清楚,不是问题重点。
然后在主函数里先初始化pwm,也就是设置好周期,下图为1000us。
机智云功能函数在gizwits_product.c文件中,调节光亮直接在功能函数中调用pwm.h中的占空比设置函数就可以
pwm_set_duty(0,0);
pwm_start();
解释:
pwm_set_duty中第一个参数是duty数值,代表高电平占空比数值,duty范围为0~22222,参数duty与设置的周期大小有关。
第二个参数是通道值,我初始化时pwm引脚设置用的0通道。
具体可查手册。
duty为0意味着一个周期内有0份为高电平即整个周期全为高电平,因为在上图user_main.c文件中初始化pwm时设置的周期为1000us即频率为1KHz,这样的话一个周期就是22222份。
每次设置pwm_set_duty后边必须紧跟pwm_start();占空比设置才能有效。
如果pwm_set_duty(22222,0);pwm_start();
也就是整个周期为高电平。
调光就是利用pwm可以调节高低电平占空比(我的理解是高低电平的百分比),因此设置duty值调光可以实现啦,我好兴奋当时哈哈哈。
LED灯不能熄灭根源:
但是突然发现有一个问题就是,当我在手机APP上把调光亮度值调到0时,发现LED灯并没有熄灭,而是亮度在微微亮。然后我就很疑惑。最后发现是这种设置方式的LED灯pwm不能达到100%。不是空穴来风,这是官方的回答。
理想的熄灭状态时,两个引脚之间没有特别大的电势差,驱动不了LED灯,LED灯就熄灭。
两个原因。
但是pwm占空比没有达到100%,也有可能原因是即使pwm占空比100%,pwm引脚并不能达到3.3V。
LED灯一个引脚为3.3V时候,pwm引脚并不是3.3V,两个引脚有比较大的电势差,使LED灯亮度达到了亮起来。
解决方法:
很简单。
刚开始LED灯一个引脚接3.3V,另一个引脚接pwm引脚,
我把它们的引脚换了一下:
pwm引脚做电源(SDK里的占空比颠倒一下,调光数据点越大,duty数值越大,高电平时间在一个周期内时间越大,LED灯越亮),另一个引脚接GND这样就可以实现没有较大电势差了。
if(STA[0]==1) //LED灯开启
{
pwm_duty_init[0]=currentDataPoint.valueDIM*222.22; //currentDataPoint.valueDIM数据点设置范围在0-100
pwm_set_duty(pwm_duty_init[0],0);
pwm_start();
}
else //LED灯关闭
{
pwm_set_duty(0,0);
pwm_start();
}
哈哈哈哈解决。