[38호]지능형 GPS & 장애물 감시 주행로봇
2016 ICT 융합 프로젝트 공모전 참가상
지능형 GPS & 장애물 감시 주행로봇
글 | 가천대학교 도성곤, 박성진
심사평
JK전자 창의적이거나 기술적으로 완성도가 높은 작품은 분명히 아니다. 하지만 보고서의 내용을 읽어 보면서 기초 지식이 굉장히 부족한 상태에서 의욕만 가지고 작품 구현을 시작한 것으로 보이고 비록 완성도가 높은 작품은 아니지만, 공모전에 참가하고 작품 완성을 위해서 하나하나 배우면서 많은 고생을 했을 것이라는 것이 보고서에서 느껴진다. 작품에 참여한 모든 인원들 수고했고 앞으로 많은 발전이 있을 것이라 생각된다.
뉴티씨 GPS를 이용하여 입력된 장소를 찾아가는 것은 말하기는 쉬우나, 실제로 만들어보면 생각보다 난제가 많음을 알 수 있다. 움직이는 것은 많은 문제점을 내포하고 있으며, 아이디어를 구현하였다는 점에 큰 점수를 주고 싶다. 이 자체로 실용적이거나 하지는 않지만, 앞으로 좀 더 연구하여 자동주행에 적용될 수 있도록 한다면 좋을 것 같다. 이 분야를 공부하는 한가지 계기가 될 수 있지 않았을까 생각하며, 이 작품을 만든 학생의 미래를 꿈꿔본다.
칩센 보고서 내용처럼 공부를 목적으로 하는 부분은 충분히 만족했을 것 같다. 너무 어려운 주제를 선택한 것 같다.
위드로봇 고생을 많이 한 작품으로 보인다. 특히 실외에서 실험을 진행해야 하기에 더욱 그러했을 것이다. UART 통신 및 기타 센서 인터페이스를 위해 MCU의 기초부터 차근차근 학습하면 좀 더 수월하게 개발을 할 수 있을 것으로 보인다.
작품개요
동기
현재 애플, 구글과 같은 세계적인 IT 기업은 무인자동차를 미래 먹거리 산업으로 정하고 계속 연구를 진행하고 있다는 것을 언론으로 알게 되었고, 꼭 한번 직접 만들고 싶다는 생각을 하게 되었습니다. 그러나 실제 크기의 자동차를 만들기에는 무리가 있다고 생각하여 미니카 사이즈로 제작하는 것부터 시작하였습니다.
무인자동차를 만들면 많은 부분에 관한 기초를 익힐 수 있다고 생각했습니다. GPS, 적외선 센서를 사용해 봄으로써 다양한 분야에 응용이 가능할 것이라는 기대를 합니다. 예로 청소기 로봇을 들 수 있는데 청소기 로봇은 집안의 장애물을 파악하여 피하며 스스로 청소를 하는 로봇입니다. 기존의 청소기 역시 청소는 가능했으므로 기존의 청소기에 장애물을 피하는 능력이 있으면 로봇 청소기가 되는 것이고, 이러한 장애물을 피하는 알고리즘을 무인 자동차를 만들면서 생각해 볼 수 있습니다.
또 다른 예로 작년에 많은 관심을 일으켰던 드론에도 적용하는 것도 가능할 것입니다. 아마존에서는 드론을 이용하여 제품을 배달하려는 계획을 세웠는데 이를 위해서는 GPS를 통해 현재 위치를 파악하고 목적지까지 가는 방법을 생각해야 합니다. 향후 우리들이 이 분야에도 진입할 수 있다는 생각에, 한동안 작품을 만들면서 힘들지만 계속 동기부여를 할 수 있었습니다.
제품의 도전 과제
① 적외선 센서의 장애물 감지
② 로봇의 모터 움직임(차체의 무게 최소화)
③ GPS 센서의 위성신호 데이터 수신
④ 수신된 데이터 GLCD에 표시
⑤ 이 모두를 구동케 하는 전원 장치(스위치로 구동)
제품 결과
적외선 센서는 평균적으로 15cm 거리의 장애물을 인식합니다. 앞과 좌, 우의 인지로, 로봇이 움직이는 방향이 달라집니다. 만약, 1) 좌측에 장애물이 있다면 우측으로 방향을 정하고 90도 각도로 회전해 움직입니다. 2) 좌측과 우측에 모두 장애물이 있을 시 180도 각도로 회전해 반대 방향으로 움직입니다. 3) 장애물이 없을 시 계속 전진합니다. 이 구동은 실외나 실내 모두 작동됩니다.
GLCD는 LCD보다 더 세밀한 장치입니다. 원래는 LCD를 하려고 했지만, 더 큰 과제로 GLCD로 도전해 보았습니다. GLCD는 픽셀로 제어해서 LCD보다는 더 정밀한 형태들을 만들 수 있었습니다. 특히, LCD는 영문자와 다른 기호 등 정도만 제어할 수 있지만, GLCD는 우리가 만들 수 있으면 한글로도 표시가 가능했습니다.
작품을 만들면서 최대한 무게를 줄이고 크기는 작게 하는 방식으로 생각했습니다. 그러기 위해선 속도보단 최소한의 안정된 경도를 유지하고 각종 센서들에 붙여진 모듈을 제거하려고 노력하였습니다. 그래서 ATmega128과 연결된 각종 PORT 보드를 안 쓰고 직접 이 MCU의 pin만 있는 상태에서 리드선을 납땜했습니다. 그리고 실외용으로 쓰이는 것도 감안하여 플라스틱으로 된 바퀴보다는 고무로 된 바퀴로 대체하여 실외용에도 크게 손상되지 않게 만들었습니다.
작품에서 의외로 전원 장치를 만드는 것에 애를 많이 먹었습니다. 우리가 쓰고자 하는 센서들이 필요한 구동전압과 전류들이 각각 다르기 때문에 거기에 적합한 구동을 하기 위해서 익숙치 않은 회로설계를 하여야 했습니다. 그리고 전원 장치로는 스위치로 작동시키기 위해 슬라이드 스위치를 이용하였고 바로 건전지의 6V에 외부전원을 공급하면 회로가 상당한 열을 받는 것을 알게 되어 다이오드 등 내부 전압강하를 유도해 전원 전압을 각종 센서들이 작동할 수 있는 최소한의 전압으로 4.5V 내지 최대 5.1V까지 공급할 수 있게 하였습니다.
작품 설명
주요동작/특징
· 적외선 센서로 80~10cm의 거리를 인식, 그 안에 장애물을 피함.
· GPS 센서 모듈을 이용, 실외에 있을시 GPS 신호를 받으며 목표지점을 지정할 수 있음
· 받은 GPS 신호와 목표지점은 GLCD에 표시가 됨.
· ATmega128 Lite를 이용, 건전지 6V 전원으로 구동.
전체 시스템 구성
1. ATMEGA128을 활용, 전원 스위치로 전원을 제어.
2. DC 모터 드라이버를 활용해서 DC 모터를 제어하여 로봇 구동.
3.적외선 센서를 이용해서 장애물 감지.
4. 장애물을 감지하면 DC 모터가 그에 따라 각도 조절.
5. GPS 모듈을 사용해서 어떤 데이터가 들어오는지 로봇이 확인.
6. GPS 데이터를 GLCD로 전송.
7. GLCD에서 수신 받은 GPS 데이터를 확인하고 목표 좌표 데이터를 로봇으로 전송.
8. 로봇이 목표 좌표 데이터를 수신 받고 수신 받은 데이터를 하이퍼 터미널이나 GLCD로 확인.
9. 목표 거리만큼 소스 코드에 따라 DC모터 제어를 통해 주행.
10. 앞의 적외선 센서 프로그램 제어를 통해 목표 좌표로 가는 동안 장애물을 감지하면서 구동.
개발환경
1) 개발 언어 – C언어
2) Tool – 이클립스, AVR studio4.19, RS232_terminal
3) 사용 시스템 – 디지털 멀티 미터, power supply
단계별 제작 과정
1. 자동차 차체에 두 개의 DC 모터를 연결하였습니다. 앞에 구동하려는 바퀴는 따로 철물점상에 사온 작은 룰러 형식의 바퀴로 쓰이게 했고 로봇이 주행하는데 더 원활하게 움직일 수 있었습니다.
2. DC 모터는 나사와 모터 고정대를 이용, 접착제와 함께 단단하게 부착시켰습니다.
3. 모터 드라이버는 차체 내 가운데에 부착시켰고, 드라이버에 선이 있어 DC 모터와 연결하고 MCU PORT B에 10p 커넥터로 연결했습니다.
4. PCB 기판은 기판의 모서리에 구멍에다 나사와 철막대 2개를 이용하여 고정시키고, 차체에 접착제를 붙였습니다.
5. 로봇의 배터리는 원활하게 전류가 흐르게 하는 것과 동시에, ATmeg128에 외부 단자가 아닌 내부 전원 5v을 공급하는데 효용성이 있다고 판단하여, 1.5V 알칼리 건전지 4개를 쓰게 되었습니다, 그래서 4개를 연결하는 소켓(6V)을 ATmega128의 외부전원으로 선택하였고 PCB 기판 아래에 부착시켰습니다.
6. 차체의 무게를 조금이라도 줄이기 위해 원래의 Atmega128을 모듈에서 빼고 PCB 기판에 부착시켰습니다. 여기에 구동전압을 최대 6V로 주지 않고 7805 IC 소자를 통해서 정전압 5V 직류로 구동되게 하였습니다.
7. PCB 기판 위에 GPS 센서 모듈을 4pin 소켓을 꽂아 고정시켰고 통신이 원활하게 유지되도록 ATmega128 uart 통신 pin에 직접 연결하였습니다.
8. 적외선센서 3개는 차체 앞에 간격을 동일하게 두면서 접착제로 고정시켰습니다.
9. 기판 아래에 회로선을 모터 드라이브, 적외선 센서, GPS 센서 모듈, GLCD 센서 모듈과 연결되는 포트들에 납땜하였습니다.
10. GLCD를 PCB 기판위에 ATmega128 PORT A와 PORT F에 기판 아래 pin에다가 납땜된 커넥터와 GLCD 모듈의 10p 커넥터와 연결하였습니다. GLCD에 표시되는 것은 현재 속도, 현재 좌표, 목표 좌표입니다.
11. 최종적으로 PCB 기판 위에 정리되지 않는 선들은 최대한 기판 아래 납땜하였고 기판 차체 사이에 보이는 연결선들을 접착제로 붙여 정리하였습니다. 위에서 보면은 UART 선들과 전원선을 제외하고는 연결선들이 거의 보이지 않게 하였습니다.
12.제품 소프트웨어 구성
· DC 모터 구동 소스
/*
Purpose: Go forward
Input: Void
Output: Void
*/
void forward()
{
PORTB=0×00;
PORTB|=0×02;
PORTB|=0×10;
PORTB|=0×04;
}
/*
Purpose: Read value from infrared sensor
Input: Pin number
Output: Value which is read from infrared sensor
*/
unsigned int read_adc(unsigned char ch){
ADMUX=ch|0×40; _delay_us(10);
ADCSRA|=0×40; while((ADCSRA&0×10)==0); ADCSRA|=0×10;
return ADC;
}
/*
Purpose: Interrupt service routine
Input: GPS Signal
Output: Parsed value
*/
ISR(USART1_RX_vect)
{
unsigned char RX;
int i;
RX=UDR1;
if(RX==’$’))//각각의 신호의 시작을 나타내는 것(GPS신호는 5개가 들어온다).
{
rx_buf[0]=’$’;
rx_cnt=1;
}
else if(RX==0x0A)//1개의 신호가 끝났음을 의미
{
rx_buf[rx_cnt++]=0;
if(strncmp(“$GPRMC”, rx_buf, 6)==0)/이번에 받은 신호가 우리에게 필요한 신호인지 확인
{
GPS_cut=strtok(rx_buf, “,”);//필요한 신호라 판단되면 ,을 기준으로 문자열을 나눈다.
for(i=0; GPS_cut; i++)
{
GPRMC[i]=GPS_cut;
GPS_cut=strtok(0, “,”);
}
strcpy(valid, GPRMC[2]);
strcpy(cur_lon, GPRMC[5]);
strcpy(cur_lat, GPRMC[3]);
strcpy(speed, GPRMC[7]);
}
rx_cnt=0;
}
else if(RX==0x0D)
rx_buf[rx_cnt++]=0;
else if(RX==’,’)
{
if(rx_buf[rx_cnt-1]==’,’)
rx_buf[rx_cnt++]=’0’;
rx_buf[rx_cnt++]=RX;
}
else if(RX==’*’)
{
if(rx_buf[rx_cnt]==’,’)
rx_buf[rx_cnt++]=’,’;
rx_buf[rx_cnt++]=RX;
}
else
{
if(rx_cnt<180)
rx_buf[rx_cnt++]=RX;
}
}
/*
Purpose: Input cmd to GLCD
Input: pinNumber and command
Output: Void
*/
void write_cmd(unsigned char cs, unsigned char cmd)
{
//check_bf();
LCD_CTRL = cs & CS_ALL;
SetE(1);
LCD_OUTP = cmd;
delay(1);
SetE(0);
delay(1);
LCD_CTRL=0×00;
delay(10);
}
/*
Purpose: Write data to GLCD
Input: Pin number and char
Output: void
*/
void write_data(unsigned char cs, unsigned char ch)
{
LCD_CTRL = (cs & CS_ALL) | DI;
SetE(1);
LCD_OUTP = ch;
delay(1);
SetE(0);
delay(1);
LCD_CTRL=0×00;
delay(10);
}
/*
Purpose: Clear glcd
Input: Void
Output: Void
*/
void lcd_clear(void)
{
unsigned char i, j, x, y;
LCD_CTRL=0×00;
write_cmd(CS_ALL,0x3f);
write_cmd(CS_ALL,0xc0);
x = 0xB8; /* X start address */
y = 0×40; /* Y start address */
for(i = 0; i <= 7; i++)
{
write_cmd(CS_ALL,x);
write_cmd(CS_ALL,y);
for(j = 0; j < 64; j++)
write_data(CS_ALL,0×00); /* clear CS1 and CS2 */
x++;
}
}
/*
Purpose: Initiation of glcd
Input: Void
Output: Void
*/
void lcd_init(void)
{
write_cmd( CS_ALL, DISPON );
write_cmd( CS_ALL, 0xc0 );
write_cmd( CS_ALL, 0xb8 );
write_cmd( CS_ALL, 0×40 );
}
/*
Purpose: Pointing and turn on lcd
Input: X, Y value
Output: Void
void PointXY(int xpoint, int ypoint){ //픽셀 단위로 x,y축으로
int point=0×01, value; 조정
int x1, y1, y2, y3;
x1=xpoint%128;
y1=ypoint%64;
y2=y1/8;
y3=y1%8;
compare[y2][x1]|=(point<<y3);
value=compare[y2][x1];
if(x1<64){
write_cmd(CS_ALL, x+y2);
write_cmd(CS_ALL, y+x1);
write_data(_CS1, value);
} else {
write_cmd(CS_ALL, x+y2);
write_cmd(CS_ALL, y+x1-64);
write_data(_CS2, value);
}
}
Purpose: Pointing and delete
Input: X&Y value
Output: Void
*/
void Point_Del(int xpoint, int ypoint){
int point=0×01, value;
int x1, y1, y2, y3;
x1=xpoint%128;
y1=ypoint%64;
y2=y1/8;
y3=y1%8;
compare[y2][x1]&=(~(point<<y3));
value=compare[y2][x1];
if(x1<64){
write_cmd(CS_ALL, x+y2);
write_cmd(CS_ALL, y+x1);
write_data(_CS1, value);
} else {
write_cmd(CS_ALL, x+y2);
write_cmd(CS_ALL, y+x1-64);
write_data(_CS2, value);
}
}
재료
· ATmega128 모듈(뉴티씨)
MUC는 ATmega128을 사용하였습니다. 뉴티씨 Lite 모델로 무게를 최소화하고 ADC, UART, LCD를 이용할 pin들은 따로 pin 포트를 사와 고정시키고 PCB기판 동박면에 센서 모듈을 장착시킬 수 있었습니다. 외부 전원은 5V-input 핀에 연결을 하였고 GPS센서는 UART1통신에 연결하였습니다. 리셋버튼으로 통신제어하기에도 용이했습니다.
· DC모터 & 듀얼 DC모터 드라이브(YS-2270/유틸전자)
저희는 DC모터를 가벼운 것으로 선택하였습니다. 세운상가에서 값싼 가격대에서 샀고 모터드라이버는 1.5A에 5V~12V까지 구동되는 걸로 구매했습니다. 빠른 속도를 요하는 게 아니라서 5V 내로 전압을 준 속도면 충분했습니다. 실제, 모든 센서 모듈과 같이 제어하고 나면 마지막으로 모터와 GLCD가 가장 전류를 많이 잡아먹었습니다. 나머지 센서들이 작동되고 두 센서가 모두 켜지기 위해서는 600mA까지 전류가 흘러야 구동이 되었습니다.
· 적외선센서(lk-dms) 3개
10cm-80cm정도 거리를 인식합니다. 구동전압은 4.5V-5.5V입니다. 적외선 센서는 3개를 이용하였으며, 각 VCC와 GND를 공통 VCC선과 GND선에 연결하였고, MCU의 PORT F.1,2,3 에 Vout선을 납땜하였습니다. 대체적으로 하이터미널로 확인한 바 15cm내외로 수신을 잘 받아내었습니다.
· GPS 센서모듈(us-technology-UST-SNR-GPS v2)
3.3V로 구동되는 GPS 센서는 위 그림처럼 위성신호에서 수신받은 데이터를 다시 MCU에 송신해줘야 하기 때문에 센서의 UART 통신모듈 핀 VCC/TX/RX/GND에서 GPS의 VCC와 GND는 연결해주고 TX를 MCU UART1 RX에 연결해줍니다. 위도, 경도에 PC를 연결하여 하이퍼터미널로 확인 또는 GLCD로 확인케 하였습니다.
위성신호 데이터는 ‘$GPRMC’라는 문장에서 나오는데 이 신호가 가는 것이 위도, 경도가 그 뒤를 따릅니다. ‘A’라는 문구가 뜨면 실내로 들어온 것이라 뜨게 됩니다.
· 정전압 레귤레이터 7805 소자
전원문제를 해결하는데 사용하였습니다. 1.5V 건전지 4개를 연결하여 6V 외부전원이 들어오는데 5V로 정전압을 공급해야 했습니다. 순간적인 전압의 흔들림으로 인한 리플값을 잡아주기 위해서 세라믹 콘덴서를 양쪽에 병렬로 설치하였습니다.
· GLCD 모듈(LG128643 LMD WH6V)
5V 구동전압을 가지고 128×64 dots 로 제어합니다. 이것을 픽셀이라 합니다.
완성품
작품후기
처음 시작했을 때 GPS 신호라든지 적외선 센서라든지 LCD라든지 제대로 배워본 적 없던 소자를 다루기 때문에 걱정이 정말 많이 들었다. 역시나 해보면서 너무 많은 것을 배워야 되는 일들이 한꺼번에 쏟아져서 자료들을 많이 검색해서 얻은 정보로 간신히 만든 정도이다. 처음 용산전자로 가서 모터가 뭔지도 모르고 시작했던 터라 물어보는 것도 시원찮아 꾸중도 많이 들었다. 같이 했던 조원과도 뜻을 맞추기도 힘들었고 계속할 수 있을지 계속 의문이 들었다.
얼마 안 된 시간에 조금씩 차체에서 원했던 모습들이 쌓여가는 것이 보여지는 걸로 위안 삼아 이를 악물고 버티면서 배워보려고 했다. 처음 소자를 구매하는 것부터 디바이스마트에서 제품 설명서를 보면서 이해할려고 최대한 노력하였다. 추운 날씨에 GPS를 실외에서 신호를 받아 가는 과정을 지켜보는 시간이 길어지면서 너무 힘이 들었지만, MCU를 샀던 사이트에서 소스를 가져와서 고쳐보고 다시 그 소스로 밖에서 확인하고 하는 과정을 몇 십번씩 하면서 결국엔 GPS 신호를 처음으로 받아봤던 기쁨은 잊을 수 없다. 역시나 완성품이라고 하기에는 볼품이 없는 것 같다. 다른 학생들이 작품을 보면서 우리들이 쏟아부었던 노력들을 쌍그리 무시할 정도로 냉담히 평가하면 할 말이 없어진다. 하지만, 지금까지 이런 어려운 과제를 하면서 배우고, 실행하였던 과정들이 지금은 굉장히 뜻깊고 잘했단 생각이 든다. 앞으로 또 이런 과제로 주어지게 된다면 더 잘하고 싶다. 특히 GPS를 아직도 제대로 이해하지 못하여서 GPS관련한 걸로 하고 싶다.