如何添加跟踪器来查看按钮被按下的次数?

问题描述 投票:0回答:1

我正在尝试制作一个简单的计数器项目只是为了好玩。我已经掌握了主要功能,但现在我想添加一些额外的花招。这是一个 Arduino 项目,这就是我正在使用的:一个 LCD 显示屏、一个按钮和一个红色 LED。基本上,我想要的只是让 LCD 打印出按钮被按下的次数,一旦超过某个“限制”,我希望启动“警告阶段”,这只是一个 LED 亮起眨眼,我就得到了这一切。但我现在需要的是一种将LCD计数器“重置”为0,并关闭LED的方法;一种覆盖系统。我想要执行此操作的方法是单击按钮两次(与原始计数器使用的按钮相同),然后这将解除“警告阶段”。但我只希望在警告阶段启动后覆盖系统可用。我试图制作一个跟踪器来查看警告阶段后按钮被按下的次数,但我无法弄清楚如何实现。有人可以帮忙吗?谢谢!

这是我到目前为止的代码。我留下了其中的一些部分供将来参考,但这些应该被注释掉。任何帮助将不胜感激!

#define BUTTON_PIN 2
#define RED_LED_PIN 10

#include <LiquidCrystal.h>
#define LCD_RS_PIN A5
#define LCD_E_PIN A4
#define LCD_D4_PIN 6
#define LCD_D5_PIN 7
#define LCD_D6_PIN 8
#define LCD_D7_PIN 9

LiquidCrystal lcd(
    LCD_RS_PIN,
    LCD_E_PIN,
    LCD_D4_PIN,
    LCD_D5_PIN,
    LCD_D6_PIN,
    LCD_D7_PIN
);

int cursorLine = 0; // I don't think I need this.
int counter = 0;
int tracker = 0;

void trackerye() { // (purposely named that).
    if (counter > 5) {
        tracker++; // <-- This is wrong.
    }
    if (tracker > 2) {
        counter == 0;
    }
}

void crazy() {
    digitalWrite(RED_LED_PIN, HIGH);
    delay(300);
    digitalWrite(RED_LED_PIN, LOW);
    delay(300);
}

void setup() {
    pinMode(BUTTON_PIN, INPUT);
    pinMode(RED_LED_PIN, OUTPUT);
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    // Serial.begin(9600);
}

void loop() {
    if (digitalRead(BUTTON_PIN) == HIGH) {
        counter++;
        delay(200);
    }
    lcd.setCursor(0, 1);
    lcd.print("Times Opened: ");
    lcd.print(counter);

    if (counter > 3) {
        crazy();
        lcd.setCursor(0, 0);
        lcd.print("OVER MAX LIMIT");
        trackerye();
    }
}

我尝试添加不同的 if 语句等,但没有成功。我尝试了 tracker++ 的东西,但很快意识到这也是错误的,如上所述,现在需要帮助,因为我被卡住了。

c arduino counter
1个回答
0
投票

正如其他人指出的那样,当连续按下按钮时,您需要“消除弹跳”,即忽略它。您当前执行此操作的延迟为 200 毫秒,但如果按下时间更长会怎样?

另一个建议是,在计数器超过一定限制后,不要按两次,而是长按(例如 5 秒),这就是当今大多数事情的工作方式,您需要重置某些内容,按住按钮一段时间同时它就做到了。

另外,尽量避免使用delay()函数,它会阻塞你的代码,所以如果你需要做其他事情,它就不会发生。这是您正在构建的一个简单的东西,但如果您开始制造更复杂的设备并添加更多功能,它会在背面咬您。

这是一个如何编写代码并保持“非阻塞”的简单示例,当然还有很多东西要写,但是一旦您习惯使用 millis() 和变量来跟踪循环中的时间()安排事情你会有更好的流程。

我只添加了循环中的位和之前的一些内容,因此根据您的需要对其进行自定义,逻辑是按钮按下将仅执行一次,除非您处于“重置模式”,并且按钮向上将仅执行一次除非你处于“疯狂”眨眼模式。

///...add whatever your need before 

unsigned long blink_timer = 0;
unsigned long reset_timer = 0;
int reset_after = 5000; //the reset when enabled will happen after holding the button for 5 seconds
bool can_reset = false; // flags when the max counter is exceeded so the counter can be reset
bool can_press = true; //does the de-bouncing, basically blocks the counting if the button is constantly pressed
bool button_up_done = true;

int counter = 0;
int max_count = 5; // after this counter value we can reset the counter with a long press
int blink_after = 2; // the led will blink when the counter goes over this value
int blink_state = LOW;

void setup(){
    //...whatever you need here
}
//show the info on the screen
void showInfo(){
    lcd.setCursor(0, 1);
    lcd.print("Times Opened: ");
    lcd.print(counter);
}

void loop() {


    ///anything before or after this IF block will work without blocking
    if(digitalRead(BUTTON_PIN) == HIGH && (can_press == true || can_reset == true){
        
       can_press = false; // ignore anything whilst the button is kept being pressed unless we are in the reset mode
       button_up_done = false; //get ready for the button release

       if(can_reset == true){ //we are in the reset mode
            if(millis() - reset_timer >= reset_after){
                counter = 0;
                can_reset = false;
                reset_timer = 0;
            }
       }else{
            //we have reached the max and next long press will reset the counter
            // note: we are not resetting the counter yet so it will keep counting on button up
            if(counter == max_count){
                can_reset = true;
                reset_timer = millis(); //remember current time
    
            }
       }

    }else if(button_up_done == false){ //the button is released and we will only execute this once

        if(can_reset == true){
           reset_timer = millis();
        }

        if(counter > blink_after){ //we are in the "crazy" mode
            if(millis() - blink_timer > 300){
                if(blink_state == LOW){
                    showInfo(); //show the info on the screen
                    counter++;

                    digitalWrite(RED_LED_PIN, HIGH);
                    blink_state == HIGH;
                }else{
                    digitalWrite(RED_LED_PIN, LOW);
                    blink_state == LOW;

                    button_up_done = true; // we have finished with the blinking so ignore the button up
                    can_press = true; // we can listen to the button press
                }
                blink_timer = millis()
            }
        }else{ //we haven't reached the "crazy" mode yet
            counter++;
            showInfo(); //show the info on the screen
            state_up_done = true; // we have finished with the button up
            can_press = true; // we can listen to the button press
        }
    }

}

我写得很快,还没有在设备上测试它,它更多的是如何构建代码的粗略示例。它有点大 if 语句,可以通过调用单独的函数分成更小的块,但这样可能更容易理解。

© www.soinside.com 2019 - 2024. All rights reserved.