Arduino 声纳实时测距与 Processing 可视化
组件与物料
| 组件 | 数量 | 备注 |
|---|---|---|
| Arduino UNO | 1 | |
| SG90 微型舵机 | 1 | |
| HC-SR04 超声波传感器 | 1 | |
| 跳线 (若干) | 1 | |
| 全尺寸无焊面包板 | 1 |
所需工具和机器
- 热熔胶枪
- 电烙铁套装 (SolderPro 150)
应用与在线服务
- Arduino IDE
- Processing IDE (The Processing Foundation)
项目介绍
作者原本打算制作避障小车,但觉得太常见,便利用舵机和 HC-SR04 超声波传感器制作声纳雷达。由于没有 TFT 屏幕,选择用 Processing IDE 在电脑上高分辨率显示声纳数据。先用 p5.js 网页编辑器练习,再转用 Processing 正式开发。

将超声波传感器用热熔胶固定在舵机上,随舵机旋转覆盖 180° 范围。Processing 端实时绘制雷达扫描图,显示检测到的物体距离和角度。

代码
Arduino 端代码 (C/C++)
#include <Servo.h>
const int trigPin = 12;
const int echoPin = 11;
long duration;
int distance;
Servo s1;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
s1.attach(9);
}
void loop() {
for(int i = 0; i < 180; i++) {
s1.write(i);
delay(30);
distance = calDist();
Serial.print(i);
Serial.print(",");
Serial.print(distance);
Serial.print(".");
}
for(int i = 180; i > 0; i--) {
s1.write(i);
delay(30);
distance = calDist();
Serial.print(i);
Serial.print(",");
Serial.print(distance);
Serial.print(".");
}
}
int calDist() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration * 0.034 / 2;
return distance;
}
Processing 端代码 (Java)
import processing.serial.*;
Serial myPort;
String ang = "";
String distance = "";
String data = "";
int angle, dist;
void setup() {
size(2000, 800);
myPort = new Serial(this, "COM3", 9600);
myPort.bufferUntil('.');
background(0);
}
void draw() {
fill(0, 5);
noStroke();
rect(0, 0, width, height * 0.93);
noStroke();
fill(0, 255);
rect(0, height * 0.93, width, height);
drawRadar();
drawLine();
drawObject();
drawText();
}
void serialEvent(Serial myPort) {
data = myPort.readStringUntil('.');
data = data.substring(0, data.length() - 1);
int index1 = data.indexOf(",");
ang = data.substring(0, index1);
distance = data.substring(index1 + 1, data.length());
angle = int(ang);
dist = int(distance);
System.out.println(angle);
}
void drawRadar() {
pushMatrix();
noFill();
strokeWeight(0.5);
stroke(10, 255, 10);
translate(width/2, height - height * 0.06);
line(-width/2, 0, width/2, 0);
arc(0, 0, width * 0.5, width * 0.5, PI, TWO_PI);
arc(0, 0, width * 0.25, width * 0.25, PI, TWO_PI);
arc(0, 0, width * 0.75, width * 0.75, PI, TWO_PI);
arc(0, 0, width * 0.95, width * 0.95, PI, TWO_PI);
// 角度刻度线
for (int a = 30; a <= 150; a += 30) {
line(0, 0, (-width/2) * cos(radians(a)), (-width/2) * sin(radians(a)));
}
stroke(175, 255, 175);
for (int a = 15; a <= 165; a += 30) {
line(0, 0, (-width/2) * cos(radians(a)), (-width/2) * sin(radians(a)));
}
popMatrix();
}
void drawLine() {
pushMatrix();
strokeWeight(9);
stroke(0, 255, 0);
translate(width/2, height - height * 0.06);
line(0, 0, (width/2) * cos(radians(angle)), (-width/2) * sin(radians(angle)));
popMatrix();
}
void drawObject() {
pushMatrix();
strokeWeight(9);
stroke(255, 0, 0);
translate(width/2, height - height * 0.06);
float pixleDist = (dist / 40.0) * (width / 2.0);
float pd = (width/2) - pixleDist;
float x = -pixleDist * cos(radians(angle));
float y = -pixleDist * sin(radians(angle));
if (dist <= 40) {
line(-x, y, -x + (pd * cos(radians(angle))), y - (pd * sin(radians(angle))));
}
popMatrix();
}
void drawText() {
pushMatrix();
fill(100, 200, 255);
textSize(25);
text("10cm", (width/2) + (width * 0.115), height * 0.93);
text("20cm", (width/2) + (width * 0.24), height * 0.93);
text("30cm", (width/2) + (width * 0.365), height * 0.93);
text("40cm", (width/2) + (width * 0.45), height * 0.93);
if (dist <= 40) {
text("Distance :" + dist, width * 0.7, height * 0.99);
}
translate(width/2, height - height * 0.06);
textSize(25);
text(" 30", (width/2) * cos(radians(30)), (-width/2) * sin(radians(30)));
text(" 60", (width/2) * cos(radians(60)), (-width/2) * sin(radians(60)));
text("90", (width/2) * cos(radians(91)), (-width/2) * sin(radians(90)));
text("120", (width/2) * cos(radians(123)), (-width/2) * sin(radians(118)));
text("150", (width/2) * cos(radians(160)), (-width/2) * sin(radians(150)));
popMatrix();
}
原理图

制造工艺
- 基于 Edge Impulse 的 TinyML 语言检测器:Arduino Nano 33 BLE Sense 实战
- Arduino Nano 与 MPU-6050 构建实时陀螺仪游戏
- Arduino 数字骰子:LCD 显示随机点数的电子骰子
- 用 Arduino 制作超声波悬浮装置:分步指南
- Arduino 与智能手机打造智能电压表——简单易做的 DIY 项目
- Arduino + DHT11 + 以太网盾板温湿度数据记录仪
- 智能物联网罐:ESP8266 + Arduino + 超声波传感器实时监测罐内物位
- 智能停车计数系统:Arduino + Processing + PHP 实时车位追踪上云
- Bolt IoT + Arduino UNO 实现 6 路 LED 无级调光
- 通过 Arduino IoT Cloud 用 Alexa 控制电视:分步指南
- 使用 Arduino Nano 和 RDA8057M 制作紧凑型 FM 收音机
- Arduino 实时数字罗盘:HMC5883L + Processing 可视化教程