. 코드 및 구현 내용

#define F_CPU 16000000 
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h> 
#define OC1A_WIDTH OCR1A
#define OC1_PERIOD ICR1
// 실제 동작 clock hz를 설정하고, 코드구현에 앞서 AVR 기본 입출력관련 헤더파일과 지연함수 관련 헤더파일과 인터럽트 관련 헤더파일을 선언했다.
//이후, OC1A_WIDTH와 OC1_PERIOD를 각각 OCR1A와 1CR1로 정의합니다.
 

enum tone_scale 
{
No, Do, Rae, Mi, Pa, Sol, Ra, Si_P, Si, Do_5, Rae_5
};

 
uint16_t frequency_return(uint16_t fre); 
 
void tone(uint8_t scale, uint16_t delay);
  
uint16_t tone_array[11] = {0,1046,1174,1318,1396,1567,1760,1864,1975,2093,2349}; 
//enum함수를 사용하여 5옥타브 ‘도’부터 6옥타브 ‘레’까지 열거했다.
//PWM period to frequency를 정하는 frequency_return 함수를 정의해주며, 
//tone함수를 정의하여 주파수와 duration에 따라 다른 음을 출력하도록 설정하였다.

void delay_ms(int ms)
{
while(ms-- != 0)
_delay_ms(1);
} 
//tone 함수 내에서 delay함수에 대한 오류가 발생하여 해결하기 위한 방법으로 구글링을 통해 선언.

 
void Forward(uint8_t speed);
 
void Backward(uint8_t speed);
 
void Turn_left(uint8_t speed);
 
void Turn_right(uint8_t speed); 
//Tekbot의 방향을 함수로 선언한다. 직진, 후진, 좌로 돌기, 우로 돌기

void BuzzerN();
 
void BuzzerS();
 
void BuzzerL();

void BuzzerR();
 
void BuzzerB();
//출발 전 두개의 스위치가 눌릴 경우, 출발할 경우, 왼쪽 스위치가 눌릴경우, 오른쪽 스위치가 눌릴 경우, 두개의 스위치가 동시에 눌릴 경우에 따른 Buzzer음을 각각 함수로 선언

ISR(TIMER3_OVF_vect) 
{
 PORTB =0b00001000;
 
 PORTD =0b00000100;
 
 delay_ms(250);
 
  TCNT3 = 0xffff - 7812; // Every 1 second
} 
// 인터럽트 서비스 루틴으로 인터럽트가 발생 시 수행하는 코드이다. ISR이 실행될 경우 두 바퀴가 서로 반대로 돌게 설정하여 delay 시간 만큼 회전을 한 후에 
//TCNT3을 이용하여 다시 카운팅을 시작하게 만들어준다.
 
int main()
 
{
DDRB = 0b10101100; 
DDRD = 0b00000111; 
DDRF = 0b11111100;
 
PORTF=0b00000011; 
 
TCCR0A = 0b11110001; 
TCCR0B = 0b00000100; 
 
TCCR1A = 0b10000000; 
TCCR1B = 0b00010010; 
 
TCCR3A = 0b00000000; 
TCCR3B = 0b00000101; 
 
TIMSK3 = 0b00000001;
// 왼쪽 바퀴와 오른쪽 바퀴의 EN와 DIR_A, DIR_B에 해당하는 핀을 OUTPUT으로 설정해주며, 왼쪽 스위치와 오른쪽 스위치에 해당하는 핀을 INPUT으로 설정했다. 이 후, PORTF를 통해 각각의 스위치를 풀업저항으로 설정하고 TCCR(Timer/Counter Control Register)를 이용해 TCCR0과 TCCR1에는 PWM모드와 분주비에 대해 설정하며 TCCR3에는 인터럽트를 사용하기 위한 모드와 분주비를 설정했다. 마지막으로 TIMSK로 노말모드를 Enable로 Set 하였다.

sei(); //모든 인터럽트 활성화


while(1)	
{
   if(!(PINF &(1<<0)) &&!(PINF &(1<<1)))
  {
    BuzzerN();
    Forward(100);
    BuzzerS();
    TCNT3 = 0xffff-9000;
 	// PINF연산에 의해 두개의 스위치가 모두 눌릴경우 if문을 실행하게 된다. 그 외의 경우에는 다른 문을 실행하지 않는다.
    // if문안에서는 BuzzerN()함수에 의해 음이 출력이 된 후 Forward함수에 의해 100의 속도로 직진동작을  수행한다. 이때 BuzzerS()함수가 실행되며 음 출력이 끝난 후 부터 타이머/카운팅이 시작된다.
 
    while(1)
   {
   // 최초 if문이 실행 후 if문 안의 while문으로 들어와 무한 반복을 하게 되는데 이때, 왼쪽 스위치가 눌렸을 경우를 if문, 오른쪽 스위치가 눌렸을 경우를 else if문 아무것도 눌리지 않았을 경우를 else문으로 설정했다.
 
   if(!(PINF &(1<<0)))
    {
      if(!(PINF &(1<<1)))
       {
         TCNT3 = 0xffff-9000;
         Backward(190);
         BuzzerB();
         PORTB =0b00001000;
         PORTD =0b00000100;
         _delay_ms(90);
         Forward(100);
       }

      else
       {
         TCNT3 = 0xffff-9000;
         Backward(190);
         BuzzerL();
         Turn_left(100);
         _delay_ms(100);
       }
     } 
  // 왼쪽 스위치가 눌릴 경우 if문에 오른쪽 스위치가 눌릴 경우와 else문에 눌리지 않았을 경우를 설정하여 동시 검출과 왼쪽 스위치만 검출, 두 가지 경우를 설정했다.
  // 왼쪽 스위치가 눌리고 오른쪽 스위치도 눌릴 경우 설정한 TCNT부터 카운팅이 시작되며 그 동안 190의 속도로 후진하며 Buzzer음을 출력하고 이후 delay시간 만큼 회전을 하고 직진동작을 수행한다.
  // 왼쪽 스위치만 눌렸을 경우에는 마찬가지로 설정한 TCNT값 부터 카운팅이 시작되며 후진동작과 BuzzerL음이 출력되며 이후, 왼쪽으로 약 90도 회전동작을 수행한다

	else if(!(PINF &(1<<1)))
    {
     if(!(PINF &(1<<0)))
      {
        TCNT3 = 0xffff-9000;
        Backward(190);
        BuzzerB();
        PORTB =0b00001000;
	    PORTD =0b00000100; 
        delay_ms(90);
        Forward(100);
      }
 
    else
     {
       TCNT3 = 0xffff-13000; 
       Backward(190); 
       BuzzerR();  
       Turn_right(100);
       delay_ms(115);
     }
   } //else if문 
   // 오른쪽 스위치가 눌릴 경우 왼쪽 스위치가 눌렸을 때와 동일하게 if문과 else문에 동시검출과 한쪽 스위치 검출을 설정하여 동시검출시 위와 동일한 동작을 수행하며, 오른쪽 스위치만 눌렸을 경우 설정한 TCNT 값부터 타이머/카운팅이 시작된다.
   // 타이머/카운팅이 시작된 후 PWM에 의해 190의 속도만큼 후진동작과 BuzzerR음이 출력되며 오른쪽으로 약 90도 회전동작을 수행한다. 이 과정에서 타이머/카운팅이 0xffff에서 0x0000이 될 경우 오버플로우가 발생하여 인터럽트 서비스 루틴(ISR)이 실행하여 하던 동작을 멈추고 ISR함수를 실행한다.

else
       Forward(100);
 // 출발 후 스위치가 눌리지 않을 경우 Forward()함수를 실행해 직진동작만을 수행한다. 이때에도 ISR함수 내에서 타이머/카운터를 초기화해주었기 때문에 일정 시간이 지나면 인터럽트함수를 수행하게 된다.
  }
 }
}
return 0;
}
 
void Forward(uint8_t speed)

{
   PORTB =0b00001000;
   PORTD =0b00000010;
   OCR0A = speed+58;
   OCR0B = speed+25;
}

void Backward(uint8_t speed)
 
{
   PORTB =0b00000100;
   PORTD =0b00000100;
   OCR0A = speed+10;
   OCR0B = speed;
}
 
void Turn_left(uint8_t speed)
 
{
   PORTB = 0b00000000;
   PORTD = 0b00000010;
   OCR0A = speed+50;
   OCR0B = speed;
}

void Turn_right(uint8_t speed) 
 
{
   PORTB = 0b00001000;
   PORTD = 0b00000000;
   OCR0A = speed+50;
   OCR0B = speed;
}

void tone(uint8_t scale, uint16_t delay)  
{
   OC1_PERIOD = frequency_return(tone_array[scale]);  
   OC1A_WIDTH = frequency_return(tone_array[scale])/20;
   delay_ms(delay);
}
 

uint16_t frequency_return(uint16_t fre)
{
   int8_t period_1 = 2; // period 2us
   int set_period = 0;
   int16_t return_fre = 0; 
   set_period = 1000000 / fre;
   return_fre = set_period /period_1;
   return return_fre;
}
 
void BuzzerN()
{
   int dulation = 100;
   tone(Mi, dulation);
   tone(0, 60);
   tone(Mi, dulation);
   tone(0, 60);
   tone(Mi, dulation);
   tone(0, 60);
   tone(Do_5, dulation+50);
}
void BuzzerS()
{
   int dulation = 100;
   tone(Sol, dulation+30);
   tone(Mi, dulation-50); 
   tone(Sol, dulation+50); 
   tone(0, 60);
}
void BuzzerL()
{
   int dulation = 30;
   tone(Mi, dulation);
   tone(0, 20);
   tone(Sol, dulation);
   tone(0 , 20);
   tone(Sol, dulation); 
   tone(0 , 20);
   tone(Mi, dulation); 
   tone(0, 0);
   tone(Sol, dulation+50); 
   tone(0 , 20);
   tone(Ra, dulation);
   tone(0 , 20);
   tone(Ra, dulation);
   tone(0 , 20);
   tone(Sol, dulation);
   tone(0 , 20);
}
void BuzzerR()
{
   int dulation = 50;
   tone(Pa, dulation);
   tone(0, 5);
   tone(Pa, dulation);
   tone(0, 5);
   tone(Ra, dulation);
   tone(0, 5);
   tone(Ra, dulation);
   tone(0, 5);
   tone(Si_P, dulation+10);
   tone(Ra, dulation);
   tone(0, 5);
   tone(Si_P, dulation);
   tone(0, 5);
   tone(Rae_5, dulation);
   tone(0, 
   tone(Do_5, dulation);
   tone(0, 5);
   tone(Si_P, dulation);
   tone(0, 10);
}

void BuzzerB()
{
   int dulation = 50;
   tone(Si, dulation);
   tone(0 , 5); 
   tone(Ra, dulation);
   tone(0 , 5); 
   tone(Si, dulation);
   tone(0 , 5);
   tone(Ra, dulation);	
   tone(0 , 5);
}

 

구현 내용

 

1. 양 쪽 스위치를 누를 경우 BuzzerN 함수 실행 후 주행 시작

 

2. 주행 시작 후 BuzzerS 함수가 실행되며 앞으로 전진

 

3. 왼쪽 스위치가 눌릴 경우 BuzzerL 함수 실행과 동시에 뒤로 느리게 이동 후 왼쪽으로 회전 후 전진

 

4. 오른쪽 스위치가 눌릴 경우 BuzzerR 함수 실행과 동시에 뒤로 느리게 이동 후 오른쪽으로 회전 후 전진

 

5. 스위치 두개가 동시에 눌릴 경우 BuzzerB 함수 실행과 동시에 뒤로 느리게 이동 후 반 바퀴 회전을 하여 전진

 

6. 특정 시간이 지나면 타이머 카운터 인터럽트 발생(한 바퀴 회전)

 

 

. 문제점과 해결 방안

 

1. Tekbots 조립을 완료한 후 직진과 후진의 속도에 차이를 주기위해 PWM을 사용했으나 올바르게 작동하지 않았다.

=> PWM을 이용해 후진의 속도를 늦추는 코드를 구현하였지만 왼쪽 바퀴는 올바르게 작동하지만 오른쪽 바퀴는 PWM의 영향을 받지 않는 것을 발견하였고, 이에 따라 오른쪽 바퀴의 PWM을 결정하는 핀들의 납땜상태를 확인하고 재납땜을 하였으나 실패하여 모터컨트롤러보드와 Teensy보드를 처음부터 새로 정성들여 납땜을 하여 결과적으로 PWM이 정상적으로 작동하게 만들었다.

2. 코드 상으로는 서로 같으나 모터와 전류주입의 차이로 양 바퀴의 속도가 일정하지 않다.

=> 코드 구현 후 시범 주행을 하였을 때, 왼쪽 바퀴가 오른쪽 바퀴보다 빠르게 돌아 직진 시 오른쪽으로 휘는 현상이 발생하였고, 이를 코드상에서 OCR0A의 값을 변경(Speed+)시켜 양 바퀴의 속도를 비슷하게 만들었다.

3. tone함수 에러

=> 소리를 출력하기 위해 tone함수를 사용했으나 해결할 수 있는 방안이 떠오르지 않아 구글링을 하였고, 구글링을 통해 delay의 문제가 있다는 것을 식별하였고, delay함수를 따로 정의를 해주어 문제를 해결했다.

4. 버저소리 문제

=> 버저를 통해 나오는 소리가 USB를 컴퓨터와 연결하였을 때는 청아한 소리가 났으나 USB를 제거하는 순간 초저음의 소리가 출력되어 음을 식별하기 어려웠다. 그래서 tone의 주파수를 한 옥타브 올려 음을 식별할 수 있는 상태로 만들었다.

5. 시범 구동을 할 때마다 속도 및 인터럽트 발생시간, delay시간 등이 달라진다.

=> 컴퓨터와 USB를 연결한 상태로 코드를 구현하고 속도 및 인터럽트 시간 제어를 완료한 상태로 USB를 제거한 후 시범 구동을 했을 시 올바르게 작동하지 않았다. 전류 주입의 차이라고 생각하여 배터리를 새로 사서 갈아 끼웠으나 큰 차이가 나지 않아 코드 상의 값을 처음부터 새로 설정하여 구동 시범에서 올바르게 작동할 수 있게 하였다.

 

 

2. 소프트웨어

A. Arduino?

 AVR 기반의 마이크로컨트롤러 개발환경인 Wiring에서 파생한 프로젝트다. 아두이노는 다수의 스위치나 센서로부터 값을 받아들여, LED나 모터와 같은 외부 전자 장치들을 통제함으로써 환경과 상호작용이 가능한 물건을 만들어 낼 수 있다. , 임베디드 시스템 중의 하나로 쉽게 개발할 수 있는 환경을 이용하여, 장치를 제어할 수 있다.

 

아두이노의 특징

1. 저비용 = 다른 마이크로컨트롤러 플랫폼에 비해 저렴하다.

2. 크로스 플랫폼 = 다양한 운영체제에서 작동한다.

3. 간단하고 프로그래밍 환경 = 아두이노 프로그래밍 환경은 초보자가 사용하기 쉽다. 또한, 소프트웨어 개발을 위한 통합개발환경(IDE)이 제공되며 컴파일 된 펌웨어를 USB를 통해 손쉽게 업로드 할 수 있다.

4. 오픈 소스 = 아두이노 하드웨어 및 소프트웨어는 오픈 소스 툴이기 때문에 고급 프로그래머들에 의해 작성된 확장 소프트웨어 라이브러리들을 구할 수 있으며, 회로 설계자들이 손쉽게 자신만의 모듈을 만들고 개선할 수 있다.

 

=> 아두이노 통합 개발 환경은 소스 코드를 작성하고 편집할 수 있도록 하며, 코드를 아두이노 하드웨어가 이해할 수 있는 명령어로 컴파일하여 보드에 이를 업로드 하는 기능을 제공한다. 소스코드는 C++ 언어를 기반으로 하기 때문에 아두이노에서는 C 언어의 표준라이브러리 함수가 사용 가능하다.

 

Arduino를 통해 간단하게 teensy를 프로그래밍 할 수 있지만 이번 실험은 AVR Studio4를 사용하여 PWM 등을 이용해 모터제어, 속도제어, 인터럽트, 부저 등의 역할을 하게 하는 것이 주 목적이다.

 

B. AVR Studio?

AVR 마이크로 컨트롤러를 개발, 생산하고 있는 ATMEL사에서 무료로 제공하고 있는 IDE(통합 개발 환경)이다. 기본적인 구성으로는 어셈블러, 에디터, 디버거, 다운로더가 있다.

 

1. 어셈블러 = 어셈블리언어로 작성된 코드를 어셈하여 실행파일을 생성해내는 실행 코드 생성 프로그램

2. 에디터 = 각종 코드나 문서를 편집하는 편집기

3. 디버거 = 사용자가 작성한 코드의 논리적인 오류를 진단, 수정하기 위한 도구

4. 다운로더 = 사용자가 생성한 실행 코드를 보드에 전송하여 실행할 수 있도록 하는 프로그램

 

 

추가로 C 컴파일러가 있다. 이는 win AVR별도로 설치하여 AVR 스튜디오가 ‘win AVR’ 호출하여 컴파일을 완료한다.

 

C. GPIO

GPIOGeneral Purpose Input/Output의 약자로 다용도 입출력 포트를 말한다. GPIO는 마이크로프로세서가 주변장치와 통신하기 위해 범용으로 사용되는 입력 출력 포트로 정의 할 수 있다. GPIO는 설계자가 마음대로 변형하면서 제어할 수 있도록 제공해주는 I/O포트로 각각의 포트를 제어하기 위해서 포트당 3개의 I/O 레지스터 (DDRx, PORTx, PINx)를 가진다. 특징으로는 입력과 출력을 마음대로 선택할 수 있고, 01의 출력신호를 임의로 만들어줄 수 있는 구조를 가진다.

ex) 예를 들어, 입출력 A 포트의 상위 4개의 핀들은 출력 핀으로 사용하고, 하위 4개의 핀들은 입력 핀으로 사용하고 싶다면 다음과 같이 DDRA 레지스터 값을 설정해주면 된다

마찬가지로 입출력 A 포트가 모두 출력 핀으로 설정되어 있을 경우, 상위 4개의 핀 을 통해서는 High 신호가, 하위 4개의 핀으로는 Low 신호가 출력되도록 하고 싶다면다음과 같이 PORTA 레지스터 값을 설정하면 된다

입력일 경우엔 DDRA, PORTA 레지스터들과는 달리 사용자가 데이터(비트 값) 변경하는 게 아니라 외부와 연결된 주변 장치(부품)로부터 High 혹은 Low 신호가 입력되어 입출력 포트 컨트롤러(I/O Port Controller)에 의해 자동적으로 비트 값이 기록되기 때문에, PINA 레지스터의 8비트에 대응되는 8비트 변수(unsigned char변수)에 저장하여 읽어 보면 된다
PINA 비트 값을 읽어 보니 다음과 같다면 상위 4개의 핀으로는 High 신호가, 하위 4개의 핀으로는 Low 신호가 입력되었다는 뜻이다

AVRArduino에서 각각 PIN을 설정하는 법

pinMode(pin, status) -> DDRx = 0b00001111

digitalWrite(pin, status) -> PORTx = 0x0f

digitalRead(pin) -> button = PINx

 

D. PWM

PWM이란 Pulse Width Modulation의 약자로 PWM 제어라고 하면 펄스의 폭을 조정하여 부하에 전력의 크기를 조절하는 것이다. PWM의 장점은 기존의 구조에서 많은 변화를 주지않고 프로그래밍만을 통하여 손쉽게 제어가 가능하다는 것과 타이머 카운트를 사용할 경우 모터에 PWM신호를 주기 위해 프로세서에서 분담되는 작업량을 대폭 줄일 수 있다.

 

, 출력되는 전압값을 일정시간동안 HIGH로 유지하고 나머지는 LOW를 출력하여 사각파의 출력을 만들어 낼 수 있으며, PWM을 사용함으로서 0V5V 사이의 아날로그 값을 묘사할 수 있어 통신과 제어에 주로 사용한다.

 

 

예를 들어 LED에 같은 시간동안 위 그림의 펄스를 사용한다면 LED가 꺼졌다 켜졌다 하게 된다. 이때 Pulse Width넓을수록 LED가 오래 켜지게 된다.다시 말해 Pulse Width가 넓으면 넓을수록 한 주기 평균을 냈을 때 평균전압이 높아진다 라는 뜻이다. , Pulse Width가 한 주기일 때, 평균 전압은 입력전압의 100%이고, Pulse Width0일 때 평균 전압은 0%가 된다.여기서 %duty ratio(=Pulse Width*100 / Period) 라고 한다.

 

 

 

위와 같은 역할을 바탕으로 PWM은 주로 LED의 밝기 제어나, DC모터 속도 제어, 사운드 출력 등에 사용된다.

 

PWM 사용

타이머의 동작 모드가 Normal 모드, CTC 모드, Fast PWM 모드, Phase Correct PWM 모드로4개의 모드가 있다.

4개의 모드 중 Fast, Phase Correct PWM 모드가 타이머를 이용한 PWM모드이다.

 

Table을 통해 TCCR0A0번과 1번 비트와 TCCR0B3번 비트에 의해 Timer/Counter 모드가 결정된다. 또한, COM0A1COM0A0에 의해 설정이 달라진다.

 

1) Fast PWM 모드

00 : OCn 차단

01 : -

10 : (비반전 출력 모드) 비교 매치에서 OCn Clear, TOP->BOTTOM일 때 Set

11 (반전 출력 모드) 비교 매치에서 OCn Set, TOP->BOTTOM일 때 Clear 

 

 

2) Phase Correct PWM  

00 : OCn 차단

01 : -

10 : (비반전 출력 모드)(비교 매치 시)업 카운터에서 OCn Clear, 다운 카운터에 OCn Set

11 : (반전 출력 모드)(비교 매치 시)다운 카운터에서 OCn Clear, 업 카운터에서 OCn Set

 

 

 

 

 

 

 

Fast PWM Mode

 

 

 

TCNTn0x00~0xFF까지 갔다가 오버플로우가 되는 것을 반복한다.이때, OCRn값과 TCNTn값이 일치하면(비교 매치) OCn핀의 출력 값이 바뀐다.여기서 출력값은 모드에 따라 다르게 출력된다. 

 

비반전 비교 출력모드(TCNTn 밑에 있는 그림)일 경우에는 HIGH가 출력되다가, 비교 매치에서 OCn핀에 0이 출력된다. TCNTn0xFF에서 0x00으로 떨어질 때 다시 HIGH가 출력된다. 

 

반전 비교 출력모드(세번째 그림)일 경우에는LOW가 출력되다가, 비교 매치에서 OCn핀에 1이 출력된다. TCNTn0xFF에서 0x00으로 떨어질 때 다시 LOW가 출력된다.

 

 

 

 

 

 Phase Correct PWM

 

 

 

TCNTn0x00~0xFF로 갔다가 다시 0x00으로 감소한다. 하지만 Fast PWM 모드처럼 뚝 떨어지지는 않는다. 

 

비반전 출력 모드에서는업 카운트 중에(TCNTn값이 상승할 때) TCNTn=OCRn일 때 OCn핀에 0이 출력된다. 다운 카운트 중에 일치하면 1이 출력된다. 

 

반전 출력 모드에서는업 카운트 중에 TCNTn = OCRn이면 OCn핀에 1, 다운 카운트 중에 일치하면 0이 출력된다.

 

 

 

 

Fast PWM Phase Correct PWM의 차이

Fast PWM : 높은 주파수 PW

Phase Correct PWM : 높은 분해능 PWM

 

 

E. Interrupt

Interruptcpu가 프로그램을 실행하고 있을 때, 입출력 하드웨어 등의 장치나 또는 예외 상황이 발생하여 처리가 필요할 경우에 cpu에게 알려 처리할 수 있도록 하는 것을 말한다. , cpu가 다른 연산을 수행하고 있는 중에 특정 이벤트가 일어나면 즉시 하던 연산을 멈추고 발생한 이벤트를 처리하기 위한 연산을 수행하게 된다.

 

 

Table에 의해 Normal, Phase Correct PWM, CTC모드를 나타낼 수 있다.

 

이때, Normal 모드의 경우

timer/counterX overflow interrupt

CTC 모드의 경우

timer/counterX compare match interrupt

 

밑의 예제코드에서 TCCR3A = 0b00000000 하여 Normal모드로 설정 하였고, TCCR3B = 0b00000101 로 하여 분주비를 1024로 설정 하였고,

TIMSK30번비트를 1 설정해줌으로써 타이머/카운터 0 노멀모드로 설정 하였다. 마지막으로 TCNT3 1초로 설정하여 매 1초마다 버플로우 되어 인터럽트가 발생하도록 구현하였다.

 

 

 

 

<예제 코드 분석>

 

Main 함수 내에서 TCCR3ANormal 모드, timer/counterX overflow interrupt로 설정하였고, 분주비는 1024로 설정, TCNT31(0xffff-7812) 설정하고 sei(); 함수를 사용해 인터럽트를 활성화 시켰다.

 

따라서 main문 안에서는 매 1초마다 인터럽트가 발생하는 타이머 카운터 인터럽트가 발생한다.

 

다시 말해, 1초가 될 때마다 ISR(인터럽트 서비스 루틴)이 실행되어 ISR문 안의 코드를 실행한다.

 

결과적으로, 이 예제 코드는 매 1초마다 인터럽트가 발생하여 LED가 켜졌다가 꺼졌다가를 반복하는 코드인 것을 알 수 있다.

 

 

 

1. Tekbot 하드웨어

A. 납땜

납땜이란. 전자기기 및 통신기기 등의 회로를 구성하고 있는 소자 적, TR, IC, 저항, 콘덴서 등의 부품이나 배선 등을 서로 접합하기 위한 작업으로 가열하면 땜납이 녹아 모세관 작용에 의해 결합부위에 흡수되고 습윤 작용으로 결합하게 된다.

 

주요 도구 :

인두기회로와 같은 전자소자를 서로 붙이기 위한 기본 공구

실납 : 전자소자를 납땜할 때 사용되는 재료로 주로 납과 주석의 비율이 4:6으로 합금한 실납을 주로 사용    

인두 받침대 : 납땜 작업 시 달구어진 인두를 안전하게 놓아두기 위해 사용.

납 흡입기 : 납땜을 잘못 하였거나 파손된 부품을 교체할 때, 부품을 기판에서 제거하기위해 사용되는 공구로서, 인두로 납을 녹이면서 흡입기로 납을 흡입, 제거한다.

솔더링 페이스트 : 인두기를 세척할 때나 납이 잘 퍼지게 하기 위해 사용. 인두기 끝이 녹이 슬었다면 (온도를 높인 상태에서) 페이스트에 살짝 넣었다가 뺀 후 마른 헝겊이나 휴지 등으로 닦아준다.

팁 클리너 : 오랜 시간 사용한 인두 끝에 묻어있는 이물질들을 제거하기 위해 사용.

기타 보조 도구 : 이외에도 납땜에 앞서 피복선을 자르거나 다듬을 때 사용하는 니퍼, 펜치등과 같은 기타 도구도 필요하다.

 

- 납땜 시 주의사항

인두의 팁은 작업 전에 견고하게 조여서 작업할 때 흔들리지 않도록 한다.

인두로 모재를 세게 문지르거나 한 곳에 오래 대고 있으면 제대로 납땜이 되지 않는다.

다이오드, IC, TR등과 같이 열에 약한 반도체 부품의 납땜에는 롱노즈나 핀셋으로 리드선을 잡고 열이 부품에 직접 전달되지 않도록 한다.

납땜 작업 시 근접된 다른 배선이나 부품에 인두가 닿아 배선의 피복이나 부품이 손상되지 않도록 한다.

인두 끝의 온도가 부족하여 냉납땜이 되지 않도록 유의한다.

인두가 굉장히 뜨거우므로 안전사고에 유의한다.

 

B. 모터 및 본체

모터란 우리 주변에서 쉽게 얻을 수 있는 전기에너지를 물리적인 법칙에 따기계적인 에너질 변환하여 우리의 일상생활에 편리함을 제공해 주는 효율적인 구동장치이다.

 

<모터 연결 모습>

모터에 캐퍼시터(축전기)를 연결하고 전선도 함께 연결하여 납땜을 한다. 납땜한 모터에 바퀴를 달아준다.

본체가 되는 판에 배터리 홀더와 뒷바퀴 역할을 하는 롤러바퀴를 달아준다.

납땜을 완료한 모터에 주 바퀴를 연결하고 마찬가지로 판에 연결한다.

완료한 후, 모터 컨트롤러 보드(Motor Controller Board)에 피메일헤더(Female Header)와 메일헤더(Male Header)를 알맞게 납땜하여 완성시킨다.

 

< 연결을 완료한 모습 >

 

C. Controller board (컨트롤러 보드)

Controller board는 크게 두 종류가 있다. 첫 번째는 Motor Controller Board(모터 컨트롤러 보드), 두 번째는 Analog Controller Board(아날로그 컨트롤러 보드)가 있다.

 

Motor Controller Board(모터 컨트롤러 보드)

= 모터 컨트롤러 보드는 모터를 시작 및 정지하고, 정방향 또는 역방향 회전을 선택하고 속도를 선택 및 조절을 디지털 방식으로 제어하는 보드이다.

<완성된  Motor Controller Board>

 

 모터 컨트롤러 보드 구성 요소 

 Female, Male Header 

 Capacitor 

 Resister 

 Transistor 

 16pin Socket 

 LED  IC(16pin)

 

 

 

 

 

 

Analog Controller Board(아날로그 컨트롤러 보드)

= 아날로그 구성요소만을 사용하여 간단한 Tekbots 동작을 허용한다. 이때, 온보드(On board) 전위차계를 사용하여 설정할 수 있는 전압기준을 이용하여 프로그래밍이 가능한 보드이다.

< 완성된  Analog Controller Board>

 아날로그 컨트롤러 보드 구성 요소

 Female Header 

 Capacitor 

 Resister 

 Diode 

 IC(14pin) 

 Potentiometer 

 Comparator(: 비교기

 

 

 

날로그 컨트롤러 보드는 두 개의 모터를 제어하기 위해 있는 보드4개의 가변 저항이 부착 되어있다. 왼쪽 두개의 가변 저항은 왼쪽 모, 오른쪽 두개의 가변 저항은 오른쪽 모터를 각각 조절한다.

=> 하지만 정확한 컨트롤이 어렵기에 이번 실험에서는 아날로그 컨트롤러 보드를 직접적으로 사용하지 않았다.

 

 

D. Charger board

 Charger board는 배터리를 tekbot의 동력으로 이용할 수 있게끔 도와주는 보드이며 사고 방전을 방지하기 위하여 배터리 출력을 제한하기 위해서도 사용한다.

 

Charger Board 구성 요소

Female, Male header

Diodes

Transistor

Fuse

Capacitor

Resister

Switch

IC(Integrated Circuit)

Power Connector

 

 

 

Charger board를 구성할 때 저항의 종류가 많으므로 multimeter 각 저항들의 값을 측정하고 알맞은 위치에 납땜해야한다. 다이오드의 경우 극성이 있으므로 극성에 맞게 알맞게 위치시켜 납땜을 해야 정상적인 charger board의 역할을 할 수 있다. 이후에는 동력 전달이 잘 되는지 확인하기 위해 발광 다이오드를 부착시킨다.

=> Charger board의 경우 이전 Tekbots에서 사용한 보드로 이번 실험에서 만드는 Tekbots에서는 사용하지 않았다.

 

E. Sensor board

Sensor board는 소리, , 버튼, 슬라이드 등의 외부 자극을 감지할 수 있는 보조 장치이다. Tekbots에서 Sensor board는 간단한 환경 상호작용을 제공하여 각 상황에 맞게 수행할 수 있게 한다. 센서보드의 두개의 스위치는 독립적이면 장애물을 효과적으로 감지할 수 있는 오른쪽 / 왼쪽 범프를 제공한다.

 Charger Board 구성 요소 

 Female header 

 Switch sensor 

 Resistor

 

 

F. MCU (Teensy 2.0 board)

MCUMicro Controller Unit의 약자로 다양한 전자기기에 탑재되는 핵심 부품으로 프로그래밍을 통해 다양한 제어연산이 가능하다. , MCU전자회로 혹은 전자기기를 구성하는 기계 부품의 기능을 조정하는 역할을 한다.

<PIN Assignment>                                                                       <Teensy 2.0  주요 특징 >

Teensy2.0USB기반의 마이크로 컨트롤러 개발 시스템이다. 모든 프로그래밍은 USB포트를 통해 수행된다. 특별한 프로그래머가 필요하지 않으며, 표준 "Mini-B" USB케이블과 USB포트가 있는 PC또는 Macintosh 케이블만 있으면 된다.

 

Wiring 및 조립 결과

 

<Motor Controller Board Wiring>

Left Encoder PIN B7

Right Encoder PIN D0

Left DIR_A PIN B3

Left DIR_B PIN B2

Right DIR_A PIN D1

Right DIR_B PIN D2

 

<Sensor Board Wiring>

Left Switch PIN F0

Right Switch PIN F1

 

<Buzzer>

Buzzer(+) - PIN B5

Buzzer(-) - GND

 

+ Recent posts