초음파 레이더
페이지 정보
작성자 브랜든 작성일16-10-20 16:19 조회4,814회 댓글1건관련링크
본문
오늘은 몸풀기로 가볍게 퀴즈 하나 내보겠습니다.
"이 감옥은 감시자 없이도 죄수들 자신이 스스로 감시하는 감옥을 말합니다."
'이 감옥'의 이름은 무엇일까요?
에? 감시자가 없는데 누구든지 탈출할 수 있지 않을까? 라고 생각되는데요!
문제가 너무 쉬웠나요? '이 감옥'은 바로 팬옵티콘[Panopticon]이라고 합니다.
(무언가 트랜스포머에 나올 듯한 이름이네요:D)
팬옵티콘은 중앙의 원형공간에 높은 감시탑을 세우고 중앙 감시탑 바깥의 원 둘레를 따라 죄수들의 방이 있습니다. 중앙의 감시탑은 어둡게 하고, 죄수의 방은 밝게 해 중앙에서 감시하는 감시자의 시선이 어디로 향하는지를 죄수들이 알 수 없도록 되어있습니다.
예를 들면, 썬팅한 자동차 안에서는 밖이 쉽게 보이지만, 밖에선 안이 잘 보이지 않습니다.
본론 들어가기 앞서 벌써 하나 배웠군요! 여러분, 대단합니다!
그래서 오늘은 초음파 레이더를 만들어 보겠습니다.
부품 알아보기
제작 과정
초음파 센서 4개를 밖으로 동서남북으로 보게 만능기판에다가 끼웁니다.
초음파 센서가 고정이 되도록 위쪽에다가 글루건을 붙여줍니다.
고정을 깔끔하게 하고 싶다면 센서와 기판을 납땜해주시면 됩니다.
초음파 센서가 고정이 되도록 위쪽에다가 글루건을 붙여줍니다.
고정을 깔끔하게 하고 싶다면 센서와 기판을 납땜해주시면 됩니다.
죄수들을 완벽히 구석구석 감시하기 위해, 층을 조금 더 높여야 될 것 같습니다.
간단한 나무조각으로 위에는 만능기판, 아래에는 모터를 부착해줍니다.
그리고 브레드보드와 모터를 움직이지 않게 글루건으로 붙여줍니다.
간단한 나무조각으로 위에는 만능기판, 아래에는 모터를 부착해줍니다.
그리고 브레드보드와 모터를 움직이지 않게 글루건으로 붙여줍니다.
TIP! 2,3,10,11번은 초음파 센서의 Trigger 단자에 5,6,7,8번은 Echo에 방향에 맞게 끼워줍니다.
위와같이 배선합니다.
여기서 잠깐! 초음파센서의 감지가 안된다면, 서보모터의 VCC를 Vin 또는 외부전원을 넣어서 다시 작동해보세요.
하지만 일반적으로는 VCC에 끼워야 합니다.
소스코드 알아보기
아두이노 코드입니다.
#include<Servo.h>
Servo myservo;
int pos = 0;
int angle = 0;
Servo myservo;
int pos = 0;
int angle = 0;
void setup()
{
Serial.begin(9600);
myservo.attach(9);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
pinMode(8, INPUT);
//기본 설정을 해 줍니다.
}
{
Serial.begin(9600);
myservo.attach(9);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
pinMode(8, INPUT);
//기본 설정을 해 줍니다.
}
void loop() {
for (pos = 0; pos <= 90; pos += 1)
{
myservo.write(pos);
delay(10);
ultraSonicAll();
angle=angle+1;
//모터 회전을 설정합니다.
}
for (pos = 90; pos >= 0; pos -= 1)
{
myservo.write(pos);
delay(10);
ultraSonicAll();
angle=angle-1;
//모터 회전을 설정합니다.
}
}
for (pos = 0; pos <= 90; pos += 1)
{
myservo.write(pos);
delay(10);
ultraSonicAll();
angle=angle+1;
//모터 회전을 설정합니다.
}
for (pos = 90; pos >= 0; pos -= 1)
{
myservo.write(pos);
delay(10);
ultraSonicAll();
angle=angle-1;
//모터 회전을 설정합니다.
}
}
void ultraSonicAll() {
Serial.print(ultraSonic(2, 5));
Serial.print(",");
Serial.print(ultraSonic(10, 8));
Serial.print(",");
Serial.print(ultraSonic(11, 7));
Serial.print(",");
Serial.print(ultraSonic(3, 6));
Serial.print(",");
Serial.print(-angle);
Serial.print(".");
//값을 화면에 출력합니다.
}
Serial.print(ultraSonic(2, 5));
Serial.print(",");
Serial.print(ultraSonic(10, 8));
Serial.print(",");
Serial.print(ultraSonic(11, 7));
Serial.print(",");
Serial.print(ultraSonic(3, 6));
Serial.print(",");
Serial.print(-angle);
Serial.print(".");
//값을 화면에 출력합니다.
}
int ultraSonic(int trigPin, int echoPin) {
unsigned long duration;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH,6000);
int distance = duration * 17 / 1000;
if(distance >= 40 || distance == 0) {
distance = 40;
}
return distance;
//초음파 센서값을 측정합니다.
}
이번에도 아두이노의 시리얼 모니터로 장애물 여부를 구분하기 힘드므로
아래 processing 프로그램을 이용하겠습니다.
프로세싱 코드입니다.
아래 processing 프로그램을 이용하겠습니다.
프로세싱 코드입니다.
import processing.serial.*;
Serial myPort;
String myString = null;
int distance_up = 0;
int distance_right = 0;
int distance_down = 0;
int distance_left = 0;
int angle = 0;
void setup(){//기본설정
size(700, 700);
background(0);
myPort = new Serial(this, "COM5", 9600);
}
void draw(){//화면에 그림을 표시해줍니다.
noStroke();
fill(0,10);
rect(0,0,width,height);
drawRader();
drawLine();
}
Serial myPort;
String myString = null;
int distance_up = 0;
int distance_right = 0;
int distance_down = 0;
int distance_left = 0;
int angle = 0;
void setup(){//기본설정
size(700, 700);
background(0);
myPort = new Serial(this, "COM5", 9600);
}
void draw(){//화면에 그림을 표시해줍니다.
noStroke();
fill(0,10);
rect(0,0,width,height);
drawRader();
drawLine();
}
void serialEvent(Serial p){//시리얼 입력이 생기면
try{
myString = p.readStringUntil('.');
String[] list = split(myString, ',');
distance_up = int(list[0]);
distance_right = int(list[1]);
distance_down = int(list[2]);
distance_left = int(list[3]); //각 방향마다 거리를 저장
angle = int(list[4]); //각도를 저장
//angle = 90;
}catch(Exception e){
}
}
void drawRader(){
pushMatrix();
translate(width/2, height); //line length
noFill();
strokeWeight(2); //line thicknes
stroke(98, 245, 31);
// draw the arc lines
arc(0, -width/2, width, width, 0, TWO_PI);
arc(0, -width/2, width*3/4, width*3/4, 0, TWO_PI);
arc(0, -width/2, width*2/4, width*2/4, 0, TWO_PI);
arc(0, -width/2, width*1/4, width*1/4, 0, TWO_PI);
arc(0, 0, width, width, PI, PI);
textSize(15);
fill(98, 245, 31);
textAlign(RIGHT);
text("10cm", width*1/8, -350);
text("20cm", width*2/8, -350);
text("30cm", width*3/8, -350);
text("40cm", width*4/8, -350);
popMatrix();
}
void drawLine(){
pushMatrix();
strokeWeight(10); //point thickness
stroke(255,10, 10); // red color
float d1 = (width/2.0/40.0)*(float)distance_up;
float d2 = (width/2.0/40.0)*(float)distance_right;
float d3 = (width/2.0/40.0)*(float)distance_down;
float d4 = (width/2.0/40.0)*(float)distance_left;
line(width/2,width/2,width/2-(d1*cos(radians(angle))),width/2-(d1*sin(radians(angle))));
line(width/2,width/2,width/2-(d2*cos(radians(angle+90))),width/2-(d2*sin(radians(angle+90))));
line(width/2,width/2,width/2-(d3*cos(radians(angle+180))),width/2-(d3*sin(radians(angle+180))));
line(width/2,width/2,width/2-(d4*cos(radians(angle+270))),width/2-(d4*sin(radians(angle+270))));
popMatrix();
}
try{
myString = p.readStringUntil('.');
String[] list = split(myString, ',');
distance_up = int(list[0]);
distance_right = int(list[1]);
distance_down = int(list[2]);
distance_left = int(list[3]); //각 방향마다 거리를 저장
angle = int(list[4]); //각도를 저장
//angle = 90;
}catch(Exception e){
}
}
void drawRader(){
pushMatrix();
translate(width/2, height); //line length
noFill();
strokeWeight(2); //line thicknes
stroke(98, 245, 31);
// draw the arc lines
arc(0, -width/2, width, width, 0, TWO_PI);
arc(0, -width/2, width*3/4, width*3/4, 0, TWO_PI);
arc(0, -width/2, width*2/4, width*2/4, 0, TWO_PI);
arc(0, -width/2, width*1/4, width*1/4, 0, TWO_PI);
arc(0, 0, width, width, PI, PI);
textSize(15);
fill(98, 245, 31);
textAlign(RIGHT);
text("10cm", width*1/8, -350);
text("20cm", width*2/8, -350);
text("30cm", width*3/8, -350);
text("40cm", width*4/8, -350);
popMatrix();
}
void drawLine(){
pushMatrix();
strokeWeight(10); //point thickness
stroke(255,10, 10); // red color
float d1 = (width/2.0/40.0)*(float)distance_up;
float d2 = (width/2.0/40.0)*(float)distance_right;
float d3 = (width/2.0/40.0)*(float)distance_down;
float d4 = (width/2.0/40.0)*(float)distance_left;
line(width/2,width/2,width/2-(d1*cos(radians(angle))),width/2-(d1*sin(radians(angle))));
line(width/2,width/2,width/2-(d2*cos(radians(angle+90))),width/2-(d2*sin(radians(angle+90))));
line(width/2,width/2,width/2-(d3*cos(radians(angle+180))),width/2-(d3*sin(radians(angle+180))));
line(width/2,width/2,width/2-(d4*cos(radians(angle+270))),width/2-(d4*sin(radians(angle+270))));
popMatrix();
}
여기서 중요한 것한한것은 프로세싱 소스코드에서
myPort = new Serial(this, "COM5", 9600);에 있는 COM5를 아두이노에서 현재 사용하고 있는 포트번호로 바꿔줍니다. 만약 아두이노에서 COM3을 이용하고 있다면 processing 프로그램에서 COM5를 COM3으로 바꿔줍니다.
myPort = new Serial(this, "COM5", 9600);에 있는 COM5를 아두이노에서 현재 사용하고 있는 포트번호로 바꿔줍니다. 만약 아두이노에서 COM3을 이용하고 있다면 processing 프로그램에서 COM5를 COM3으로 바꿔줍니다.
동작 영상보기
<
감옥에 설치하면 아무도 못 나가겠어요:D
읽어주셔서 감사합니다.
댓글목록
안승호님의 댓글
안승호 작성일아두이노와 프로세싱을 같이 사용한 프로젝트중에 가장 멋있는 것 같아요