Измерение расстояния в реальном времени: Ардуино-сонар с визуализацией в Processing
Компоненты и материалы
| Arduino UNO | ×1 |
| Сервопривод SG90 | ×1 |
| Ультразвуковой датчик HC-SR04 | ×1 |
| Перемычки | ×1 |
| Беспаечная макетная плата (полного размера) | ×1 |
Инструменты
- Клеевой пистолет
- Паяльная станция SolderPro 150
Программное обеспечение
- Arduino IDE
- Processing IDE
О проекте
Автор решил не строить типичный робот-избегатор препятствий, а сделать сонар: ультразвуковой датчик на сервоприводе сканирует пространство на 180°, а данные передаются в Processing для визуализации на экране ПК. Датчик клеится на серво клеевым пистолетом.
Принцип работы
Сервопривод поворачивает датчик HC-SR04 от 0 до 180° и обратно. Arduino измеряет расстояние и отправляет пары «угол,расстояние» через последовательный порт. Processing рисует радарный экран: дуги расстояния, луч текущего угла и красные отметки обнаруженных объектов до 40 см.
Код для Arduino
#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
import processing.serial.*;
Serial myPort;
String ang = "", distance = "", 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);
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);
}
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);
// линии углов...
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 x = -pixleDist*cos(radians(angle));
float y = -pixleDist*sin(radians(angle));
if(dist <= 40) {
line(-x, y, -x+(pixleDist*cos(radians(angle))), y-(pixleDist*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);
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(90)), (-width/2)*sin(radians(90)));
text("120", (width/2)*cos(radians(120)), (-width/2)*sin(radians(120)));
text("150", (width/2)*cos(radians(150)), (-width/2)*sin(radians(150)));
popMatrix();
}
Схема подключения
Датчик HC-SR04: VCC — 5V, GND — GND, Trig — D12, Echo — D11. Сервопривод: сигнальный провод — D9, питание — 5V/GND. Схема на фото.
Производственный процесс
- TinyML-детектор языка на Arduino Nano 33 BLE Sense с Edge Impulse
- Создание игры в реальном времени на Arduino Nano с гироскопом MPU-6050 и OLED-дисплеем
- Цифровые кости на Arduino: генератор случайных чисел с LCD-дисплеем и кнопкой
- Создание ультразвукового левитатора на Arduino: пошаговое руководство
- Умный вольтметр на Arduino и смартфоне — простое DIY-проект
- Логгер температуры и влажности на Arduino с DHT11 и Ethernet Shield
- Умная банка на ESP8266 + Arduino: мониторинг наполненности в реальном времени
- Умный счетчик парковки: Отслеживание машин в реальном времени (Arduino, Processing, PHP)
- Бесшовное управление яркостью светодиодов с помощью Bolt IoT и Arduino UNO
- Цифровой компас в реальном времени на Arduino и Processing