Arduino:简单的增量不起作用

时间:2016-01-18 21:58:35

标签: arduino

一个非常简单的代码,但过去两周它一直在杀我。

简单地说:按下按钮增加按状态增加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上的方法。

这里有什么问题?

2 个答案:

答案 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();
  ...

请注意,现在您不需要UpValDownVal,因为阅读功能已在update中完成(因此read功能实际上并不阅读输入。)

只有一句话:你知道你需要在电路板上有一个上拉,不是吗?如果您没有安装上拉,则只需转换pinMode(xxxx,INPUT);中的pinMode(xxxx,INPUT_PULLUP);