我小的时候经常和同学做一个游戏,那个时候刚有电子表,电子表有一个计时装置,连续按两下按钮,就会显示出时间间隔,小伙伴们轮流来按,比一比谁按的时间间隔最短。当时玩的也是不亦乐乎,但从来没有想过原理。
后来在实际应用中,遇到了开关量采集这样一个名词,其中的脉冲开关量采集,和当初的小游戏非常相似。
开关量采集一般有电平和脉冲两种类型,电平开关量就是外部信号通断引起电平的高低状态变化,脉冲开关量是外部信号在特殊情况下给出一个或几个周期的脉冲值,一般又分为高脉冲(上升沿有效,下降沿失效)和低脉冲(下降沿有效,上升沿失效)检测。
电平开关两容易检测,只要读取电平值就可以了,脉冲开关量该如何检测呢?常用的方法就是计数法。也就是从有效的上升沿或者下降沿开始,按照固定的周期开始计数(这个周期越短,测量精度就越高),遇到失效沿后立刻停止计数,然后用计数个数乘以周期,得出来有效脉冲的宽度。
如上图所示:如果检测周期是1us,高脉冲的有效值就是1*20=20us
ARDUINO中提供一个方便的函数实现了脉冲该功能:pulseIn(pin, value, timeout);
参数含义:
pin:你要进行脉冲计时的引脚号(int)。
value:要读取的脉冲类型,HIGH或LOW(int)。
timeout (可选):指定脉冲计数的等待时间,单位为微秒,默认值是1秒(unsigned long)
返回值:
脉冲长度(微秒),如果等待超时返回0(unsigned long)。
我们来做个简单电路测试一下,接一个轻触开关在D3和+5V之间,D3再串一个电阻到GND:
根据上图,没有按下开关,D3读数应该是0,按下开关后,读数应该是1。
来看代码:
int pin = 3; //定义引脚为D3
unsigned long duration; //定义duration变量为无符号长整数型变量
void setup()
{
Serial.begin(9600); //串口波特率为9600
pinMode(pin, INPUT); //设置引脚为输入模式
}
void loop()
{
duration = pulseIn(pin, HIGH,60000000); //读取引脚上的高电平脉冲,最大脉冲时间间隔为60秒,并且把结果赋值给duration变量
Serial.println(duration); //每次按下然后抬起开关之后,显示读数值
}
执行上面的代码,每次按下开关持续的时间就会显示出来,和小时候玩的电子表计数非常像哟~