[53호]어린이와 노약자를 위한 휴대용 타격게임
1. 심사평
칩센 학생다운 재미있는 작품으로 판촉활동에 도움이 될 것 같습니다. 좀 더 눈에 띄는 리액션이 있었으면 좋았을 것 같습니다.
뉴티씨 딱밤의 세기를 측정하는 실내용 게임을 제작한다는 재미있는 설정으로 시작된 프로젝트네요. 친근하고 재미있게 작품을 만들면서, 여러 가지 기술을 습득할 수 있는 기회가 되었다는 점에서 좋은 점수를 얻었지만, 전반적인 완성도나, 작품을 보는 사람들의 이해도의 측면에서 조금 더 디자인적인 측면을 고려하였으면 하는 아쉬움이 남는 작품이었습니다. 하지만, 여러 가지 내부의 기술들을 모두 구현하려고 노력하여 구현한 점 등은 높은 점수를 드립니다.
위드로봇 압력 센서를 활용하여 ‘딱밤’의 세기를 측정하는 게임을 만든다는 아이디어가 재미있습니다. 전체적인 작품의 완성도 잘 되었습니다만 보고서에서 결과에 대한 분석 및 기타 개선할 부분이 정리가 되면 더 좋았었을 것 같습니다.
2. 작품 개요
2.1. 주제
자신의 ‘딱밤’의 파워를 측정 할 수 있는 미니 게임기. 친근하고 포근한 이미지를 주기위해 마동석과 에뛰드 하우스를 모티브로 디자인한 귀여운 게임기
2.2. 개발 동기
길거리 펀치 머신을 이용하지 못하는 아이들이나 어른들을 위해서 집에서도 할 수 있는 작고 간단한 타격 게임을 만들고 싶었습니다. 길거리 펀치 머신은 날씨의 제약을 많이 받기 때문에 비가 오는 날이나 무척 추운 날에는 잘 하지 않게 됩니다. 심지어 건강한 성인들 중에서도 길거리 타격 게임을 이용하다가 다치는 경우가 일상 다반사입니다. 그래서 전 연령대가 집에서도 재미있게 할 수 있는 게임을 만들어보고자 싶었습니다. 미니 타격 게임을 생각하다가 모든 사람들이 잘 알고 있는 딱밤을 생각하게 되었고 그것을 주제로 친근한 에뛰드 하우스와의 콜라보로 제작하게 되었습니다.
3. 작품 설명
3.1. 주요 동작 및 특징
3.1.1. 사용 기술
① 타이머를 이용한 서보모터 2개 컨트롤
② Bluetooth를 이용한 핸드폰과 ATmega128통신
③ 압력센서를 통한 표적 인식
④ CLCD기능을 이용한 최고점수와 현재점수 표현
⑤ ADC를 이용한 LED제어
3.1.2. 동작 원리 및 시스템 구성
블루투스(HC-06)을 이용한 핸드폰 어플 블루투스터미널과 ATmega128의 Bluetooth 통신 기능입니다. 블루투스 칩의 Tx핀과 ATmega128의 PE0(Rx)핀을 가변저항을 이용하여 5[V]->3.3[V]로 변환하여 연결하고, 블루투스 칩의 Rx핀과 PE1(Tx)핀을 직접 연결하여 핸드폰과 ATmega128을 연결합니다. 블루투스 터미널 어플에서 설정한 세 가지 버튼(주먹, 보자기, 가위)을 선택하여 ATmega128에서 난수 함수(rand 함수 이용)를 발생시켜 얻은 세 가지 결과(주먹, 보자기, 가위)와 비교를 하여 승, 무, 패를 결정하여 핸드폰 어플 화면에 결과를 띄우고, 동시에 ATmega128로 결과를 전송합니다.
void Timer_init()
{
ETIMSK = (1 << TOIE3); // timer 3 overflow
TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
// TIMER1 비교일치 COM1A. COM1B 사용
TCCR1B = (1 << WGM3) | (1 << WGM12) | (1 << CS11) | (1 << CS10);
// 분주비 64, 입력캡처 사용
TCCR3A = 0×00; // timer 3
TCCR3B = 0×04; // 분주비 256 사용
ICR1 = 4999; // 입력캡처 사용 – > 50Hz
TCNT3H = 0xFF; // 처음 타이머 초기값이라 필요 없음 아무값 상관 X
TCNT3L = 0×05;
}
타이머 1번과 3번의 자체 타이머를 이용하여 서보모터 2개를 동시에 컨트롤함으로써 블루투스와 연결된 가위바위보 게임에서 블루투스 가위바위보 중/이겼을 시/ 졌을 시에 모터를 움직임으로 표적의 이동을 나타내는데 표적 제어는 서보모터(MG-995)를 이용하여 표적을 계속 좌우로 움직이게 하였습니다.
void ADC_init()
{
ADMUX = (0 << ADLAR) | (0 << REFS0) | (0 << REFS1); // AREF 사용 , ADC 0 사용
ADCSRA = (1<<ADEN) | (1 << ADSC) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // 프리스케일 128 분주비랑 adc 허용
}
압력센서(FSR-402)를 이용하여 표적을 인식합니다. 이 센서에 힘이 가해지면 저항값이 낮아지게 되고, 위의 회로와 같이 전압 분배 법칙을 이용하였습니다. 입력된 ADC값은 0~5[V] 값으로 Atmega128의 PF0핀으로 입력을 받습니다. 회로를 구성할 때 가변저항을 같이 사용했기 때문에 눌렀을 때 전압이 증가하는 전압 비를 조절할 수 있고, 가변저항을 돌리는 방향에 따라 조금만 눌러도 5[V]가 되기도 합니다. 이를 이용하여 딱밤의 세기를 조절할 수 있습니다.
현재 사용하고 있는 가변저항 10[]이고 값은 2.43[]입니다. 레지스터는 ADMUX이고 기준전압은 AREF로 5[V] 어댑터를 이용하여 기준전압을 설정했고, ADMUX = 0×00을 넣어 ADC0를 사용했습니다. ADCSRA 레지스터로 프리스케일을 허용해주고, 분주비는 128로 설정했습니다.
Vref값은 ADC값을 받은 후 다른 변수에 저장하여 계산하였는데 계산식은 (*ADC0) = (float) (*temp) * 512.0 / 1024.0 로 계산하였습니다. 앞에 별은 C언어에서 포인터를 사용하였기 때문에 적어준 겁니다. 10bit는 1024기 때문에 이 계산식을 이용하면 0부터 511까지 값을 얻을 수 있습니다.
void LCD_init()
{
_delay_ms(75);
write_instruction(0×30); // 기능 설정 데이터 길이 8비트,표시행수 1행, 문자폰트 5*7도트 사용
_delay_ms(25);
write_instruction(0×30);
_delay_ms(5);
write_instruction(0×30);
_delay_ms(5);
write_instruction(0x3C); // 기능 설정 데이터 길이 8비트, 표시행수 2행, 문자폰트 4*10도트 사용
_delay_ms(5);
write_instruction(0×08); // 화면표시 OFF, 커서 OFF, 커서 위치에 있는 블링크 기능 OFF
_delay_ms(5);
write_instruction(0×01); // 화면 모두 지움, 커서가 홈위치로 돌아감
_delay_ms(5);
write_instruction(0×06); // 엔트리 모드셋, 커서의 진행방향 오른쪽+방향, 화면자동시프트 OFF ( ON 설정시 화면이 자동으로 밀려서 감)
_delay_ms(5);
write_instruction(0x0c); // 화면표시 ON , 커서 OFF ,커서 위치에 있는 블링크 기능 OFF(블링크 ON설정시 커서 부분에 검은색 깜빡임)
_delay_ms(5);
}
CLCD 기능을 이용하여 압력센서에서 변환된 ADC 값을 변수로 받아 CLCD에 숫자 값을 표시해 줍니다. 여기서 처음 주목해야할 CLCD에 PIN은 4번입니다. CLCD 4번을 이용하여 CLCD를 초기화하여 사용 가능하게 하고, 데이터 입력이 가능한 상태로 만듭니다. 그리고 PIN 5번에서 데이터를 쓰거나 읽는 것을 조정할 수 있어 PIN 4번과 5번을 이용하여 ADC 값을 받아서 CLCD에 데이터를 쓸 수 있게 CLCD를 준비시킵니다. 우리가 받을 ADC값은 치는 사람에 따라 숫자 값이 0~511까지 변합니다. 그래서 이 숫자 값을 변수로 지정을 해서 CLCD로 입력을 시켜야 하지만 CLCD는 3자리 변수를 받지 않으니 SCORE라는 변수를 지정하고
(int)Score/100, (int)Score/10%10, (int)Score%10을 이용하여 숫자를 백의자리 십의자리 일의자리 수로 나눕니다. 이렇게 하나씩 떼어진 숫자에 +‘0’을 해줌으로써 CLCD에 아스키 코드의 값이 들어갈 수 있게 해주어 ADC에서 계산된 값을 CLCD pin 7~14번으로 넘겨 데이터를 써줄 수 있습니다. 이 원리로 사용자가 압력센서에 가한 압력의 크기를 측정해 실질적으로 자신의 That-Bam 파워 수치를 확인 가능하게 해줍니다.
void LED_control(int temp) // LED 제어 함수
{
int Floor = 0;
while(temp>0)w
{
if(Floor == 0){
Floor = 1;
}
else
Floor = (Floor << 1)+1;
temp–;
}
PORTC = Floor;
}
LED 제어 소스 설명
temp 변수는 0~512로 변환된 ADC값을 128로 나누고 1을 더하여 0~8 사이값으로 변환해놓은 값을 인자로 받는 변수입니다. 따라서 Floor라는 변수를 선언하고 temp를 0이 될 때 까지 마이너스 해주면 크기에 비례하는 LED값을 PORTC로 출력할 수 있게됩니다.
위에서 나온 압력센서 제어와 비슷하게 ADC를 이용합니다. LED는 압력센서로 받은 전압을 ADC로 변환 하고, 그 값을 즉각적으로 8개의 비트로 나누어 LED에 크기에 비례하는 LED를 켜주게 됩니다. 전체를 켜지 않고, Shift register를 이용하여 8개중 크기에 비례하게 1개씩만 들어오게 했으며, 크기가 0일때는 모든 LED에 불이 들어오지 않습니다.
3.2. Software Architecture (소프트웨어 구조)
위 그림은 프로그램의 진행을 나타내는 순서도입니다. 왼쪽의 그림은 핸드폰에서의 순서도, 오른쪽 그림은 Atmega128에서의 순서도입니다.
주요 동작과정은 Atmega128쪽에 표시되어 있습니다.
각 순서도를 참고하면, 프로그램의 동작 방법을 알 수 있습니다.
3.3. System Architecture (시스템 구조)
위의 그림은 시스템 구조를 블록다이어 그램으로 나타낸 그림입니다.
Atmega128에서 외부 기기를 제어할 때 사용한 기능들을 표시하였습니다.
화살표에 제어를 하는 기능들이 어떤 역할을 수행하는지 표시해 놓았습니다.
블록다이어그램을 보면 이번 프로젝트에서 설계한 하드웨어가 어떤 식으로 동작하는지 대략적으로 알 수 있습니다.
3.4. 개발 환경(개발 언어, Tool, 사용 시스템 등)
3.4.1. 주요 구성 부품
기본 부품
서보모터 (MG-995)
최대 120 degree까지 움직일 수 있습니다. 주파수를 50Hz(주기 20ms)로 맞추면 duty 비를 조절하여 모터를 제어할 수 있다.
Operating voltage : 4.8 ~ 7.2 [V]
압력센서 (FSR-402)
최대 10KG의 하중까지의 값을 측정할 수 있다. 압력센서는 0.45[]~100[] 사이의 저항값을 가지고 있는 소자입니다.
왼쪽에 그림에서 보면 소자에는 2개의 핀이 존재합니다. 한쪽에는 VCC를 연결하고 한쪽에는 ADC를 연결해주면 사용할 수 있습니다.
3.4.2. 개발 환경
개발언어 : C programming
개발Tool : AVR Studio
4. 단계별 제작 과정
5. 기타(회로도, 소스코드, 참고문헌 등)
5.1. 회로도
5.2. 참고 문헌
Atmega128 데이터 시트 (http://www.alldatasheet.co.kr/)
6. 완성사진