Привет! Соберем еще один проект на Processing и Ардуино. На этот раз это будет ультразвуковой радар с визуализацией в Processing программе в киношном стиле. Необходимо сказать, что этот проект будет не самостоятельным, а переводом и разбором статьи с сайта create.arduino.cc
Содержание
Для этого проекта нам опять понадобиться ультразвуковой дальномер hc-sr04. Описание которого мы уже делали в отдельном уроке. Посмотрите его, если уже забыли или пропустили.
Для выполнения этого урока нам понадобятся
- Ардуино UNO
- Макетная плата
- Перемычки
- Ультразвуковой датчик расстояния hc-sr04
- Сервопривод
- Кабель USB
Проект и схема
Как вы помните ультразвуковой дальномер показывает нам расстояние до препятствия. Мы уже настраивали этот датчик и получали в мониторе порта данные о расстоянии. В этой части проект не изменился. Но теперь мы передадим эти данные в программу на processing. И нарисуем картинку из шпионских фильмов для них.
Во-первых соберем на макетной плате схему. Светодиод подключать не обязательно. Мы не будем его программировать.
Закрепим дальномер на сервоприводе, чтобы он вращался вместе с поворотом двигателя.
Программа на Ардуино
В программе не будет ничего нового. Мы используем стандартную схему для дальномера. Посылаем короткий сигнал и считываем данные с контакта echo. После чего можем рассчитать расстояние в сантиметрах и записать в последовательный порт.
Желтый провод серводвигателя подключен к контакту 10. А дальномер установлен на двигателе и вращается вместе с ним.
Полный текст программы
#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(10);
}
void loop(){
for(int i=15;i<=165;i++){ //вращаем серводвигатель от 15 до 165 градусов
s1.write(i);
delay(30);
distance = calDist();
Serial.print(i); // Отправляем градусы в порт
Serial.print(","); // Разделяем данные для processing программы
Serial.print(distance); // Отправляем расстояние в порт
Serial.print("."); // Разделяем данные для processing программы
}
for(int i=165;i>15;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="";
String distance="";
String data="";
int angle, dist;
void setup() {
size (1200, 700);
myPort = new Serial(this,"COM7", 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);
}
void drawRadar(){
pushMatrix();
noFill();
stroke(10,255,10);
strokeWeight(3);
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);
line(0,0,(-width/2)*cos(radians(30)),(-width/2)*sin(radians(30)));
line(0,0,(-width/2)*cos(radians(60)),(-width/2)*sin(radians(60)));
line(0,0,(-width/2)*cos(radians(90)),(-width/2)*sin(radians(90)));
line(0,0,(-width/2)*cos(radians(120)),(-width/2)*sin(radians(120)));
line(0,0,(-width/2)*cos(radians(150)),(-width/2)*sin(radians(150)));
stroke(175,255,175);
strokeWeight(1);
line(0,0,(-width/2)*cos(radians(15)),(-width/2)*sin(radians(15)));
line(0,0,(-width/2)*cos(radians(45)),(-width/2)*sin(radians(45)));
line(0,0,(-width/2)*cos(radians(75)),(-width/2)*sin(radians(75)));
line(0,0,(-width/2)*cos(radians(105)),(-width/2)*sin(radians(105)));
line(0,0,(-width/2)*cos(radians(135)),(-width/2)*sin(radians(135)));
line(0,0,(-width/2)*cos(radians(165)),(-width/2)*sin(radians(165)));
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);
textSize(40);
text("Угол :"+angle,width*0.45,height*0.99);
if(dist<=40) {
text("Расстояние :"+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();
}
Ультразвуковой радар Processing
В итоге мы получили вращающийся датчик измерения расстояния и программу, которая показывает препятствие в радиусе действия датчика.
Заключение
Мы собрали Ультразвуковой радар на Processing и Ардуино. Написали программу для отображения данных с датчика расстояния в удобной форме. И еще раз использовали передачу данных из Ардуино в программу на компьютере через последовательный порт.