今天碰到一个爱好者求助,其目的如下:
晃动手中的震动传感器(滚珠式),然后Arduino读取了开关的情况,然后点亮一个LED的呼吸灯。
而实际的情况是,他的呼吸灯调试成功,但是在调震动开关的时候,总是调试不成功。
他的调试代码如下:
=====================
int Led=13;//定义LED 接口
int Shock=7;//定义震动传感器接口
int val;//定义数字变量val
void setup()
{
pinMode(Led,OUTPUT);//定义LED 为输出接口
pinMode(Shock,INPUT);//定义震动传感器为输出接口
}
void loop()
{
val=digitalRead(Shock);//将数字接口7 的值读取赋给val
if(val==HIGH)//当震动传感器检测有信号时,LED 点亮
{
digitalWrite(Led,HIGH);
}
else
{
digitalWrite(Led,LOW);
}
}
===============
初一看,貌似没有问题,也就是digitalRead()函数来读插在IO7口上面的震动传感器的值。
当读取到了震动之后,则立即点亮L灯。
但是,在实际的调试的时候却发现,只要以上电,L灯就点亮了。
问题在哪里?
我也感到好奇,所以,就协助他调试。
调试步骤如下:
我首先让他把震动传感器的S针由IO7转移到A0端口上,
然后用如下的代码进行读取。
=======================
void setup(){Serial.begin(9600);}
void loop(){
Serial.println(analogRead(0);delay(1);}
======================
然后使用串口监视器,得到的情况为:
不管传感器怎么摆放,它的读值始终都在0-1023之间波动。(0和较小的读数表示感受到震动)
而如果晃动它,那么读到0的概率就大很多。
由此,可以确认,这个震动传感器太灵敏了,以至于当它貌似静置的时候,其实,它还是会对哪怕小小的空气流动等因素产生反应。也就是说,如果我们简单的判断这个振动传感器是否感受到震动,那么,它时刻都会感受到震动,简单的开关动作已经无法进行判断。
怎么办?
前面已经说过,如果晃动它,那么读到0的概率就大很多。
那么,如何使得这个概率能够被捕获到呢?
于是我就采用了平均值的方法,即对其进行300次的连续采样,然后根据采样的平均值来判断是否被认为晃动。
测试的代码如下:
==================
int i;
long int all=0;
int pj;
void setup(){pinMode(9,OUTPUT);Serial.begin(9600);}
void loop(){
for(int S=0;S<300;S++){
all=all+analogRead(0);
}
pj=all/300;
Serial.println(pj);
pj=0;
all=0;
}
==============
得到的结果为,如果不晃动传感器,那么它的均值维持在400左右,最低不低于384,而如果晃动,则均值维持在50以下。
由此,问题得到解决。
整个的完整代码如下:
=========================
int i;
long int all=0;
int pj;
void setup(){pinMode(9,OUTPUT);}
void loop(){
for(int S=0;S<300;S++){
all=all+analogRead(0);
}
pj=all/300;
if(pj>0&&pj<50){
for(i=0;i<255;i++){analogWrite(9,i);delay(30);}
for(i=255;i>0;i--){analogWrite(9,i);delay(30);}
}
else{analogWrite(9,0);}
pj=0;
all=0;
}
=========================
结论:对于某些过于“精密”的传感器,当我们并不关心其在某一个时点的状态,或者并不关心其在某一个瞬间的状态的时候。我们可以用算数平均值来进行“滤波”,然后将其一个时段内的平均值作为我们对外界的感知判断。