#include <LiquidCrystal.h>
//LCD引脚配置(RS, EN, D4, D5, D6, D7)
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
//引脚定义
const int trigPin = 8;
const int echoPin = 9;
const int buzzer = 10;
const int led = 11;
const int button = 12;
//状态变量
unsigned long timer = 0; //记录检测到物体之后的时间戳
byte alertStage = 0; //警报等级:0-正常 1-提醒 2-灯光 3-蜂鸣
bool lastState = false; //保存上一次是否检测到物体的状态(true或false)
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(buzzer, OUTPUT);
pinMode(led, OUTPUT);
pinMode(button, INPUT_PULLUP); //默认高电平,按下时为低电平
lcd.begin(16, 2); //初始化LCD,设置为16列2行的显示
lcd.clear(); //清空LCD屏幕
}
//开关设置
void loop() {
float distance = getDistance(); //调用getDistance()函数测量当前物体的距离
bool btnPressed = !digitalRead(button); //读取开关状态,表示开关被按下
if (btnPressed) { //如果被按下
resetAlarm(); //重置警报状态
lcd.clear(); //清空LCD屏幕
return; //不再执行后面代码
}
//主逻辑
if (distance < 10 && distance > 0) { //如果测量的距离小于10cm且大于0
if (!lastState) { //如果上一次还没检测到物体
timer = millis(); //记录下检测到物体的时间,单位毫秒
lastState = true; //表示检测到了物体
}
unsigned long duration = millis() - timer; //计算物体出现的持续时间
//根据时间长度设置警告级别
alertStage = (duration >= 15000) ? 3 : //超过15秒 -> 第3级
(duration >= 10000) ? 2 : //超过10秒 -> 第2级
(duration >= 5000) ? 1 : 0; //超过5秒 -> 第1级,其他(小于5秒)-> 第0级
//显示屏设置
lcd.setCursor(0, 0); //把光标设置到第一行
lcd.print("!! WARNING !!"); //显示警告文字
lcd.setCursor(0, 1); //第二行清空
lcd.print(" "); //打印一串空格
//根据不同警告阶段,执行蜂鸣器和LED的动作,在triggerAlarm()函数里定义
triggerAlarm();
} else {
if (lastState) { //如果之前检测到了物体,但是现在没有了
resetAlarm(); //调用resetAlarm()重置警报
lcd.clear(); //清空LCD
}
}
}
//超声波测距
//给Trig引脚发一个10微秒的高电平脉冲,启动超声波测距
float getDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH); //使用pulseIn测量从Trig发出到Echo接收到返回信号的时间(单位微秒)
return duration * 0.034 / 2; //计算距离
}
//根据警报阶段执行不同动作
void triggerAlarm() {
switch (alertStage) {
case 1: //阶段1:LED关,蜂鸣器静音
digitalWrite(led, LOW);
noTone(buzzer);
break;
case 2: //阶段2:LED闪烁(每500毫秒闪一次),蜂鸣器静音
digitalWrite(led, millis() % 500 < 250);
noTone(buzzer);
break;
case 3: //阶段3:LED常亮,蜂鸣器发出1000Hz声音
digitalWrite(led, HIGH);
tone(buzzer, 1000);
break;
}
}
void resetAlarm() {
alertStage = 0; //把警报阶段清零
lastState = false; //检测状态清零
digitalWrite(led, LOW); //LED关闭
noTone(buzzer); //蜂鸣器停止发声
}