Dark
  • thứ hai, 23 tháng 9 2024
ESP8266 Và Nút Nhấn Phần 2: Nhấn Nhả - Nhấn Giữ

ESP8266 Và Nút Nhấn Phần 2: Nhấn Nhả - Nhấn Giữ

Tiếp theo bài nút nhấn thì còn 1 vài trạng thái của nút nhấn mà ta hay gặp ở thực tế, bài dưới đây mình hướng dẫn các xác định các trạng thái này.

Short Press - Nhấn Nhả Nhanh

Trước tiên ta phải xác định thời gian nhấn nút thông thường là dưới (SHORT_PRESS_TIME) 500ms cho mỗi lần nhấn. Nếu nhấn nút nhanh dưới thời gian SHORT_PRESS_TIME thì tính là 1 lần nhấn. Ở đây mình sử dụng chân 4 để đọc nút nhấn. 

#define BUTTON_PIN 4          // GIOP4 chân nối nút nhấn
#define SHORT_PRESS_TIME 500  // 500 milliseconds thời gian nhấn

byte lastState = LOW;  // trạng thái cuối
byte currentState;     // trạng thái hiện tại

unsigned long pressedTime = 0;   //tính thời điểm nhấn nút
unsigned long releasedTime = 0;  //tính thời điểm nhả nút

void setup() {
  Serial.begin(115200);      // khai báo để sử dụng Serial
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // khai báo chân 4 là chân đọc với trở kéo lên
  Serial.println("Start Up");
}

void loop() {
  // đọc trạng thái hiện tại của nút nhấn:
  currentState = digitalRead(BUTTON_PIN);

  if (lastState == HIGH && currentState == LOW)         // nhấn nút thay đổi trạng thái trước sau.
    pressedTime = millis();                             // lấy thời điểm nhấn nút
  else if (lastState == LOW && currentState == HIGH) {  // nhả nút
    releasedTime = millis();                            // lấy thời điểm nhả nút

    long pressDuration = releasedTime - pressedTime;  // tính khoảng thời gian nhấn nút rồi nhả

    if (pressDuration < SHORT_PRESS_TIME)  // nếu mà thời gian nhấn nhỏ hơn 500ms thì tính là nhấn nút nhanh
      Serial.println("Nhấn nhả Nhanh");
  }

  // lưu lại trạng thái cuối
  lastState = currentState;
}

Long Press - Nhấn Giữ

Trường hợp 1: Nhấn nút qua 1 giây nhả nút thực hiện lệnh in ra màn hình.

Ta sẽ đo khoảng thời gian từ thời điểm nhấn nút và thời điểm thả nút nếu hơn 1 giây thì tính là nhấn giữ.

#define BUTTON_PIN 4          // GIOP4 chân nối nút nhấn
#define LONG_PRESS_TIME 1000  // 1 second thời gian nhấn

byte lastState = LOW;  // trạng thái cuối
byte currentState;     // trạng thái hiện tại

unsigned long pressedTime = 0;   // thời điểm nhấn nút
unsigned long releasedTime = 0;  // thời điểm nhả nút

void setup() {
  Serial.begin(115200);      // khai báo để sử dụng Serial
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // khai báo chân 5 là chân đọc với trở kéo lên
  Serial.println("Start Up");
}

void loop() {
  // đọc trạng thái hiện tại của nút nhấn:
  currentState = digitalRead(BUTTON_PIN);

  if (lastState == HIGH && currentState == LOW)         // nhấn nút
    pressedTime = millis();                             // lấy thời điểm nhấn nút
  else if (lastState == LOW && currentState == HIGH) {  // nhả nút
    releasedTime = millis();                            // lấy thời điểm nhả nút

    long pressDuration = releasedTime - pressedTime;  // tính khoảng thời gian nhấn nút rồi nhả

    if (pressDuration > LONG_PRESS_TIME)  // nếu mà thời gian nhấn lâu hơn thì tính là nhấn nút
      Serial.println("Nhấn giữ 1s");
  }

  // lưu lại trạng thái cuối
  lastState = currentState;
}

Trường hợp 2:  Nhấn nút giữ nếu qua 2 giây thì thực hiện lệnh in ra màn hình. Nhả nút ra khi chưa đến 2 giây nhấn lại thì bắt đầu tính lại thời gian nhấn giữ.

Ở trường hợp này thì sau khi nhấn nút thì sẽ kiểm tra thời gian liên tục nếu hơn 2 giây thì in ra màn hình 1 lần.

#define BUTTON_PIN 4          // GIOP4 chân nối nút nhấn
#define LONG_PRESS_TIME 2000  // 2 second thời gian nhấn

byte lastState = LOW;  // trạng thái cuối
byte currentState;     // trạng thái hiện tại

unsigned long pressedTime = 0;  // thời điểm nhấn nút

bool isPressing = false;      // cờ đang nhấn
bool isLongDetected = false;  // cờ nhấn giữ

void setup() {
  Serial.begin(115200);      // khai báo để sử dụng Serial
  pinMode(BUTTON_PIN, INPUT_PULLUP);   // khai báo chân 5 là chân đọc với trở kéo lên
  Serial.println("Start Up");
}

void loop() {
  // đọc trạng thái hiện tại của nút nhấn:
  currentState = digitalRead(BUTTON_PIN);

  if (lastState == HIGH && currentState == LOW) {         // khi nhấn nút
    pressedTime = millis();                               // lấy thời điểm nhấn nút
    isPressing = true;                                    // bật cờ đang nhấn
    isLongDetected = false;                               // tắt cờ nhấn giữ
  } else if (lastState == LOW && currentState == HIGH) {  // nếu thả nút
    isPressing = false;                                   // tắt cờ đang nhấn (đang không nhấn nút)
  }

  if (isPressing == true && isLongDetected == false) {  // nếu đang nhấn nút và cờ nhấn giữ chưa kích hoạt
    long pressDuration = millis() - pressedTime;        // tính thời gian nhấn nhấn giữ liên tục

    if (pressDuration > LONG_PRESS_TIME) {  // nếu thời gian nhấn lâu hơn 2s thì tính là nhấn giữ
      Serial.println("Đã nhấn hơn 2s");     // in ra màn hình
      isLongDetected = true;                // bật cờ nhấn giử khi thả nút nhấn lại mới vào lại được đây.
    }
  }

  // lưu lại trạng thái cuối
  lastState = currentState;
}

Kết hợp nhấn nhả và nhấn giữ

Trường hợp 1: Kích hoạt in ra màn hình nhấn giữ hoặc nhấn nhả sau khi buông nút nhấn. 

#define BUTTON_PIN 4           // GIOP4 chân nối nút nhấn
#define SHORT_PRESS_TIME 1000  // 1000 milliseconds
#define LONG_PRESS_TIME 1000   // 1000 milliseconds

byte lastState = LOW;  // trạng thái cuối
byte currentState;     // trạng thái hiện tại

unsigned long pressedTime = 0;
unsigned long releasedTime = 0;

void setup() {
  Serial.begin(115200);               // khai báo để sử dụng Serial
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // khai báo chân 5 là chân đọc với trở kéo lên
  Serial.println("Start Up");
}

void loop() {
  // đọc trạng thái hiện tại của nút nhấn:
  currentState = digitalRead(BUTTON_PIN);

  if (lastState == HIGH && currentState == LOW)         // nhấn nút thay đổi trạng thái trước sau.
    pressedTime = millis();                             // lấy thời điểm nhấn nút
  else if (lastState == LOW && currentState == HIGH) {  // nhả nút
    releasedTime = millis();                            // lấy thời điểm nhả nút

    long pressDuration = releasedTime - pressedTime;  // tính khoảng thời gian nhấn nút rồi nhả

    if (pressDuration < SHORT_PRESS_TIME) // nếu khoảng thời gian nhấn nhả dưới 1s thì là nhấn nhanh
      Serial.println("Nhấn nhả nhanh");

    if (pressDuration > LONG_PRESS_TIME)// nếu khoảng thời gian nhấn nhả trên 1s thì là nhấn giữ
      Serial.println("Nhấn giữ");
  }

  // lưu lại trạng thái cuối
  lastState = currentState;
}

Trường hợp 2: kích hoạt in ra màn hình khi nhấn nhả nhanh hoặc nếu nhấn giữ quá 2s thì in ra màn hình

#define BUTTON_PIN 4           // GIOP4 chân nối nút nhấn
#define SHORT_PRESS_TIME 1000  // 1000 milliseconds
#define LONG_PRESS_TIME 2000   // 1000 milliseconds

byte lastState = LOW;  // trạng thái cuối
byte currentState;     // trạng thái hiện tại

unsigned long pressedTime = 0;
unsigned long releasedTime = 0;
bool isPressing = false;
bool isLongDetected = false;

void setup() {
  Serial.begin(115200);               // khai báo để sử dụng Serial
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // khai báo chân 5 là chân đọc với trở kéo lên
  Serial.println("Start Up");
}

void loop() {
  // đọc trạng thái hiện tại của nút nhấn:
  currentState = digitalRead(BUTTON_PIN);

  if (lastState == HIGH && currentState == LOW) {         // khi nhấn nút
    pressedTime = millis();                               // lấy thời điểm nhấn nút
    isPressing = true;                                    // bật cờ đang nhấn
    isLongDetected = false;                               // tắt cờ nhấn giữ
  } else if (lastState == LOW && currentState == HIGH) {  // nếu thả nút
    isPressing = false;                                   // tắt cờ đang nhấn (đang không nhấn nút)

    // tính cho nhấn nhả nhanh
    releasedTime = millis();

    long pressDuration = releasedTime - pressedTime;

    if (pressDuration < SHORT_PRESS_TIME)
      Serial.println("Nhấn nhả nhanh");
    // tính cho nhấn nhả nhanh
  }

  if (isPressing == true && isLongDetected == false) {  // nếu đang nhấn nút và cờ nhấn giữ chưa kích hoạt
    long pressDuration = millis() - pressedTime;        // tính thời gian nhấn nhấn giữ liên tục

    if (pressDuration > LONG_PRESS_TIME) {  // nếu thời gian nhấn lâu hơn 2s thì tính là nhấn giữ
      Serial.println("Đã nhấn hơn 2s");     // in ra màn hình
      isLongDetected = true;                // bật cờ nhấn giử khi thả nút nhấn lại mới vào lại được đây.
    }
  }
  // lưu lại trạng thái cuối
  lastState = currentState;
}

Đếm lần nhấn nút

Trên đây mình đã hướng dẫn các bạn cách đọc các trạng thái nút nhấn giữ và nhấn nhả, để kết thúc bài hôm nay thì mình sẽ làm 1 ví dụ về đếm số lần nhấn nút và bật đèn led theo số lần nhấn nút. 

#define BUTTON_PIN 4          // GIOP4 chân nối nút nhấn
#define SHORT_PRESS_TIME 500  // 500 milliseconds thời gian nhấn

#define LED_1_PIN 5   // GIOP5 chân nối led
#define LED_2_PIN 12  // GIOP12 chân nối led
#define LED_3_PIN 13  // GIOP13 chân nối led

byte lastState = LOW;  // trạng thái cuối
byte currentState;     // trạng thái hiện tại
byte countButtonPress = 0;
unsigned long pressedTime = 0;   // thời điểm nhấn nút
unsigned long releasedTime = 0;  // thời điểm nhả nút

void setup() {
  Serial.begin(115200);               // khai báo để sử dụng Serial
  pinMode(BUTTON_PIN, INPUT_PULLUP);  // khai báo chân 5 là chân đọc với trở kéo lên

  pinMode(LED_1_PIN, OUTPUT);  // khai báo chân 5 là chân ra led 1
  pinMode(LED_2_PIN, OUTPUT);  // khai báo chân 12 là chân ra led 2
  pinMode(LED_3_PIN, OUTPUT);  // khai báo chân 13 là chân ra led 3

  digitalWrite(LED_1_PIN, LOW);  // Tắt led 1
  digitalWrite(LED_2_PIN, LOW);  // Tắt led 2
  digitalWrite(LED_3_PIN, LOW);  // Tắt led 3

  Serial.println("Start Up");
  Serial.println("Count Button Press: " + String(countButtonPress));
}

void loop() {
  // đọc trạng thái hiện tại của nút nhấn:
  currentState = digitalRead(BUTTON_PIN);

  if (lastState == HIGH && currentState == LOW)         // nhấn nút
    pressedTime = millis();                             // lấy thời điểm nhấn nút
  else if (lastState == LOW && currentState == HIGH) {  // nhả nút
    releasedTime = millis();                            // lấy thời điểm nhả nút

    long pressDuration = releasedTime - pressedTime;  // tính khoảng thời gian nhấn nút rồi nhả

    if (pressDuration < SHORT_PRESS_TIME) {
      countButtonPress++;  // mỗi lần nhấn tăng countButtonPress 1 đơn vị

      if (countButtonPress == 1) {
        digitalWrite(LED_1_PIN, HIGH);  // Bật led 1
        Serial.println("Bật Led: " + String(countButtonPress));
      } 
      else if (countButtonPress == 2) {
        digitalWrite(LED_2_PIN, HIGH);  // Bật led 2
        Serial.println("Bật Led: " + String(countButtonPress));
      } 
      else if (countButtonPress == 3) {
        digitalWrite(LED_3_PIN, HIGH);  // Bật led3
        Serial.println("Bật Led: " + String(countButtonPress ));
      } 
      else if (countButtonPress > 3) {  // nếu nhấn trên 3 lần thì reset lại giá trị countButtonPress
        countButtonPress = 0;
        digitalWrite(LED_1_PIN, LOW);  // Tắt led 1
        digitalWrite(LED_2_PIN, LOW);  // Tắt led 2
        digitalWrite(LED_3_PIN, LOW);  // Tắt led 3
        Serial.println("Reset Count Button Press: " + String(countButtonPress));
      }
    }
  }

  // lưu lại trạng thái cuối
  lastState = currentState;
}

Bình luận / Trả lời