引用外部函式庫:OneButton、Grove 4-Digit Display

Arduino的OneButton Library是一個非常實用的工具,可以用來輕鬆處理按鈕的多種操作,例如:單擊、雙擊、長按等。對於需要處理多種按鈕輸入模式的應用場景非常方便。

#include <OneButton.h>         // 引用OneButton函式庫
#define pb 34                  // 定義按鈕引腳
OneButton button(pb, true);    // 建立OneButton物件,名稱為button,按鈕為低態動作

void setup() {
  Serial.begin(9600);                           // 啟用串列埠監看視窗
  button.attachClick(singleClick);              // 單擊
  button.attachDoubleClick(doubleClick);        // 雙擊
  button.attachLongPressStart(longPressStart);  // 長按開始
  button.attachDuringLongPress(longPress);      // 長按過程中
  button.attachLongPressStop(longPressStop);    // 長按結束
}

void loop() {
  button.tick(); // 定期偵測按鈕狀態
}

// 單擊處理
void singleClick() {
  Serial.println("Button Click.");
}

// 雙擊處理
void doubleClick() {
  Serial.println("Button Double Click.");
}

// 長按開始
void longPressStart() {
  Serial.println("Button Long Press Start.");
}

// 長按過程中
void longPress() {
  Serial.println("Button Long Press ......");
}

// 長按結束
void longPressStop() {
  Serial.println("Button Long Press Stop.");
}

Grove 4-Digit Display 是一個函式庫,可以驅動TM1637晶片所建構的4位元七段顯示器模組,能快速簡單的顯示數字(0-9)和某些字母(A, b, C, d等)。

//-----------------------------------------------------------------------------
#include "TM1637.h"            // 引用TM1637函式庫,並定義TM1637接腳
#define CLK 22                 // CLK為時脈接腳
#define DIO 23                 // DIO為資料接腳
TM1637 tm1637(CLK, DIO);       // 創立一個TM1637物件,名稱為tm1637
//-----------------------------------------------------------------------------
int num[4] = {0, 0, 0, 0};     // 4位數字陣列 {仟位,百位,十位,個位}
int count = 1234;
//-----------------------------------------------------------------------------

void setup() {
  //----------------------------------------------------------
  Serial.begin(9600);  // 啟用串列埠監看視窗
  //----------------------------------------------------------
  tm1637.init();               // 初始化TM1637
  tm1637.set(BRIGHT_TYPICAL);  // 設定亮度,範圍是0到7,預設值為2
  //----------------------------------------------------------
}

void loop() {
  //----------------------------------------------------------
  // 設定與轉換七段顯示器每個位元要顯示的數字
  num[0] = count / 1000 % 10;   // 千位
  num[1] = count / 100 % 10;    // 百位
  num[2] = count / 10 % 10;     // 十位
  num[3] = count % 10;          // 個位
  tm1637.display(0, num[0]);    // 顯示第一位
  tm1637.display(1, num[1]);    // 顯示第二位
  tm1637.display(2, num[2]);    // 顯示第三位
  tm1637.display(3, num[3]);    // 顯示第四位
  //----------------------------------------------------------
}

結合上述2個Library的參考程式如下:

//-----------------------------------------------------------------------------
#include <OneButton.h>         // 引用OneButton函式庫
#define pb 34                  // 定義按鈕引腳
OneButton button(pb, true);    // 建立OneButton物件,名稱為button,按鈕為低態動作
//-----------------------------------------------------------------------------
#include "TM1637.h"            // 引用TM1637函式庫,並定義TM1637接腳
#define CLK 22                 // CLK為時脈接腳
#define DIO 23                 // DIO為資料接腳
TM1637 tm1637(CLK, DIO);       // 創立一個TM1637物件,名稱為tm1637
//-----------------------------------------------------------------------------
int num[4] = {0, 0, 0, 0};     // 4位數字陣列 {仟位,百位,十位,個位}
int count = 5678;
//-----------------------------------------------------------------------------

void setup() {
  //----------------------------------------------------------
  Serial.begin(9600);  // 啟用串列埠監看視窗
  //----------------------------------------------------------
  button.attachClick(singleClick);              // 單擊
  button.attachDoubleClick(doubleClick);        // 雙擊
  button.attachLongPressStart(longPressStart);  // 長按開始
  button.attachDuringLongPress(longPress);      // 長按過程中
  button.attachLongPressStop(longPressStop);    // 長按結束
  //----------------------------------------------------------
  tm1637.init();               // 初始化TM1637
  tm1637.set(BRIGHT_TYPICAL);  // 設定亮度,範圍是0到7,預設值為2
  //----------------------------------------------------------
}

void loop() {
  //----------------------------------------------------------
  button.tick(); // 定期偵測按鈕狀態
  //----------------------------------------------------------
  // 設定與轉換七段顯示器每個位元要顯示的數字
  num[0] = count / 1000 % 10;   // 千位
  num[1] = count / 100 % 10;    // 百位
  num[2] = count / 10 % 10;     // 十位
  num[3] = count % 10;          // 個位
  tm1637.display(0, num[0]);    // 顯示第一位
  tm1637.display(1, num[1]);    // 顯示第二位
  tm1637.display(2, num[2]);    // 顯示第三位
  tm1637.display(3, num[3]);    // 顯示第四位
  //----------------------------------------------------------
}

// 單擊處理
void singleClick() {
  Serial.println("Button Click.");
}

// 雙擊處理
void doubleClick() {
  Serial.println("Button Double Click.");
}

// 長按開始
void longPressStart() {
  Serial.println("Button Long Press Start.");
}

// 長按過程中
void longPress() {
  Serial.println("Button Long Press ......");
}

// 長按結束
void longPressStop() {
  Serial.println("Button Long Press Stop.");
}

作業練習:請改用OneButton Library、Grove 4-Digit Display Library完成上週的作業。

  1. 開機後,4位元七段顯示器顯示欲倒數計時的初始時間(例:1200代表12:00,時間12:00→11:59→11:58→……→11:01→11:00→10:59→……→00:00)。
  2. 每按一下按鈕開關,可開始或停止倒數計數(每秒減1,直到0000停止)。
  3. 長按按鈕開關,計數器重置為初始時間。
  4. 任何過程中,可以透過監看視窗改變倒數計時的數值。(輸入範圍0000~5959)
  5. 七段顯示器的狀態必須同步顯示在監看視窗上。
  6. 請完成實體接線。
  7. 請在Wokwi網站模擬後,並完成實體接線。