[14호] 2011 캡스톤 디자인 공모전 우수상- 보행보조기구 2부
4. 제어부
4.1 작동 프로세스
4.1.1 작동 프로세스 개요
RF MODEM A3007B는 UART 통신 방식을 지원하므로 목발의 MCU와 UART 방식의 통신을 한다. 목발의 MCU는 목발 밑에 부착된 스위치가 ON이 되거나 일어서기/앉기 스위치가 ON이 될 경우에 RF Modem이 해당 모드에 맞는 신호를 보내도록 한다. RF Modem 간의 통신을 통해 메인 MCU가 신호를 받아들이면 RS485 통신 방식을 사용하여 2개의 모터컨트롤러가 작동될 수 있도록 한다. RS485는 1:n의 통신방식을 지원하기 때문에 2개의 통신포트를 가지고도 여러 개의 통신을 할 수 있다. 메인 MCU의 UART0 포트는 RF Modem의 수신부와, UART1의 포트는 2개의 컨트롤러와 각각 연결된다.
기존목발에 스위치를 부착하여 양 목발이 순차적으로 ON 상태가 되면 모터가 작동하여 걸음이 가능하도록 설계한다. 스위치와 모터의 연결은 RF Modem을 사용한 무선통신으로, 보행에 방해가 되지 않게 한다.
4.1.2 걷기
양 목발이 동시에 땅을 짚을 경우, 4점 보행법으로 작동한다. 고관절부의 엉치뼈에 장착된 모터가 1차로 구동이 되어 허벅지 부분을 들어 올려주며, 순차적으로 무릎 부분의 모터가 구동을 시작하여 무릎을 일정한 각도까지 굽혀준다. 허벅지 부분의 모터 구동이 잠시 멈추면 무릎 부분의 모터가 작동하여 보행이 가능한 일정각도까지 무릎을 펴줌과 동시에 장애인은 목발에 하중을 싣고 몸을 앞으로 숙여 발바닥이 땅에 닿도록 한다. 한쪽 발바닥이 발바닥에 고정되고 목발에 일정한 압력이 다시 가해지면 반대쪽 발이 같은 원리로 구동을 시작한다.
4.1.3 앉기/일어나기
의자에 앉거나 일어나는 경우는 목발에 부착된 별도의 스위치를 사용하여 구동하도록 한다. 스위치를 사용하여 앉는 경우엔 무릎부의 모터가 중심이 되기 때문에 걸을 때에 비해 큰 각도로 회전하며, 엉치뼈 부분의 모터가 추가적으로 회전하여 허리를 숙이게 함으로써 의자에 앉는 것이 가능하게끔 한다.
일어나는 경우, 모터가 앉는 경우와 반대로 회전하여 일어서는 것을 도와준다. 이 때, 사용자는 최대한 목발에 의지해 몸의 무게중심을 앞으로 쏠리게 하여 무릎부분 관절에 가해지는 힘을 분산시키도록 한다.
4.2 회로도
4.2.1 전원부
4.2.2 스위치 및 LED
4.2.3 RF Modem 회로
4.3 작동 소스
사용 프로그램 | ATMEL사에서 제공하는 AVR Studio프로그램을 사용.
4.3.1 RF Modem(송신부)
RF Modem 송신부(앉기/일어나기) 소스보기
#include <avr/io.h>
#include <util/delay.h>
// RF로 송신 할 값을 캐릭터 함수로 설정
//HEAD(0xAA,0xBB, OP code(주파수 311/송신 12 + 송신할 문자)
char RF_FREQ_SET[5]={0xAA,0xBB,3,1,1}; //주파수 세팅
char RF_TX0_STAND[6]={0xAA,0xBB,1,2,1,1}; //일어서기 모드
char RF_TX0_SIT[6]={0xAA,0xBB,1,2,7,7}; //앉기 모드
char RF_TX0_WALK[6]={0xAA,0xBB,1,2,5,5}; //걷기 모드
void TX0_CH(char ch){ while(!(UCSR0A&0×20)); UDR0=ch; }
int main(void) //메인 함수 구문
{
char i; //캐릭터함수 i 설정
DDRA=0xFF; DDRF=0×00; DDRE=2;
//PORTA 출력, PORTF 출력 TXD0 PORTE.1
UCSR0A=0; UCSR0B=0×18; UCSR0C=6; UBRR0H=0;
UBRR0L=103;
// UART0 통신관련 레지스터 설정 , BAUD RATE 9600bps
_delay_ms(100);
// RF 주파수 세팅
for(i=0;i<5;i++)TX0_CH(RF_FREQ_SET[i]);
_delay_ms(1000);
while(1)
{
//delay();
if((PINF&0×04)==0×00) // PORTF에 연결된 2번 스위치를 누르면
{
for(i=0;i<6;i++)TX0_CH(RF_TX0_STAND[i]); //STAND값 송신
_delay_ms(1000);
}
if((PINF&0×10)==0×00) // PORTF에 연결된 4번 스위치를 누르면
{
for(i=0;i<6;i++)TX0_CH(RF_TX0_SIT[i]); //SIT 값 송신
_delay_ms(1000);
}
if((PINF&0×01)!=0×00) // PORTF에 연결된 1번 스위치를 누르면
{
for(i=0;i<6;i++)TX0_CH(RF_TX0_WALK[i]); //WALK 값 송신(left_on)
_delay_ms(1000); }
while(PINF&1); // 누르고 있는 동안은 한 번만 함수 호출
}
}
RF Modem 송신부 소스보기
#include <avr/io.h>
#include <util/delay.h>
// RF로 송신 할 값을 캐릭터 함수로 설정
//HEAD(0xAA,0xBB, OP code + (주파수 311/송신 12 + 송신할 문자)
char RF_FREQ_SET[5]={0xAA,0xBB,3,1,1}; //주파수 세팅
char RF_TX0_WALK[6]={0xAA,0xBB,1,2,4,4}; //걷기 모드
void TX0_CH(char ch){ while(!(UCSR0A&0×20)); UDR0=ch; }
int main(void) //메인 함수 구문
{
char i; //캐릭터함수 i 설정
DDRA=0xFF; DDRF=0×00; DDRE=2;
//PORTA 출력, PORTF 출력 TXD0 PORTE.1
UCSR0A=0; UCSR0B=0×18; UCSR0C=6; UBRR0H=0; UBRR0L=103;
// UART0 레지스터 설정 , BAUD RATE 9600bps
_delay_ms(100); //딜레이 1초
for(i=0;i<5;i++)TX0_CH(RF_FREQ_SET[i]);
// i의 숫자가 0에서 4까지 커지는 동안 RF는 주파수 세팅
_delay_ms(1000);
while(1)
{
if((PINF&0×01)!=0×00) // PORTF에 연결된 1번 스위치를 누르면
{
for(i=0;i<6;i++)TX0_CH(RF_TX0_WALK[i]); //WALK 값 송신(right_on)
_delay_ms(1000); }
while(PINF&1); // 누르고 있는 동안은 한 번만 함수 호출
}
}
4.3.2 RF modem(수신부) :main MCU
RF Modem 수신부 소스보기
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
typedef unsigned char BYTE;
#define BAUD_HIGH 00 //baudrate가 high일때 설정
#define BAUD_LOW_M 8 // 모터의 bps는 115200으로 설정
#define BAUD_LOW_RF 103 // RF모뎀의 bps는 9600으로 설정
#define ALL_FLAG_CLEAR 0×00
#define USATR_RECEIVER_ENABLE 0×10
#define USATR_TRANSMITTER_ENABLE 0×08
#define USATR_CHARACTER_SIZE 0×06
//TXD, RXD 설정
#define RXC_FLAG 0×80
#define TXC_FLAG 0×20
#define COM1 1
//
static int uart_putchar(char c, FILE *stream);
static FILE mystdout=FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
volatile BYTE movement;
volatile char RF_FREQ_SET[5]={0xAA,0xBB,3,1,1}; //RF 주파수 세팅
volatile int MODE, right_on=0, left_on=0, standing=0, sitting=0;
//
void TX0_CH(char ch){ while(!(UCSR0A&0×20)); UDR0=ch; } // UART0 송신 함수
//
ISR(USART0_RX_vect){ // Interrupt Service Routine
char ch;
ch=UDR0; //UDR0의 값을 ch에 저장
if(ch==7)sitting=1; // 만약 ch가 7이면 sitting ==1
else if(ch==1)standing=1; // ch가 1이면 standing ==1
else if(ch==4)right_on=1; // ch가 4이면 right_on ==1
else if(ch==5)left_on=1; //ch가 5이면 left_on ==1
}
//
void initialize_serial(void){ // initialize_serial 함수 정의
UBRR1H=BAUD_HIGH; UBRR1L=BAUD_LOW_M; // UDR1 레지스터 설정
UCSR1A=ALL_FLAG_CLEAR; //
UCSR1B=USATR_RECEIVER_ENABLE | USATR_TRANSMITTER_ENABLE;
UCSR1C=USATR_CHARACTER_SIZE;
}
//
static int uart_putchar(char c, FILE *stream){
if(c==’\n’) uart_putchar(‘\r’, stream);
if(MODE==COM1){ loop_until_bit_is_set(UCSR1A, UDRE); UDR1=c; }
return 0;
}
//
void TX1_CH(char ch){ while(!(UCSR1A&0×20)); UDR1=ch; }
// UART1의 송신함수
//
void setting(){ // 모터 세팅 함수
unsigned volatile char i;
BYTE SendBuff[256]={0};
PORTA=0xff;
MODE=COM1;
// 컨트롤러 세팅값 (SS2000,2000, Ss200,200, SM0202, PE0001 .. ) 전송
// 모터 컨트롤러에 각각 채널 1,2로 값을 전송함
// 0×01 :1번 컨트롤러ID 0×02 : 2번 컨트롤러 ID
memset(SendBuff,0,sizeof(BYTE)*256); //초기화
SendBuff[0]=0×01; sprintf(&SendBuff[1],”SS2000,2000!”); _delay_ms(1); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”Ss200,200!”); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”SM0202!”); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PE0001!”); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”SS2000,2000!”); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”Ss200,200!”); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”SM0202!”); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PE0002!”); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
}
//
void standing_M(){ // 모터의 일어나기 동작을 정의
unsigned volatile char i;
BYTE SendBuff[256]={0};
MODE=COM1;
//위치 제어 PA 명령어를 사용하여 위치값 전송
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA5200000,5000000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PA4800000,5000000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(10000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA5200000,5500000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PA4800000,4500000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(10);
memset(SendBuff,0,sizeof(BYTE)*256);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(1000000);
_delay_ms(100000);
_delay_ms(10000);
_delay_ms(100000);
_delay_ms(10000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA4800000,5500000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(1);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PA5200000,4500000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(100);
}
//
void walking_M(){ // 모터의 걷기 동작을 정의
unsigned volatile char i; // 캐릭터 함수 i 설정
BYTE SendBuff[256]={0};
PORTA=0×00; // PORTA의 LED가 꺼짐
MODE=COM1;
_delay_ms(100);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA5200000,5500000!”); _delay_ms(100); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]);
_delay_ms(1000);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA5200000,5100000!”); _delay_ms(100); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA5200000,5500000!”); _delay_ms(100); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA4800000,5500000!”); _delay_ms(100); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]);
_delay_ms(100);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PA4700000,4500000!”); _delay_ms(100); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]);
_delay_ms(100);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PA4700000,5000000!”); _delay_ms(100); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PA5200000,4500000!”); _delay_ms(100); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]);
_delay_ms(10);
}
//
void sit_M(){ // 앉기 동작 정의
unsigned volatile char i;
BYTE SendBuff[256]={0};
PORTA=0×00;
MODE=COM1;
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA4800000,5500000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(10);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PA5200000,4500000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(10);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(100000);
_delay_ms(10000);
_delay_ms(10000);
_delay_ms(10000);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA4800000,5000000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(10);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PA5200000,5000000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(10);
_delay_ms(100000); _delay_ms(100000); _delay_ms(100000); _delay_ms(100000);
_delay_ms(100000); delay_ms(100000); _delay_ms(100000); _delay_ms(10000);
_delay_ms(100000); _delay_ms(100000); _delay_ms(100000); _delay_ms(1000);
_delay_ms(1000); _delay_ms(10000);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×01; sprintf(&SendBuff[1],”PA5000000,5000000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(10);
memset(SendBuff,0,sizeof(BYTE)*256);
SendBuff[0]=0×02; sprintf(&SendBuff[1],”PA5000000,5000000!”); _delay_ms(10); i=0; while(SendBuff[i])TX1_CH(SendBuff[i++]); _delay_ms(10);
}
//
int main(void){
char i;
left_on=right_on=sitting=standing=0;
DDRA=0xff;
DDRE=2;
DDRG=0b11000000;
UCSR0A=0; UCSR0B=0×98; UCSR0C=6; UBRR0H=0; UBRR0L=103;
//UART0 레지스터 설정, BAUD RATE 9600bps
PORTA=0xff;
initialize_serial(); //초기화
_delay_ms(1);
stdout=&mystdout;
_delay_ms(1000);
for(i=0;i<5;i++)TX0_CH(RF_FREQ_SET[i]); //RF 주파수 세팅
_delay_ms(1000);
sei(); //인터럽트 허용
while(standing==0); //standing==1이 될 때 까지 대기
while(left_on==0); //right_on 과 left_on 둘다 1이 될 때까지 대기
PORTA=0×00;
setting(); // 모터 세팅 호출
_delay_ms(10000);
_delay_ms(10000);
standing_M(); //딜레이 후 일어서는 동작 호출
while(1){
//left_on과 right_on이 둘다 1이라면 걷기 동작 호출
left_on==0;
if((left_on&right_on)==1){
walking_M(); left_on=0; right_on=0; } //함수 호출 후 left_on=0으로 초기화
//sitting==1이 되면 앉기 동작 호출
if(sitting==1){
sit_M(); sitting=0;
}
}
return 0;
}
5. 제작 과정
5.1 부품 사진
5.1.1 설계부
허벅지 관절부와 무릎 관절부 발목을 잇고, 지탱해주면서 몸에 최대한 밀접하게 붙게 하는 뼈대 브라켓이다.
5.1.2 제어부
5.2 조립 사진
5.3 제작 과정
6. 결론
6.1 설계 쪽 실패과정 & 해결방안
전체적인 기구부가 커지는 것을 막기 위해 모듈1의 베벨기어박스를 사용하였으나, 소형 베벨기어였기 때문에 큰 토크에서 견디는 힘이 부족했다. 기구부만 작동시키는 데에는 큰 무리가 가해지지 않았으나 사람이 착용하고 구동한 경우, 앉기 동작에서 문제가 발생하였다. 사람이 의자에 앉는 경우 하중이 뒤로 자연스레 쏠리는 것을 미처 계산하지 못한 바람에 기어 이빨이 손상된 일이 있었다.
따라서 무릎에 가해지는 토크를 보다 잘 견딜 수 있도록 기존보다 큰 2.5 모듈의 베벨기어로 바꾸었다. 결과적으로 이빨의 크기가 커져서 전체적인 기어박스 및 기구부의 크기도 덩달아 커졌지만 상대적으로 견딜 수 있는 토크의 크기도 커졌다.
6.2 제어 쪽 실패과정 & 해결방안
ATmega128 보드를 직접 만들기 위해 브래드 보드에 꽂아 실험할 수 있는 UST-MPB-ATmega128 제품을 이용하여 기본적인 회로들을 확인하였다. 납땜을 하기 전 RF 모뎀 회로를 체크하기 위해 브래드 보드로 전원 회로 및 기본적인 송수신 회로를 작성한 후, PCB에 납땜을 하였다. 기본적인 RF 회로 및 스위치 회로는 납땜을 하여 확인을 하였으나, max232 회로 등이 제대로 작동을 하지 않았으며 잦은 브래드 보드 실험 및 전원 회로부에서 꼬인 회로들로 인해 대부분이 쇼트가 나서 max232의 회로를 확인할 수가 없었다. 보드를 다시 제작하려 했으나, 시간상의 문제로 보드를 다시 만들 수 없다고 판단하여 보드 옆에 회로 판이 부착된 개발보드 기능의 AVR 모듈을 이용하였다. 이 AVR 보드에 RF modem 회로 및 필요한 스위치 회로만 추가로 납땜을 해서 필요한 보드를 완성하였다.
기존의 통신방식은 RS232통신을 이용하는 것이어서 추가의 회로가 필요하지 않았지만 후에 RS485로 통신방식을 바꾸면서 RS485와 관련된 회로가 필요하게 되었다. SN75176이란 IC를 사용하여 통신을 할 생각이었으나, 추가적인 회로를 납땜하는 것보다 컨버터를 이용하는 편이 효율적이라 판단하여 MOXA사의 TCC-80 이라는 RS232 to RS485 컨버터를 사용하였다.
구동 프로세스가 목발에 연결된 스위치에 힘을 가하면 목발 쪽 RF가 메인보드에 신호를 송신하고 이러한 RF신호 2개가 메인보드에 수신되어야만 모터가 작동하는 것이라서 컨트롤러 2개, RF modem까지 총 3개의 통신포트가 필요했다. 모터 제어부와 RF 제어부를 따로 작업하다보니 UART방식과 RS232 통신 방식이 충돌이 날거라는 것을 고려하지 못하였다. 그 문제점을 해결하기 위해 메인 MCU를 2개 사용하는 것으로 진행하였었다. MCU를 2개 사용하여 연동하는 것보다 1:n의 통신이 가능한 RS485방식을 택하는 게 효율적이라 판단하였고, 이를 통해 포트 2개로 2개의 컨트롤러 RF modem까지 3개의 통신을 해결할 수 있게 되었다.
6.3. 결론
무릎 부분에 힘이 많이 걸리는 것을 고려하여 무릎부 기어를 2.5 베벨 기어로 선정하였고 통신방식은 RS485방식을 선택하여 보드의 개수를 줄일 수 있었다. 실제적인 작동의 경우 기구부만으로 앉고 일어서기 및 걷기 동작은 구현이 가능하며, 현재 사람이 착용한 채 동작을 구현하는 것은 부분적으로 가능하다. 앉기 및 일어서기 동작의 경우 사람이 착용한 채 동작을 구현할 수 있었으나, 걷기 동작의 경우 기구부를 착용하는 팀원이 아직 목발 사용에 익숙치 않아 걷기 움직임이 조금 부자연스러운 관계로 일반적인 걸음걸이의 형태로 각도를 제어하였다. 사람마다 걸음걸이 방식이 조금씩 다르기 때문에 팀원의 목발사용 연습과 함께 차후에 구현할 팀원의 걸음걸이에 맞춰 시연할 예정이다.
7. 팀원 소개 및 역할 분담
이수영 : 해석 및 RF 통신
홍준호 : 가공 및 조립
정그림 : 해석 및 3D Modeling
한솔 : 모터 제어