闲言碎语
上篇文章里面的一个综合例子里面有用到用tmr模块来模拟pwm输出实现呼吸灯效果。不过,tmr模块最小时间单位是1ms,模拟出来的pwm效果实在是不理想。刚好,nodeMCU有提供pwm模块。这回就来讲讲pwm模块。
模块函数
数了一下,总共有8个函数。单从函数名字上来看,还是很好理解的。让我们快速的过一下。
序号 | 函数名 | 参数 | 返回值 |
---|---|---|---|
1 | pwm.close() | pin | nil |
2 | pwm.getclock() | pin | number |
3 | pwm.getduty() | pin | number |
4 | pwm.setclock() | pin, clock | nil |
5 | pwm.setduty() | pin, duty | nil |
6 | pwm.setup() | pin, clock, duty | nil |
7 | pwm.start() | pin | nil |
8 | pwm.stop() | pin | nil |
- .close用来让一个pin退出pwm模式。pin的范围从1~12。pin_0不支持pwm功能。
- .getclock可以获取一个pin的pwm频率。
- .getduty获取一个pin的占空比。
-
.setclock设置pwm的频率。文档中提到,使用时只能设置一个频率。频率范围从11000。然而,查阅esp8266的技术文档,其中提到频率是从100Hz1KHz。通过,用示波器抓取pwm发现,当参数传入1的时候,pwm的频率就是1Hz;传入1000,则输出1KHz。nodeMCU项目组不知道使用了黑科技,竟然比官方的频率更低。
1Hz的波形
- .setduty用于设置一个pin的占空比。取值范围0~1023。
- .setup设置pin的pwm模式。文档中提到最多支持6个pin同时为pwm模式。
- .start启动pwm输出。
- .stop暂停pwm输出。注意,和.close的区别。
函数很简单,没必要一个一个举例子了。找个RGB的三色led灯,接在pin1~pin3上。我手上的led是共阳的。
pwm.setup(1, 500, 128)
pwm.setup(2, 500, 258)
pwm.setup(3, 500, 512)
pwm.start(1)
pwm.start(2)
pwm.start(3)
接着可以通过使用.setduty手动调节单个led的亮度,数字越大,亮度越低。使用.stop来暂停pwm输出。不过,使用.stop后,发现灯更亮了。说明pwm停止了,pin输出低电平。
有图有真相综合小例子
这次,用pwm来实现上一篇文章实现的呼吸灯。看看效果如何。
pwm.setup(2, 500, 1023)
pwm.start(2)
up = 0
function changeDuty()
local duty = pwm.getduty(2)
if(up == 1) then
if(duty < 900) then
pwm.setduty(2, duty + 1)
else
up = 0
end
else
if(duty > 0) then
pwm.setduty(2, duty - 1)
else
up = 1
end
end
end
tmr.alarm(0, 1, tmr.ALARM_AUTO, changeDuty)
一点问题
在尝试动态调节两路pwm的占空比的时候,这玩意总是重启了。不知道是不支持亮度动态调节,还是程序上有什么BUG。
网友评论
dutyMAX = 1023
dutyMIN = 0
flag = 0
pwm.setup(GPIO_PIN,100,dutyMAX)
pwm.start(GPIO_PIN)
function changeDuty()
local duty = pwm.getduty(GPIO_PIN);
print(duty);
if(flag == 0) then
if (duty > dutyMIN+10) then
pwm.setduty(GPIO_PIN,duty - 10);
else
flag = 1;
end
else
if (duty < dutyMAX-10) then
pwm.setduty(GPIO_PIN,duty + 10);
else
flag = 0;
end
end
end
tmr.alarm(0 , 50 , tmr.ALARM_AUTO , changeDuty);
试试这个
请问还有什么办法提高频率吗?