上周的课程我们熟悉了arduino的一些基本的操作,主要熟悉的是数字端口的设置(pinMode)和写操作(digitalWrite)。其实对于一个控制系统而言,必须至少有三部分,第一部分为输入,第二部分处理,第三部分为输出,即(input,output,processing)。
根据这样的标准来说,我们上周的流水灯仅仅是可以输出的一个装置,还算不得可以交互的系统,本周我们重点来了解arduino的输入时如何实现的。我们仍然通过流水灯来呈现其实现过程。
一、可以开关的LED灯
这个实验要实现的是按下开关按钮流水灯才开始工作,再次按下按钮则停止流水灯。实物接线图如下:
int btnPressCount=0;
void setup() {
// put your setup code here, to run once:
pinMode(10,OUTPUT);
pinMode(1,INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
if(digitalRead(1)==HIGH)
btnPressCount++;
if(btnPressCount%2)
digitalWrite(10,HIGH);
else
digitalWrite(10,LOW);
}
这里注意,我们采用计数然后取余的方式记录是开或关,来达到控制的目的,但这样的电路有的时候是不稳定的,我们会发现手稍稍抖动就会计数,按一下计数几次的情形就出现了。我们可以通过软件算法或者硬件来避免这样的情况。
2、简单的防抖算法
下面的代码就进行了最简单的防抖,相比上面的代码其实就是在loop的第一句加上了一个延迟500毫秒delay(500),别小看这个延迟语句,在我们从容的按键的时候程序变的非常稳定。
int btnPressCount=0;
void setup() {
// put your setup code here, to run once:
pinMode(10,OUTPUT);
pinMode(1,INPUT);
digitalWrite(10,HIGH);
digitalWrite(1,HIGH);
}
void loop() {
// put your main code here, to run repeatedly:
delay(500); //去抖动作用
if(digitalRead(1)==LOW)
btnPressCount++;
if(btnPressCount%2)
digitalWrite(10,LOW);
else
digitalWrite(10,HIGH);
}
我们可以想见一下,loop运行非常之快,都在微妙级以下,那么我们的按钮手动动作基本都在200毫秒以上一次,所以我们按一下,digitalRead将读到无数次的low信号。所以我们这加入延迟半秒,这样基本保证了在按钮按下和弹起的这一段时间内loop只循环了一次。这样我们的计数就准确了(当然,如果我们按键时间过长也会导致多次计数)。
二、可以控制花样的流水灯
有了上面的btnPressCount后我们则可以引入更多的控制花样了,比如我们接下来要实现的流水灯花样,
loop(){
if(btnPressCount%2)
fun1();
if(btnPressCount%3)
fun2();
}
//流水灯花样1
void fun1()
{
}
//流水灯花样2
void fun2()
{
}
//流水灯花样3
void fun3()
{
}
我们可能发现,上面的代码在前三次是可以准确实现花样切换,但一旦超过6次就会出现问题,问题就出在取余运算上,6能够被2和3同时除尽,至于8,9,10等数那就有更多的取余数了。所以我们可以通过switch~case选择语句来完成,大致代码改进如下:
int btPressCount=0;
void setup() {
// put your setup code here, to run once:
pinMode(10,OUTPUT);
pinMode(1,INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
if(digitalRead(1)==HIGH)
btPressCount++;
switch(btPressCount)
{
case 1:
fun1();
break;
case 2:
fun2();
break;
case 3:
fun2();
break;
default:
btPressCount=0;
break;
}
}
//流水灯花样1
void fun1()
{
}
//流水灯花样2
void fun2()
{
}
//流水灯花样3
void fun3()
{
}
上面我们没有具体完成每个花样的具体代码,但其思路已经非常具体了。听过本周的课程,我们了解了arduino如何接收输入方面的内容,以及C++中的switch语句的用法(对比if~else)的优点。