一个非常简单的代码,但过去两周它一直在杀我。
简单地说:按下按钮增加按状态增加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,则State可以变为向下的任何值,例如-6 -2或-10。这也是随机的。
我没有包含的代码中唯一的主要部分是输出到我的20,4 LCD上的方法。
这里有什么问题?
答案 0 :(得分:1)
您还没有提供有关您的设置的足够信息,但这看起来像是按钮弹跳的常见问题。按下物理按钮将导致引脚上的信号反弹(电压上下跳动。)有多种方法可以解决这个问题。尝试在开关去抖动时阅读此article以便更好地理解。
你可以在软件和硬件上去抖。作为一个简单的测试,我打赌如果你放慢你的循环,它会更稳定。
答案 1 :(得分:-1)
您的问题是您想要在按钮的FALLING边缘触发状态更改,而不是在按钮为LOW时触发状态。
在你的情况下,当循环函数"循环"并且您仍然按住按钮它将再次递增/递减该值。这不是你想要的。
因此,您希望查找转换的下降沿。您应该保存旧状态,然后将其与当前状态进行比较:
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位的 - 即整数)。
现在,一旦你解决了这个问题,你会注意到通常你会得到充满活力的"联系人(即每次都会获得几个增量)。在谷歌上搜索以了解什么是去抖动以及为什么需要它。
但是,对于您的应用程序,我建议您使用Bounce2库,它非常易于使用。请参阅the page on the Arduino website以获取下载链接以及如何安装。
无论如何,对于你的问题,这可以是代码
#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);
。