July 16, 2018

디바이스마트 미디어:

[40호]Bluetooth 통신을 이용한 자율주행 안전삼각대

2016 ictmain

2016 ICT 융합 프로젝트 공모전 참가상

Bluetooth 통신을 이용한 자율주행 안전삼각대

글 | 상명대학교 박다은, 김진규, 이재섭, 고병현, 김한수

심사평
JK전자 기술적인 요소만 본다면 단순히 자이로 센서 조정기로 블루투스를 통해서 자동차를 원격으로 조종하는 단순한 내용이지만 생각을 바꾸어서, 고속도로에서 특히 야간에 자동차들이 많은 상황에서 위험하게 사람이 직접 삼각대를 설치하지 않도록 도와주는 제품으로 생각을 하니 정말 실용적이고 생활에 꼭 필요한 제품이라고 여겨지네요. 간단하지만 창의적으로 작품을 잘 만들어서 구현 하였습니다.

뉴티씨 안전에 대한 생각을 통해 만들어낸 아이디어인데, 실제 고속도로에서는 다른 차량들에도 매우 심각한 위험을 안겨줄 수 있을 것 같아서, 실제로 사용하는 것은 많은 연구와 고려가 있은 후에나 가능할 것 같다.
하지만, 학습 목적으로는 좋은 아이템으로 판단되며, 완성되어 작품 완성도면에서는 20점을 주었다. 다만, 실용성이나 기대효과 등이 낮은 점수를 받았다. 보고서 작성은 깔끔하게 잘 작성하였으나, 내용상 해당 아이템에 블루투스를 선택한 점 등이 조금 아쉬움을 남겼다.

칩센 자율주행 삼각대라고 해서 정차한 차량의 후면에서 일정거리를 자동으로 주행하여 위치하는것으로 생각했으나 실제 구현한 작품은 블루투스 RC카와 삼각대의 결합을 연상캐 한다.

위드로봇 도로 상의 안전을 위해 삼각대가 스스로 이동할 수 있게 만든다는 창의성이 돋보이는 작품입니다. 단, 이러한 삼각대를 사용자가 직접 조정을 해야 한다는 점이 아쉬운 부분인데요, 이 부분에 대해 추가 아이디어가 있다면 상품성 있는 제품으로도 만들어도 될 거 같습니다.

1. 작품제목
Bluetooth 통신을 이용한 자율주행 안전삼각대

2. 작품개요
최근 운전자의 부주의나 보행자의 부주의 또는 차량 간의 부주의 등 여러 방면으로 교통사고가 발생하고 있다. 뿐만 아니라 겨울철에 미끄러운 노면으로 인하여 사고가 발생하는 경우도 예외는 아니다. 고속도로 및 일반도로에서 운행을 하다 차량에 문제가 발생하면 차량을 안전한 곳에 세워두고 안전삼각대를 설치해야 한다. 이는 2차 사고를 예방하기 위한 것으로써, 전방에 사고가 난 차량이 있다는 것을 알려 후방 차량에 대해 방어운전을 하도록 돕는 것이다. 차량이 시속 100km의 속도로 달리다가 급정거를 할 때 자동차의 제동거리는 약 40~50m 정도이기 때문에 도로교통법(66조 67조)에 의하여 주간 100m 이상, 어두운 밤일 경우 200m 이상 후방에 안전삼각대를 설치하여 충분한 제동거리를 확보하도록 규정하고 있다.

하지만 안전 삼각대를 무리하게 설치하거나 잘못된 행동으로 인해 2차사고가 발생하는 경우도 많다. 고속도로에서 차량들의 속도는 매우 빠르고 야간에는 시야 확보가 한정되어 있기 때문에 최대한 안전하게 설치할 수 있어야 한다. 현재 안전 삼각대 설치 과정에서 2차사고 방지의 대응책이 마련되어 있지 않은 상황이다. 때문에 최근 3년간 고속도로 2차사고 통계를 살펴보면 2013년 전체사망자의 약 17%가 2차사고로 사망하게 되는 결과를 초래하고 있다. 차량 안전 삼각대는 사고를 예방하기 위해 만들어진 도구지만 2차 사고를 방지하기에는 부족한 부분이 많다. <Bluetooth 통신을 이용한 자율주행 안전삼각대>는 운전자가 삼각대를 직접 설치하지 않고 안전거리를 유지하며 삼각대를 설치할 수 있기 때문에 교통사고의 위험으로부터 안전하다.

따라서 본 작품 <Bluetooth 통신을 이용한 자율주행 안전삼각대>는 자이로센서(gyro sensor)를 사용하여 자율주행이 가능하게 함으로써 기존 안전삼각대의 단점을 보완하고 2차 사고를 안전하게 예방하기 위해 개발되었다. 또한, 사용자가 조종기를 손으로 잡고 사용하게 함으로써 앞뒤좌우로 쉽게 이동할 수 있게 만들어 안전삼각대를 정확한 위치로 이동시킬 수 있게 사용자의 편의와 안전을 고려하여 설계하였다.

3. 작품설명
3.1. 주요 동작 및 특징
고속도로 및 일반도로에서 사고발생시 운전자는 <Bluetooth 통신을 이용한 자율주행 안전삼각대>를 차량 후방에 꺼내놓고 안전한 곳으로 대피한 이후, Bluetooth 모듈이 부착된 조종기를 사용하여 안전삼각대에 부착된 Bluetooth와 통신하며 작동을 시작한다. 조종기에는 AVR, Bluetooth 모듈, 자이로센서(gyro sensor) 및 레귤레이터가 장착되어 있다.

여기서 레귤레이터는 외부전원에서 들어오는 5V의 전원을 자이로센서(gyro sensor)에 필요한 3.3V로 낮춰주는 역할을 한다. 조종기의 전원을 작동하면 Bluetooth 모듈이 자율주행 안전삼각대 본체에 부착되어 있는 Bluetooth 모듈과 페어링한다. 각각의 Bluetooth 모듈이 서로 페어링 되면 조종기에 부착된 자이로센서(gyro sensor)에서 아날로그의 값을 인식하고 AVR에서 신호처리를 한다. 그 다음 조종기의 Bluetooth 모듈을 이용해 안전삼각대에 전송한다. 안전삼각대에 부착된 Bluetooth 모듈은 이를 인식하여 AVR로 전송하게 된다. AVR에서는 수신된 신호를 기반으로 모터 드라이버로 값을 전송하여 모터를 구동하게 된다.

40 ict 참가상 bluetooth 통신 (1)

 

40 ict 참가상 bluetooth 통신 (2)

3.2. 전체 시스템 구성
3.2.1. 조종기

40 ict 참가상 bluetooth 통신 (3)

1. AVR – 신호처리 역할을 한다.
2. 외부 전원 공급 – 배터리에서 AVR로 전원을 공급한다.
3. 자이로센서 – 아날로그 값을 수신하여 디지털 신호로 변환 후 AVR로 전송한다.
4. Bluetooth 모듈(HC-06) – AVR에서 처리한 신호를 안전삼각대의 본체로 전송하는 역할을 한다.

3.2.2. 안전삼각대 본체

40 ict 참가상 bluetooth 통신 (4)

1. AVR – Bluetooth로부터 수신한 값을 바탕으로 모터 드라이버로 전송한다.
2. Bluetooth 모듈 – 조종기에서 전송한 자이로센서(gyro sensor) 값을 수신한다.
3. 모터 드라이버 및 모터 – AVR로부터 신호 값을 수신하여 모터를 구동한다.

3.3. 개발 환경 (언어 툴 등)
1. CodeVisionAVR
2. Atmega128
3. PADS9.5(PCB용 회로 설계)

4. 단계별 제작 과정
4.1. 조종기 제작 과정
1. 회로 설계하기

40 ict 참가상 bluetooth 통신 (5)

2. 외부전원에서 들어오는 5V의 전원을 자이로센서(gyro sensor)에 필요한 3.3V로 낮춰주기 위해 레귤레이터를 사용하여 설계한다.

40 ict 참가상 bluetooth 통신 (6)

3. 회로도를 보고 AVR, Bluetooth 모듈 그리고 자이로센서(gyro sensor)를 부착한다.

40 ict 참가상 bluetooth 통신 (7)

4. 안전삼각대가 자율주행 가능할 수 있도록 조종기가 완성된 모습이다. 사용자가 조종기를 한 손에 잡을 수 있도록 체계적으로 설계하였다.

40 ict 참가상 bluetooth 통신 (8)

4.2. 안전삼각대 본체
1. 회로 설계하기

40 ict 참가상 bluetooth 통신 (9)

2. 회로도를 보고 AVR, Bluetooth 모듈 그리고 전원 스위치를 납땜하여 부착한다.

40 ict 참가상 bluetooth 통신 (10)

3. 차체를 구성하고 모터 및 모터 드라이버를 부착한다.

40 ict 참가상 bluetooth 통신 (11)

4. 모터 및 모터 드라이버의 전원을 연결한다.

40 ict 참가상 bluetooth 통신 (12)

40 ict 참가상 bluetooth 통신 (13)

5. 차체의 내부를 정리하고 4개의 바퀴를 나사를 이용하여 부착한다.

40 ict 참가상 bluetooth 통신 (14)

40 ict 참가상 bluetooth 통신 (15)

6. 차체가 완성된 모습

40 ict 참가상 bluetooth 통신 (16)

7. 종이를 잘라 안전삼각대의 틀을 만들고 빨간 LED를 서로 연결하여 알맞은 위치에 고정시킨다.

40 ict 참가상 bluetooth 통신 (17)

8. 12V 베터리를 부착하고 모든 연결을 마친 후, Bluetooth 통신을 이용하여 안전삼각대가 자율주행 하는 모습이다. 물론 Bluetooth 통신을 이용하기 때문에 주행 가능 거리를 측정해본 결과 약 8.5m 정도이다.

40 ict 참가상 bluetooth 통신 (18)

5. 기타(회로도, 소스코드, 참고문헌 등)
5.1. 회로도(조종기)

40 ict 참가상 bluetooth 통신 (5)

5.2. 회로도(안전삼각대 본체)

40 ict 참가상 bluetooth 통신 (9)

5.3. 소스코드
5.3.1. 안전삼각대 본체 소스코드

// Sourcecode – car
/*******************************************************
This program was created by the CodeWizardAVR V3.23a
Automatic Program Generator
?Copyright 1998-2015 Pavel Haiduc, HP InfoTech s.r.l.

http://www.hpinfotech.com

Project :
Version :
Date : 2015-11-17
Author :
Company :
Comments:

Chip type : ATmega128
Program type : Application
AVR Core Clock frequency: 16.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 1024
*******************************************************/
#include <mega128.h>
#include <delay.h>
//char tc3_spH;
//char tc3_spL;
int stop_speed=0, cnt0=0, cnt1=0;

interrupt [TIM0_OVF] void timer0_overflow(void)
{
cnt0++;
if(cnt0 == 2000)
{
cnt0=0;
cnt1++;
if(cnt1 == 100)
{
cnt1=0;
cnt0=0;
//speed += 100;
//speed = 500;
}
}
}
// UART 통신 함수
void init_UART()
{
UCSR1A=0×0;
UCSR1B=0b00011000;
UCSR1C=0b00000110;
UBRR1H=0;
UBRR1L=16; //57600
}
//모터 제어 함수
void init_timer0(void)
{
TCCR0 = 0×01;
TIMSK |= 0×01;
}
void init_timer1(void)
{
TCCR1A = 0xA3;
TCCR1B = 0×01;
}
void forward(unsigned char motor_speed)
{
//tc3_spH=(char)(8>>(0xff00&pwmsignal));
//tc3_spL=(char)(0x00ff&pwmsignal);
PORTA=0×03;
OCR1A=motor_speed*4;
OCR1B=motor_speed*4;

}
void reverse(unsigned char motor_speed)
{
PORTA=0×00;
OCR1A=motor_speed*4;
OCR1B=motor_speed*4;
}
void turn_left(unsigned char motor_speed)
{
PORTA=0×01;
OCR1A=motor_speed*4;
OCR1B=motor_speed*2; //low reverse
}
void turn_right(unsigned char motor_speed)
{
PORTA=0×02;
OCR1A=motor_speed*2; // low reverse
OCR1B=motor_speed*4;
}
void forward_right(unsigned char motor_speed)
{
PORTA=0×03;
OCR1A=motor_speed*2;
OCR1B=motor_speed*4;
}
void forward_left(unsigned char motor_speed)
{
PORTA=0×03;
OCR1A=motor_speed*4;
OCR1B=motor_speed*2;
}
void reverse_right(unsigned char motor_speed)
{
PORTA=0×00;
OCR1A=motor_speed*2;
OCR1B=motor_speed*4;
}
void reverse_left(unsigned char motor_speed)
{
PORTA=0×00;
OCR1A=motor_speed*4;
OCR1B=motor_speed*2;
}
void stop()
{
PORTA=0×03;
OCR1A=stop_speed;
OCR1B=stop_speed;
}
void main(void)
{
unsigned char ch=0; // 데이터 받는 변수
init_timer0();
init_timer1();
init_UART();

DDRB=0xff;
DDRA=0×03;
#asm(“sei”)
PORTA=0×03;

while(1){
while(UCSR1A&0×80==0×0);
ch=UDR1;
if(ch%10==1) forward(ch-1);
else if(ch%10==2) reverse(ch-2);
else if(ch%10==3) turn_right(ch-3);
else if(ch%10==4) turn_left(ch-4);
else if(ch%10==5) forward_right(ch-5);
else if(ch%10==6) forward_left(ch-6);
else if(ch%10==7) reverse_right(ch-7);
else if(ch%10==8) reverse_left(ch-8);
else stop();
}
}

5.3.2. 조종기 소스코드

//Sourcecode – controller
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.4a Advanced
Automatic Program Generator
?Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.

http://www.hpinfotech.com

Project :
Version :
Date : 2015-11-25
Author : NeVaDa
Company :
Comments:
8방향 제어
Chip type : ATmega128
Program type : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 1024
*****************************************************/
#include <mega128.h>
#include <delay.h>
#include <stdio.h>
#include <stdlib.h>
///LCD define
#define ENABLE PORTD.7 // ENABLE 신호
#define FUNCSET 0×28 // Function Set
#define ENTMODE 0×06 // Entry Mode Set
#define ALLCLR 0×01 // All Clear
#define HOME 0×02 // HOME
#define DISPON 0x0c // Display On
#define LINE2 0xC0 // 2nd Line Move

///gyro define
#define MPU6050_ACCEL_XOUT_H 0x3B // R
#define MPU6050_TEMP_OUT_H 0×41 // R
#define MPU6050_GYRO_XOUT_H 0×43 // R
#define MPU6050_PWR_MGMT_1 0x6B // R/W
#define MPU6050_I2C_ADDR 0×68 // 디바이스 어드레스

//speed control
#define HIGH_SPEED 0×70;
#define MID_SPEED 0×50;
#define LOW_SPEED 0×30;
typedef unsigned char u_char;
u_char mpudata[14]; //mpu buffer
u_char buf;
u_char rdata;
///gyro func
int TWI_Write(int, u_char); // TWI 쓰기
int TWI_Read(int); // TWI 읽기
int TWI_Comm(int); // TWI 공통 함수
void error_out(u_char); // 에러 LED 출력함수
void MPU6050_read(void); // mpu read
void Putch(char data);
void main(void)
{
//LCD_init(); // lcd 초기화
UCSR1A=0×0;
UCSR1B=0b00011000;
UCSR1C=0b00000110;
UBRR1H=0;
UBRR1L=16;

TWBR=12; //TWI설정
TWSR=0×00;
while(1)
{
MPU6050_read(); //mpu read
delay_ms(200);
}
}
//출력함수
int TWI_Write(int addr, u_char data)
{
TWI_Comm(addr); // Start Condition, SLA + W, RA 전송

// Data
TWDR = data; // 전송 데이터
TWCR = 0×84; // TWINT, TWEN 셋
while((TWCR & 0×80) != 0×80);// TWINT 비트가 1이 될 때까지
if((TWSR & 0xF8)!= 0×28) return(0xEF); // 에러 체크

// STOP 조건 발생
TWCR = 0×94;

return(0);
}

int TWI_Read(int st_addr)
{
int err;

err = TWI_Comm(st_addr); // Start Condition, SLA + W, RA 전송
if(err != 0) return(err);

// 반복 START 조건 발생(Read 모드로 바꿈)
TWCR = 0xA4; // TWINT, TWSTA, TWEN 셋
while((TWCR & 0×80) != 0×80); // TWINT 비트가 1이 될 때까지
// ACK 수신
if((TWSR & 0xF8)!= 0×10) return(0x0F); // 에러 체크

// SLA + R
TWDR = (MPU6050_I2C_ADDR << 1) | 0×01; // R/W 비트 셋
TWCR = 0×84; // TWINT, TWEN 셋
while((TWCR & 0×80) != 0×80); // TWINT 비트가 1이 될 때까지
if((TWSR & 0xF8)!= 0×40) return(0x7f);

// Data Read
TWCR = 0×84; // TWINT, TWEN 셋
while((TWCR & 0×80) != 0×80); // TWINT 비트가 1이 될 때까지
// NACK 송신
if((TWSR & 0xF8)!= 0×58) return(0xF0);
rdata = TWDR;

// STOP 조건 발생
TWCR = 0×94;

return(0);
}
int TWI_Comm(int reg_addr)
{
// START 조건 발생
TWCR = 0xA4; // TWINT, TWSTA, TWEN 셋
while((TWCR & 0×80) != 0×80); // TWINT 비트가 1이 될 때까지
if((TWSR & 0xF8)!= 0×08) return(TWSR & 0xf8); // 에러 체크

// SLA + W
TWDR = MPU6050_I2C_ADDR << 1;
TWCR = 0b10000100; // TWINT, TWEN 셋
while((TWCR & 0×80) != 0×80); // TWINT 비트가 1이 될 때까지
// ACK 수신
if((TWSR & 0xF8)!= 0×18) return(0xFD); // 에러 체크

// Register Address(RA)
TWDR = reg_addr;
TWCR = 0b10000100;
while((TWCR & 0×80) != 0×80); // TWINT 비트가 1이 될 때까지
// ACK 수신
if((TWSR & 0xF8)!= 0×28) return(0xFB); // 에러 체크
return(0);
}
void error_out(u_char err)
{
PORTA = ~err;
//delay_ms(100);
}
void MPU6050_read(void)
{
int error,addr,x_accel,y_accel,n; //gyro변수
unsigned char temp=0;
error=TWI_Write(MPU6050_PWR_MGMT_1,0); //sleep mode 0
if(error!=0) error_out(error);
addr=MPU6050_ACCEL_XOUT_H;
for(n=0; n<14; n++)
{
error=TWI_Read(addr++);
if(error!=0) error_out(error);
mpudata[n]=rdata;
}
x_accel = (((int)mpudata[2] << 8) | ((int)mpudata[3] & 0x0FF));
y_accel = (((int)mpudata[4] << 8) | ((int)mpudata[5] & 0x0FF));

if(x_accel/200>25 && x_accel/200<45)
{
temp=0×51; //1단계 속도 전진
}
else if(x_accel/200>=45 && x_accel/200<65)
{
temp=0xA1; // 2단계 속도 전진
}
else if(x_accel/200>=65)
{
temp=0xf1;
}
else if(x_accel/200<-25 && x_accel/200>-45)
{
temp=0×52; //1단계 속도 후진
}
else if(x_accel/200<=-45 && x_accel/200>-65)
{
temp=0xA2; //2단계 속도 후진
}
else if(x_accel/200<=-65)
{
temp=0xf2;
}
else if(y_accel/200>25 && y_accel/200<45 )
{
temp=0×53; //좌회전 1단계
}
else if(y_accel/200>=45 && y_accel/200<65)
{
temp=0xA3; //좌회전 2단계
}
else if(y_accel/200>=65)
{
temp=0xf3;
}
else if(y_accel/200<-25 && y_accel/200>-45 )
{
temp=0×54; //우회전 1단계
}
else if(y_accel/200<=-45 && y_accel/200>-65)
{
temp=0xA4; //우회전 2단계
}
else if(y_accel/200<=-65)
{
temp=0xf4;
}
else
{
temp=0;
}
buf=temp;
Putch(buf);
}
void Putch(char data)
{
while(!(UCSR1A & (1<<UDRE1)));
UDR1=data;
}

5.4. 참고문헌 및 참고사이트
1. AVR ATmega128 마이크로컨트롤러, ITC 출판사 (이응혁, 작문석, 장영건 지음)
2. 참고 사이트 – www.alldatasheet.com

 

 

 

Leave A Comment

*