2025年8月8日 星期五

紅外線計數器 | 使用紅外線感測器計數任何物體並顯示在液晶顯示器上 程式碼

IR Counter | Count Any Object Using IR Sensor & Displayed On LCD  

程式碼

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

// --- 定義硬體連接 ---

const byte IR_PIN = 2; // 強烈建議使用官方支援的中斷腳位 2 3 // 2 OR 3 是使用 Arduino UNO

const byte LCD_ADDRESS = 0x27;

const byte LCD_COLUMNS = 16;

const byte LCD_ROWS = 2;

// --- LCD 物件初始化 ---

LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);

// --- 變數 ---

volatile bool objectDetected = false; // 中斷旗標,ISR只會設定它

unsigned long count_value = 0;

unsigned long lastTriggerTime = 0;

unsigned long debounceDelay = 100; // 消抖延遲可以稍微加長一點,更穩定

unsigned long lastLCDUpdateTime = 0;

const long LCD_UPDATE_INTERVAL = 500; // 可以縮短更新間隔,反應更即時

// --- 函數原型宣告 ---

void irSensorTriggered();

void setup() {

  Serial.begin(9600);

  Serial.println("IR Counter Starting...");

  lcd.init();

  lcd.backlight();

  lcd.clear();

  pinMode(IR_PIN, INPUT_PULLUP);

  // 記得根據你的感測器修改 FALLING RISING

  attachInterrupt(digitalPinToInterrupt(IR_PIN), irSensorTriggered, FALLING);

  // 初始顯示

  lcd.setCursor(0, 0);

  lcd.print("Count:");

}

void loop() {

  // --- 處理中斷觸發事件 ---

  if (objectDetected) {

    // 檢查消抖時間

    if (millis() - lastTriggerTime > debounceDelay) {

      count_value++; // 計數器增加

      lastTriggerTime = millis(); // 更新上次有效觸發的時間

      // 在計數增加時立即更新一次LCD,而不是等待固定間隔

      lcd.setCursor(7, 0);

      lcd.print("         "); // 清除舊數字

      lcd.setCursor(7, 0);

      lcd.print(count_value);

    }

    objectDetected = false; // 處理完畢,重置旗標

  }

  // 你也可以保留一個定時更新的邏輯,以防萬一

  if (millis() - lastLCDUpdateTime > LCD_UPDATE_INTERVAL) {

      lastLCDUpdateTime = millis();

      lcd.setCursor(7, 0);

      lcd.print("         ");

      lcd.setCursor(7, 0);

      lcd.print(count_value);

  }

}

// --- 中斷服務常式 (ISR) ---

// ISR 盡可能簡短!只做一件事:設定旗標

void irSensorTriggered() {

  objectDetected = true;

}


沒有留言:

張貼留言