//超声波测距并在LCD1602液晶屏显示距离,根据距离发出不同提示音
#include <LiquidCrystal_I2C.h>
#define TRIG_PIN 4
#define ECHO_PIN 6
#define BEEP_PIN 5
LiquidCrystal_I2C lcd(0x26, 16, 2);
// 非阻塞时间变量
unsigned long lcdTimer = 0;
unsigned long beepTimer = 0;
bool beepState = false;
float dist = 0;
const int alarmThreshold = 30; //报警阈值cm
void setup() {
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
lcd.init();
lcd.backlight();
lcd.print("Ultrasonic Test");
delay(1000);
lcd.clear();
}
float getDistance()
{
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000); //超时30ms,防止卡死
if(duration == 0) return 999;
float distance = duration * 0.034 / 2;
return distance;
}
void loop() {
unsigned long now = millis();
// 每100ms刷新测距+LCD,不再被蜂鸣器阻塞
if(now - lcdTimer >= 100)
{
lcdTimer = now;
dist = getDistance();
lcd.setCursor(0, 0);
lcd.print("Distance:");
lcd.setCursor(0, 1);
lcd.print(dist, 1);
lcd.print(" cm ");
}
// 无源蜂鸣器非阻塞滴滴,不占用delay
if(dist < alarmThreshold && dist > 0)
{
int beepInterval = map(dist, 2, alarmThreshold, 40, 250);
int freq = map(dist, 2, alarmThreshold, 2000, 600);
if(now - beepTimer >= beepInterval)
{
beepTimer = now;
beepState = !beepState;
if(beepState){
tone(BEEP_PIN, freq);
}else{
noTone(BEEP_PIN);
}
}
}
else
{
noTone(BEEP_PIN);
beepState = false;
}
}