wokwi搭建仿真超声波雷达测距判断(保姆级教学)

hello,小伙伴们。这里是少卿。

最近手上刚好有个Arduino板和超声波模块,想着搭建一个小demo,希望能分享给大家。

硬件模块部分

硬件具体由以下部分组成,均可以再wokwi的Arduino Uno的模块库中找到

引脚连接

硬件引脚连接部分如图

仿真连接

代码如下

主要有几个

cpp 复制代码
#include <LiquidCrystal_I2C.h>
#define TRIG 6
#define ECHO 5
#define GREEN 4
#define YELLOW 3
#define RED 2
#define BUZZ 13
#define BUTTON A0
LiquidCrystal_I2C lcd(0x27, 16, 2);
const char* NAME[4] = { "SAFE", "CAUTION", "WARNING", "STOP" };   //  屏幕文字
int cm = -1;        // 距离(cm);-1 = 没测到
int state = 0;      // 0=SAFE 1=CAUTION 2=WARNING 3=STOP        
int mode = 0;       // 0=ALARM 1=MUTE                          
int bad = 0;        // 连续没测到的次数                         
unsigned long t100 = 0, tRed = 0, tBeep = 0, tPress = 0;   // 计时
bool redOn = false, beepOn = false, pressed = false;
/*  测距:Wokwi 官方 HC-SR04 示例写法(脉宽 / 58 = 厘米) */
int distance() {
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  unsigned long us = pulseIn(ECHO, HIGH, 40000);   // 40ms 超时
  if (us == 0) return -1;                          // 没回波
  int d = us / 58;
  if (d > 500) return -1;                          // 离谱值
  return (d > 400) ? 400 : d;                      // 量程封顶
}
/*  LCD屏幕:补空格到 16 位,刷新无残留 */
void line(int row, String s) {
  while (s.length() < 16) s += ' ';
  lcd.setCursor(0, row);
  lcd.print(s);
}
void setup() {
  pinMode(TRIG, OUTPUT);   pinMode(ECHO, INPUT);
  pinMode(GREEN, OUTPUT);  pinMode(YELLOW, OUTPUT);  pinMode(RED, OUTPUT);
  pinMode(BUZZ, OUTPUT);   pinMode(BUTTON, INPUT_PULLUP);
  lcd.init();
  lcd.backlight();
}
void loop() {
  unsigned long now = millis();
  /*  每 100ms 测一次 + 刷屏
     偶发丢回波沿用上次值,连续 3 次才显示  */
  if (now - t100 >= 100) {
    t100 = now;
    int d = distance();
    if (d >= 0) { cm = d; bad = 0; }
    else if (++bad >= 3) cm = -1;
    /*  临界判断:等号位置就是采分点 */
    if (cm < 0 || cm > 100) state = 0;        // SAFE
    else if (cm >= 50)      state = 1;        // CAUTION
    else if (cm >= 20)      state = 2;        // WARNING
    else                    state = 3;        // STOP
    /* 距离 / 状态 + 模式(各字段间留空格) */
    line(0, cm < 0 ? String("D:  --- cm") : "D: " + String(cm) + " cm");
    line(1, String(NAME[state]) + (mode ? " MUTE" : " ALARM"));
  }
  /* 三色灯:绿/黄常亮,WARNING 250/250,STOP 越近闪得越快 */
  digitalWrite(GREEN, state == 0);
  digitalWrite(YELLOW, state == 1);
  unsigned long half = (state == 3) ? 40 + cm * 10 : 250;
  if (state > 1) {
    if (now - tRed >= half) { tRed = now; redOn = !redOn; }
  } else {
    redOn = false;
  }
  digitalWrite(RED, redOn);
  /* 蜂鸣器:WARNING 500/500,STOP 125/125; MUTE 立即静音 */
  unsigned long halfBeep = (state == 2) ? 500 : (state == 3) ? 125 : 0;
  if (mode == 0 && halfBeep > 0) {
    if (now - tBeep >= halfBeep) {
      tBeep = now;
      beepOn = !beepOn;
      if (beepOn) tone(BUZZ, 2000); else noTone(BUZZ);
    }
  } else if (beepOn) {
    beepOn = false;
    noTone(BUZZ);
  }
  /* 只有 WARNING/STOP 下按键才切模式
     按下沿 + 50ms 消抖 + 长按不连发 */
  int b = digitalRead(BUTTON);
  if (b == LOW && !pressed) {
    pressed = true;
    if (now - tPress > 50) {
      tPress = now;
      if (state > 1) mode = 1 - mode;
    }
  }
  if (b == HIGH) pressed = false;
}
相关推荐
C++ 老炮儿的技术栈1 小时前
机器人的坐标,像 XYZ 的坐标值,是用单精度浮点还是用双精度浮点?
c语言·c++·人工智能·单片机·c
深圳老胡2 小时前
STM32C562RET6 外部中断详解:从 EXTI 原理到 GPIO 外部中断实战
笔记·stm32·单片机·代码规范·1024程序员节
威嵌神州2 小时前
一台加固平板,能替掉几台现场设备?
嵌入式硬件·fpga开发·电脑·平板
编码追梦人2 小时前
ESP-IDF 实战:用 ESP32-C3 打造超低功耗 LoRa 无线传感器节点(深度睡眠 + OTA 全解析)
嵌入式硬件·lora·设计规范·esp-idf·esp32-c3·低功耗设计
编码追梦人2 小时前
基于 ESP32-S3 的便携式多参数环境监护仪设计:从硬件选型到 FreeRTOS 多任务落地
数据库·单片机·嵌入式硬件·mongodb·esp32·freertos·低功耗设计
wuyk55513 小时前
防逆向基础:在量产固件中关闭调试接口并设置读保护(RDP)的正确姿势
stm32·单片机·嵌入式硬件·性能优化·重构
zhangrelay17 小时前
单片机原理与接口技术-2026融合版-从MEGA2560-ESP32与Wokwi到ROS2-Lyrical与具身智能栈
单片机·嵌入式硬件
lhbweilai17 小时前
分析FreeRTOS内核对象API的源码实现(八)
c语言·开发语言·stm32·单片机
艾络迅Acceleronix18 小时前
环境监测终端:STM32+EG800Z AT+ 艾络迅平台实战|多传感器采集联动全流程
c语言·stm32·单片机·嵌入式硬件·物联网·1024程序员节