问题描述
我编写了一个反跳类来对输入进行反跳。
这个想法是某个输入的状态可能是ON,OFF,FALLING或RISING。 要以固定的间隔调用object.debounceInputs()
使用函数object.readInput()可以读取对象的正确状态。FALLING或RISING状态仅持续1个间隔时间(通常设置为20ms),并且这些状态只能读取一次。 / p>
我当然对该软件进行了测试,并且该软件无缺陷运行,现在我开始在其他项目中使用该软件,并且发现了一个特殊的错误。
如果您只有一个输入对象,则该软件可以完美运行...如果您对多个对象进行反跳操作,则输入会相互影响,这不可能,因为每个对象都使用私有变量。
源代码:
#include "debounceClass.h"
Debounce::Debounce(unsigned char _pin) {
pinMode(_pin,INPUT_PULLUP); // take note I use a pull-up resistor by default
pin = _pin;
}
unsigned char Debounce::readinput() {
byte retValue = state;
if(state == RISING) state = ON; // take note I use a pull-up resistor
if(state == FALLING) state = OFF; // rising or falling may be returned only once
return retValue;
}
void Debounce::debounceInputs() {
static bool oldSample = false,statePrev = false;
bool newSample = digitalRead(pin);
if(newSample == oldSample) { // if the same state is detected atleast twice in 20ms...
if(newSample != statePrev) { // if a flank change occured return RISING or FALLING
statePrev = newSample ;
if(newSample) state = RISING;
else state = FALLING;
}
else { // or if there is no flank change return pressed or RELEASED
if(newSample) state = ON;
else state = OFF;
}
}
oldSample = newSample;
return 255;
}
相应的头文件:
#include <Arduino.h>
#ifndef button_h
#define button_h
//#define
#define ON 9 // random numbers,RISING and FALLING are already defined in Arduino.h
#define OFF 10
class Debounce {
public:
Debounce(unsigned char _pin);
unsigned char readinput();
void debounceInputs();
private:
unsigned char state;
unsigned char pin;
};
#endif
我在2个独立项目中遇到了这个错误,所以错误肯定出在我的Debounce类中。
用于说明该程序的示例程序:
#include "debounceClass.h"
const int pin3 = 3 ;
const int pin4 = 4 ;
Debounce obj1( pin3 ) ;
Debounce obj2( pin4 ) ;
byte prevIoUsstate1,prevIoUsstate2;
unsigned long prevTime = 0,prevTime1 = 0,prevTime2 = 0;
void setup()
{
Serial.begin( 115200 ) ;
// CONSTRUCTOR OF OBJECTS SETS THE PINMODE TO INPUT_PULLUP
pinMode( pin3,OUTPUT ) ;
pinMode( pin4,OUTPUT ) ;
}
const int interval = 20,interval1 = 1000,interval2 = 2000;
void loop() {
unsigned long currTime = millis() ;
if( currTime > prevTime + interval ) {
prevTime = currTime ;
obj1.debounceInputs(); // comment one of these 2 out,and the other debounces perfectly
obj2.debounceInputs();
#define printState(x) case x: Serial.print(#x); break
byte state = obj1.readinput() ;
if( state != prevIoUsstate1 ) {
prevIoUsstate1 = state ;
Serial.print("state of obj1 = ") ;
switch ( state ) {
printState( ON ) ;
printState( OFF ) ;
printState( RISING ) ;
printState( FALLING ) ;
}
Serial.println();
}
state = obj2.readinput() ;
if( state != prevIoUsstate2 ) {
prevIoUsstate2 = state ;
Serial.print("state of obj2 = ") ;
switch ( state ) {
printState( ON ) ;
printState( OFF ) ;
printState( RISING ) ;
printState( FALLING ) ;
}
Serial.println();
}
}
if( currTime > prevTime1 + interval1 ) {
prevTime1 = currTime ;
digitalWrite( pin3,!digitalRead( pin3 ) );
}
if( currTime > prevTime2 + interval2 ) {
prevTime2 = currTime ;
digitalWrite( pin4,!digitalRead( pin4 ) );
}
}
该程序自动切换两个引脚,因此您不需要物理输入。如果注释掉指示的行中的一条,您会看到另一根销被去抖动了。但是,当两个引脚都去抖动时,结果将是灾难性的。我无法解释这两个对象之间存在一个怪异的联系。我到了开始怀疑编译器的地步,所以那一刻我才意识到我需要问其他人。
为什么会这样,我在这里做错了什么?
解决方法
我发现了问题。
我不能在类方法中使用静态变量。所有导致问题的对象都可以看到这些静态变量。
我将静态变量移到了私有变量部分