一段非常简单的代码,但在过去的两周里它一直在折磨我。
简单地说:按1按增量状态,按1按递减状态。
...
boolean ButtonPress;
const int PinUp = 3;
const int PinDown = 2;
int UpVal = 0;
int DownVal = 0;
int State = 0;
void setup()
{
pinMode(PinUp, INPUT);
pinMode(PinDown, INPUT);
}
void loop()
{
UpVal = digitalRead(PinUp);
DownVal = digitalRead(PinDown);
if(DownVal == HIGH && UpVal == LOW)
{
lcd.clear();
State++;
ButtonPress = true;
}
if(UpVal == HIGH && DownVal == LOW)
{
lcd.clear();
State--;
ButtonPress = true;
}
if(ButtonPress == true)
{
lcd.setCursor(10, 0);
lcd.print("State = ");
lcd.setCursor(18, 0);
lcd.print(State);
}
}
问题是,递增或递减会急剧地跳到一个看似随机的数字。
如果状态是1,我增加,而不是2,状态可以变成任何向上的东西,比如5,13或9,这是随机的。
同样地,如果我从1减少,而不是0,状态可以变成任何向下的东西,比如-6-2或者- 10,这也是随机的。
我没有包括的代码的唯一主要部分是输出到我的20,4液晶显示器的方法。
这里怎么了?
发布于 2016-01-18 22:06:27
您还没有提供足够的关于您的设置的信息,但这似乎是一个常见的问题做按钮反弹。当按下物理按钮时,会使引脚上的信号反弹(电压上下跳跃)。处理这个问题的方法有很多种。试着阅读这个开关上的文章,以便更好地理解。
你可以在软件和硬件两方面都击退。作为一个简单的测试,我敢打赌,如果你放慢你的循环,它将是更稳定的。
发布于 2016-01-19 14:58:22
您的问题是,您希望在按钮下降的边缘触发状态更改,而不是在按钮低时触发状态更改。
在您的情况下,当循环函数“循环”并且仍然按住按钮时,它将再次增加/减少值。这不是你想要的。
因此,您需要寻找过渡的下降边缘。您应该保存旧状态,然后将其与当前状态进行比较:
byte UpVal = 0;
byte oldUpVal = 0;
byte DownVal = 0;
byte oldDownVal = 0;
void loop()
{
UpVal = digitalRead(PinUp);
DownVal = digitalRead(PinDown);
if(DownVal == HIGH && oldUpVal == HIGH && UpVal == LOW)
{
lcd.clear();
State++;
ButtonPress = true;
}
if(UpVal == HIGH && oldDownVal == HIGH && DownVal == LOW)
{
lcd.clear();
State--;
ButtonPress = true;
}
oldUpVal = UpVal;
oldDownVal = DownVal;
...
(顺便说一下,请使用8位变量--即字节--而不是16位变量--即ints)。
现在,一旦您修复了这个问题,您就会注意到,通常您会得到“有弹性”的联系人(也就是说,每次您会得到几个增量)。在google上搜索,了解什么是被取消的,为什么需要它。
但是,对于您的应用程序,我建议您使用Bounce2库,它非常容易使用。请参阅Arduino网站上的页面以获取下载链接以及如何安装它。
无论如何,对于您的问题,这可能是代码
#include <Bounce2.h>
byte oldUpVal = 0;
byte oldDownVal = 0;
Bounce debouncerUp = Bounce();
Bounce debouncerDown = Bounce();
void setup() {
pinMode(PinUp,INPUT);
pinMode(PinDown,INPUT);
debouncerUp.attach(PinUp);
debouncerUp.interval(5);
debouncerDown.attach(PinDown);
debouncerDown.interval(5);
...
}
void loop()
{
debouncerUp.update();
debouncerDown.update();
if(debouncerDown.read() == HIGH && oldUpVal == HIGH && debouncerUp.read() == LOW)
{
lcd.clear();
State++;
ButtonPress = true;
}
if(debouncerUp.read() == HIGH && oldDownVal == HIGH && debouncerDown.read() == LOW)
{
lcd.clear();
State--;
ButtonPress = true;
}
oldUpVal = debouncerUp.read();
oldDownVal = debouncerDown.read();
...
注意,现在不需要UpVal
和DownVal
,因为读取函数是在update
中完成的(因此read
函数实际上并不读取输入)。
我只想说一句:你知道你需要在董事会上拉一拉,不是吗?如果没有挂载拉出,则只需将pinMode(xxxx,INPUT);
转换为pinMode(xxxx,INPUT_PULLUP);
。
https://stackoverflow.com/questions/34864811
复制相似问题