亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

自制 Arduino 厨房定时器:LCD 显示、四按键操作、蜂鸣器报警

元器件与材料

Arduino UNO ×1
Adafruit 标准 16x2 LCD (白字蓝底) ×1
按键开关 12mm ×4
电阻 10kΩ (上拉) ×4
电阻 220Ω (蜂鸣器/背光限流) ×2
电位器 100kΩ (LCD 对比度) ×1
蜂鸣器 (有源/无源均可) ×1
面包板 & 跳线 各×1

项目背景

从简单的数字厨房定时器出发,用 Arduino 重造一个“属于自己的”定时器,顺便理解此类小工具的工作原理。核心概念是状态机:定时器同一时刻只处于四种模式之一:

硬件连接要点

核心代码逻辑

按键去抖与长按检测

每个按键用 digitalRead 读取当前状态,与上一次状态对比,变化时标记“按下”。S4(复位键) 额外增加长按计数器:持续 HIGH 超过约 100 个循环周期(约 1 秒) 判定为长按,触发进入 SETUP 模式。

状态机切换

主循环中用 switch(currentMode) 处理四种模式的按键响应:

时间计算与蜂鸣

运行模式下用 now() - startTime 计算已过秒数,从设定总秒数中减去得到剩余时间。剩余 ≤ 0 时切换到 RINGING。响铃模式用 analogWrite(buzzerPin, 20) 配合短延时产生断续鸣叫。

LCD 显示管理

每种模式显示不同内容:待机显示“Timer ready”+ 设定时间;设置显示“Setup mode: HRS/MINS/SECS”+ 当前调整值;运行显示“Counting down...”+ 实时倒计时 HH:MM:SS;响铃显示“RING-RING!”。

完整代码

/**************************************************
 * Arduino Kitchen Timer v1.0 - 2016/01/27
 * By Angelo Fiorillo (Rome, IT) - GPL3+
 **************************************************/
#include <LiquidCrystal.h>
#include <TimeLib.h>  // Paul Stoffregen's Time 库

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int buzzerPin = 10;
const int resetButtonPin = 6;    // S4
const int startStopButtonPin = 7; // S3
const int downButtonPin = 8;      // S2
const int upButtonPin = 9;        // S1

// 设定时间
int setupHours = 0, setupMinutes = 0, setupSeconds = 0;
time_t setupTime = 0;
// 运行时时间
int currentHours = 0, currentMinutes = 0, currentSeconds = 0;
time_t currentTime = 0, startTime = 0, elapsedTime = 0;

// 按键状态变量
int resetButtonState = LOW, startStopButtonState = LOW, upButtonState = LOW, downButtonState = LOW;
int resetButtonPrevState = LOW, startStopButtonPrevState = LOW, upButtonPrevState = LOW, downButtonPrevState = LOW;
bool resetButtonPressed = false, resetButtonLongPressed = false;
bool startStopButtonPressed = false, upButtonPressed = false, downButtonPressed = false;
long resetButtonLongPressCounter = 0;

// 模式常量
const int MODE_IDLE = 0, MODE_SETUP = 1, MODE_RUNNING = 2, MODE_RINGING = 3;
int currentMode = MODE_IDLE;
int dataSelection = 0; // 0=小时, 1=分钟, 2=秒

void setup() {
  lcd.begin(16, 2);
  pinMode(resetButtonPin, INPUT);
  pinMode(startStopButtonPin, INPUT);
  pinMode(upButtonPin, INPUT);
  pinMode(downButtonPin, INPUT);
  pinMode(buzzerPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // 1. 读取并去抖所有按键 (重置按下标志)
  // ... (同源码, 此处省略重复代码, 关键逻辑见上文说明)

  // 2. 状态机处理
  switch(currentMode) {
    case MODE_IDLE:
      if(resetButtonPressed) Reset();
      if(resetButtonLongPressed) currentMode = MODE_SETUP;
      if(startStopButtonPressed) {
        currentMode = (currentMode == MODE_IDLE) ? MODE_RUNNING : MODE_IDLE;
        if(currentMode == MODE_RUNNING) startTime = now();
      }
      break;
    case MODE_SETUP:
      if(resetButtonPressed) { // 退出设置
        setupTime = setupSeconds + 60*setupMinutes + 3600*setupHours;
        currentHours = setupHours; currentMinutes = setupMinutes; currentSeconds = setupSeconds;
        dataSelection = 0; currentMode = MODE_IDLE;
      }
      if(startStopButtonPressed) { dataSelection = (dataSelection + 1) % 3; }
      if(downButtonPressed) { /* 对应 dataSelection 减 */ }
      if(upButtonPressed) { /* 对应 dataSelection 加 */ }
      break;
    case MODE_RUNNING:
      if(startStopButtonPressed || resetButtonPressed) { currentMode = MODE_IDLE; if(resetButtonPressed) Reset(); }
      break;
    case MODE_RINGING:
      if(resetButtonPressed || startStopButtonPressed || downButtonPressed || upButtonPressed) currentMode = MODE_IDLE;
      break;
  }

  // 3. 时间计算与蜂鸣
  switch(currentMode) {
    case MODE_RUNNING:
      currentTime = setupTime - (now() - startTime);
      if(currentTime <= 0) currentMode = MODE_RINGING;
      break;
    case MODE_RINGING:
      analogWrite(buzzerPin, 20); delay(20);
      analogWrite(buzzerPin, 0); delay(40);
      break;
  }

  // 4. LCD 刷新
  lcd.setCursor(0, 0);
  switch(currentMode) {
    case MODE_IDLE:
      lcd.print("Timer ready "); lcd.setCursor(0,1);
      lcd.print(currentHours); lcd.print(" "); lcd.print(currentMinutes); lcd.print(" "); lcd.print(currentSeconds); lcd.print(" ");
      break;
    case MODE_SETUP:
      lcd.print("Setup mode: "); 
      lcd.print(dataSelection==0?"HRS ":dataSelection==1?"MINS":"SECS");
      lcd.setCursor(0,1);
      lcd.print(setupHours); lcd.print(" "); lcd.print(setupMinutes); lcd.print(" "); lcd.print(setupSeconds); lcd.print(" ");
      break;
    case MODE_RUNNING:
      lcd.print("Counting down..."); lcd.setCursor(0,1);
      // 格式化 HH:MM:SS (补零)
      if(hour(currentTime)<10) lcd.print("0");
      lcd.print(hour(currentTime)); lcd.print(":");
      if(minute(currentTime)<10) lcd.print("0");
      lcd.print(minute(currentTime)); lcd.print(":");
      if(second(currentTime)<10) lcd.print("0");
      lcd.print(second(currentTime));
      break;
    case MODE_RINGING:
      lcd.print(" RING-RING! "); lcd.setCursor(0,1); lcd.print(" ");
      break;
  }
  delay(10);
}

void Reset() {
  currentMode = MODE_IDLE;
  currentHours = setupHours; currentMinutes = setupMinutes; currentSeconds = setupSeconds;
}

原理图

原理图展示了按键下拉电阻、LCD 接线、蜂鸣器驱动及电源连接。可使用标准面包板布局,蜂鸣器可置于跳线下方节省空间。

制造工艺

  1. 智能缺水报警器 – DIY植物土壤湿度监测装置
  2. 用 Arduino Nano 和 Nokia 5110 LCD 自制 20kHz 示波器:简易 DIY 指南
  3. 智能窗帘:基于Arduino与太阳能的自动光控系统
  4. 意大利语单词时钟:Arduino Nano + NeoPixel 144 灯珠 + LCD + RTC 打造
  5. 使用 SparkFun 7 段数码管构建可靠的 Arduino 倒计时器
  6. 基于Arduino MKR Fox 1200构建可靠Sigfox千瓦时电表
  7. 蓝牙温度监测仪:Arduino Nano + NTC 热敏电阻 + HC-06 无线传输
  8. 非接触手势门锁:APDS-9960 + Arduino 实现安全门禁
  9. Arduino Nano 多功能伴侣套件 —— 电阻/电容测量、二极管测试、RTC时钟一体化
  10. Arduino Micro/Leonardo USB MIDI 适配器套件 —— 完整元件清单与固件指南
  11. 为Arduino构建隔离模拟输入电路
  12. Arduino UNO 精准视觉反应时间测试仪