아두이노에는 tone()함수가 제공되는데 부저나 스피커로 음을 발생시킬 수 있는 함수이다. 기본 문법은 다음과 같다.


tone(pin, freq [, duration]);


  • pin : 부저나 스피커가 연결된 디지털 핀번호

  • freq : 주파수 (범위 : 31 ~ 65535)

  • duration : (옵션) 음의 발생 시간


여기서 duration은 주파수 지속시간으로서 이 시간이 지난 후에 noTone()함수가 자동으로 호출되는 것과 같은 효과를 낸다.  duration이  생략되면 noTone()함수가 호출될 때까지 음이 계속 발생된다. 예를 들어서 11번 핀에 부저가 연결되었다면 다음과 같이 한다.


tone(11, 262); // ‘도’음 발생
delay(500);
noTone(11);


이 코드는 ‘도’음을 0.5초간 발생시키는데 다음과 같이 할 수 있다.


tone(11, 262, 500);


이렇게 하면 음 발생 직후 다른 작업을 수행할 수 있으며 500ms후에는 내부 인터럽트가 발생하여 음발생이 자동으로 정지된다. 하지만 단음만 생성할 경우에는 상관없지만 연속음을 생성할 경우에는 주의해야 한다.


tone(11, 262, 500); // ‘도’음
tone(11, 294, 500); // ‘레’음
tone(11, 330, 500); // ‘미’음


이렇게 하면 맨 마지막의 ‘미’음만 발생하게 된다. (왜?) 따라서 올바른 동작을 위해서는 다음과 같이 해야 한다.


tone(11, 262); // ‘도’음 발생
delay(500);
tone(11, 294); // ‘레’음 발생
delay(500);
tone(11, 330); // ‘미’음 발생
delay(500);
noTone(11);
tone(11, 262); // ‘도’
delay(500);
tone(11, 294); // ‘레’
delay(500);
tone(11, 330, 500); // ‘미’


tone()함수는 내부적으로 타이머를 사용하므로 다음과 같은 점들을 주의해야 한다.

  • 이 함수를 사용할 경우 3번 11번 핀의 PWM이 정상적으로 동작되지 않는다.

  • 한 번에 하나의 주파수만 발생시킬 수 있으며 여러 핀에 동시에 다른 음을 발생시킬 수 없다.


 특정 음에 해당되는 주파수를 일일이 숫자로 기입하는 것은 가독성 면에서 좋지 않으며 이를 개선하기 위해서 아두이노에서는 음의 주파수만을 모아놓은 “pitches.h”라는 헤더파일을 제공한다. 내용은 다음과 같다.


/*************************************************
* Public Constants
*************************************************/
#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
#define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978


이 헤더파일은 전역 상수 정의로만 이루어져 있으므로 실행 파일의 용량을 증가시키진 않는다. 따라서 이 파일을 폴도에 복사한 후 인클루드시켜서 필요한 주파수를 사용하면 된다.


#include “pitches.h”
tone(11, NOTE_C3, 1000); // 3도 ‘도’음을 1초간 발생
...


이렇게 주파수(숫자) 대신 상수 이름을 사용하면 가독성이 높아지게 된다.




Posted by 살레시오
,

 자바(JAVA)는 컴퓨터 프로그래밍 언어 중의 하나로 썬마이크로시스템스(Sun Microsystems, 이하 썬) 라는 회사에서 개발하여 1996년 1월에 초기 버전이 발표된 객체 지향 (object-oriented) 언어이다. 썬의  제임스 고슬링, 아서 밴 호프와 같은 엔지니들이 처음 설계하였다고 알려져 있다.


    

[그림 1] 자바의 창시자인 제임스 고슬링과 마스코트(duke) 이미지


 원래는 썬의 엔지니어들에 의해서 가전 제품에 탑재될 소프트웨어를 만들려는 목표로 1990년에 개발이 시작되었다. 프로젝트의 초기에는 C++을 확장하여 사용하려 했지만 적합하지 않다고 판단하여 C++의 장점은 취하고 단점은 보안한 새로운 언어인 Oak 가 만들어졌다. 이후에 인터넷에 적합하도록 개발 방향이 바뀌면서 자바로 이름을 바꾸고 정식 버전을 1996년 1월에 발표하였다. 인터넷이 보급되면서 운영 체제와 상관 없이 어디에서든 실행할 수 있는 자바의 특성과 자바 애플릿(applet)의 인기에 힘입어 널리 사용되기 시작하였다.


 자바는 “Write once, run anywhere”라는 모토에 충실하여 한번 작성되어 컴파일된 실행 파일은 운영 체제와 상관없이 실행 가능하다. 이것이 가능한 이유는 자바 컴파일러는 소스 프로그램을 특정 기계어로 번역하지 않고 가상 언어로 번역한다. 그리고 그 가상 언어를 특정 기계어로 번역하여 실행하는 시스템을 자바 가상 머신(Java virtual machine, JVM)이라고 한다. (이름에 머신이라는 말이 붙어 있지만 이것도 프로그램이다.) 이 자바 가상 머신(Java Virtual Machine)은 여러 OS용으로 만들어져 있으므로 이것이 설치된 곳이라면 윈도PC, 맥, 리눅스, 서버 컴퓨터, 심지어 가전 제품 등 가리지 않고 어디에서든 자바 프로그램을 실행할 수 있다. 이러한 장점으로 인해서 자바는 다양한 기종의 컴퓨터와 운영 체제가 공존하는 인터넷 환경에 적합한 언어로서 인터넷의 발전과 함께 많은 사용자를 확보해 나갔다. 또한 기존의 C++언어의 장점은 채택하되 잘 사용하지 않는 부분은 배제하고 비교적 배우기 쉬운 간결한 문법도 사용자층을 넓히는데 한몫했다. 그리고 풍부한 클래스 라이브러리(Java API)가 공개되어 있기 때문에 프로그래머는 이것을 잘 활용하면 손쉽게 강력한 기능의 프로그램을 작성할 수 있다.


 자바를 처음 개발해서 보급했던 썬마이크로시스템스는 2010년에 데이터베이스로 유명한 오라클 (Oracle) 이라는 회사에 합병되었으며 따라서 현재 자바는 오라클사에 의해서 유지/배포되고 있다. 한 예로 구글의 안드로이드는 자바의 API를 이용하여 작성한 달빅(Dalvik)이라는 가상 머신 위에서 자바로 작성된 앱을 구동하며 자바 개발자들을 안드로이드로 끌어들여 큰 성공을 거두었다. 하지만 이로 인해서 오라클과 구글 간 자바  API의 사용료(저작권료)에 대한 소송이 진행되고 있기도 하다.


 자바 언어의 특징은 다음과 같이 요약할 수 있다.


  1. 운영체제에 독립적이다. 한번 만들어진 실행 파일은 자바 가상 머신이 설치된 곳이라면 어느 곳에서든지 바로 실행할 수 있다.

  2. 겍체 지향 언어이면서 배우기 쉽고 간결한 문법을 가지고 있다.

  3. 포인터(pointer)를 다룰 필요 없이 메모리 관리를 가상 머신이 자동으로 수행한다.

  4. 네트워크, 분산 처리, 멀티 쓰레딩을 지원한다.

  5. 최근에는 성능도 많이 개선되어 c/c++로 작성된 프로그램에 비해서도 그 실행 속도가 뒤지지 않는다.


 앞으로는 이러한 특징을 가지는 자바 언어의 기본적인 개발 방법에 대해서 알아보도록 하겠다.



Posted by 살레시오
,

 MATLAB은 수치해석(numerical analysis)을 수행하는 대표적인 프로그램이다. 원래 MATLAB은 Cleve Moler에 의해 처음에는 Fortran으로 작성되어 DOS상에서 구동 가능한 소규모 수치해석 프로그램으로 출발하였으나, 현재는 미국의 MathWorks사에 의해 java virtual machine 위에서 구동되는 (따라서 대부분의 OS를 지원한다.) 대규모 패키지 프로그램으로 발전하였다.



 MATLAB은 수치 해석에 특화된 언어 문법을 가지고 있으며 친숙한 수학적인 기호와 간단한 문법으로 복잡한 계산을 수행할 수 있다. 전형적인 이용 범위는 다음과 같다.

  • 수학과 관련된 계산

  • 알고리즘 개발

  • 상황 모델링과 data분석

  • 여러 가지 과학과 공학적인 그래픽적 표현

  • GUI(Graphical User Interface)에 의한 에플리케이션 개발

 현재 MATLAB은 학계나 연구소등에서 광범위하게 사용되고 있으며 사실상 수치해석툴의 표준으로 자리잡고 있다. 이 프로그램은 범용으로 사용되는 프로그램언어인 C나 C++과는 달리 전문적으로 수치 계산을 하기 위한 프로그램이다.


 간단한 예로 행렬의 곱셈을 들어 보자. 두 개의 행렬을 곱셈하는 프로그램을 C언어로 작성하려고 한다면 2차원 배열을 두 개 잡아서 두 행렬을 각각 저장한 후 반복문 (for 나 while 같은 반복문 명령)을 중첩해서 사용해야 계산 결과를 얻어낼 수 있다. 계산결과를 화면에 출력하거나 파일로 저장하는 추가적인 루틴도 작성해야 한다.



하지만 MATLAB에서는 간단하게 한 줄의 명령으로 이를 수행할 수 있다.



또한 미분방정식의 해나 적분등도 쉽게 계산할 수 있으며 그 결과를 그래픽으로 보여주는 기능 또한 다양하다. 이러한 수학 계산들을 C 혹은 C++이나 다른 범용 프로그래밍 언어로 구현하려고 한다면 고려해야할 사항이 한두 가지가 아닐 것이다.


 이처럼 MATLAB은 강력한 수학적인 능력을 갖고 있고 다양한 분야에 특화된 여러 toolbox(일종의 라이브러리임)를 갖추고 있으며 simulink라는 비쥬얼 모의 실험 환경과 같은 특수한 툴들을 갖추고 있다. 이러한 장점들에 의해서 수치 해석 툴의 강자로 자리매김하고 있다.



Posted by 살레시오
,

 인텔의 갈릴레오 보드는 아두이노와 똑같은 개발환경을 이용할 수 있는 고성능의 임베디드 보드이다.


[그림 1] 갈릴레오 보드의 패키지


잠시 사용해 본 간단한 느낌은 일단 업로드 속도가 일반 아두이노보다 매우 빠르다는 것과 아두이노의 개발환경과 거의 동일하다는 것이다. 하지만 리눅스 OS 위에서 동작이 되기 때문에 실제 저수준의 성능이 매우 높다고 단정할 수는 없다.

[그림 2] 갈릴레오 보드와 아두이노 프로미니 보드의 TWI 통신 실험


위 사진은 아두니오 프로미니 (좌상단)과 갈릴레오 보드를 TWI로 연결하여 통신 실험을 하는 것이다. 매우 잘 동작한다.  약간의 구글링 결과 제조사 홈페이지에서 확인한 바에 의하면 I2C 통신의 경우 갈릴레오 보드는 마스터로만 사용할 수 있고 100kHz의 속도만을 지원한다. 또한 GPIO핀의 신호를 변화시키는데 2ms 가 소요되고 실제 오버헤드를 고려한다면 230 Hz 정도가 최대이다. 생각보다 성능이 높지는 않은 것 같다.


 이전 포스트에서 두에에서 했던 것과 똑같은 실험을 수행해 보았다. 즉 다음과 같은 코드를 실행시킨 다음 2번 핀의 주파수를 측정해 보는 것이다.


void setup() {
   pinMode(2, OUTPUT);
}
void loop() {
   while(1) {
       digitalWrite(2, HIGH);
       digitalWrite(2, LOW);
   }
}

이 프로그램은 2번 핀을 단순히 on/off 시키는 것이다. 결과는 아래 그림과 같은데 좀 의외였다. [그림 ]에서 스코프의 세로줄 한 칸은 1ms 이다. 따라서 구형파의 한 주기가 약 8.5ms이고 이것을 주파수로 환산하면 약 118 Hz 라는 어이 없는 결과가 나온다. 400MHz 짜리 갈릴레오가 16MHz 짜리 우노 보다 하드웨어 제어 성능이 한참 아래라는 결론이다. 아무리 갈릴레오가 리눅스 위에서 돌아가고 물리적인 핀들이 내부적으로는 I2C로 제어된다고는 하지만 성능이 너무 낮은 것 아닌가 하는 생각이 든다.

[표 1] 성능 비교표

보드

프로세서

동작 클럭

구형파의 한 주기  시간

주파수

아두이노 우노 (uno)

ATmega328

16 MHz

5 us

200,000 Hz (200 kHz)

아두이노 두에 (due)

AT91SAM3X8E

87 MHz

8 us

125,000 Hz (125KHz)

인텔 갈릴레오

intel Quark

400 MHz

8.5 ms

     118 Hz

 물론 갈릴레오는 원보드 마이컴이라서 일반적인 아두이노와 종류와 그 타겟 분야가 다르기는 하다. 하지만 단순히 굉장히 빠른 아두이노라는 오해를 가지고 실제 프로젝트에 적용시키려면 충분한 검토가 이루어져야 할 것 같다.



Posted by 살레시오
,

Due보드의 PWM 개요

 아두이노 두에 (arduino due) 의 PWM 핀은 다음 그림의 핀맵에 나온 바와 같이 같이 D2부터 D13까지 12개를 사용할 수 있다. 따라서 우노보다 더 많은 핀을 PWM출력으로 사용할 수 있다.


[그림 1] 아두이노 두에의 핀맵


단순히 핀 수만 많은 것이 아니라 우노와 달리 최대 해상도를 12비트까지 지정해 줄 수 있다. 따라서 우노는 [0, 255]범위의 출력(8비트)을 사용했었는데 두에의 숫자 범위는  [0, 4095] 이다.


 PWM의 해상도를 조절하려면 다음과 같은 함수를 사용해야 한다.


analogWriteResolution(nBits);


입력인수는 몇 비트를 사용할 것인가를 지정해주면 되며 기본값은 8비트이다. 만약 12비트로 해상도를 높이고 싶다면 다음과 같이 하면 된다.


analogWriteResolution(12);


그런 다음 analogWrite()함수를 사용하면 된다. 예를 들어서


analogWrite(6, 4095); // 6번핀에 4095값을 내보낸다.


 만약 어떤 아날로그 센서의 입력이 [0, 1023] 범위의 값인데 이것을 [0. 4095]범위의 값으로 변환하고 싶다면 map()이라는 함수를 사용하면 된다.


map(sVal, sMin, sMax, cMin, cMax);


이 함수는 sVal 값을 원래의 범위인 [sMin, sMax] 에서 변환하고자 하는 범위 [cMin, cMax]에 해당하는 값으로 바꾸는 함수이다. 만약 (0, 1023)범위의 센서값을 [0,4096]값으로 바꾸고 싶다면 다음과 같이 하면 된다.


map(sVal, 0, 1023, 0, 4095);


이 함수들을 사용해서 PWM을 12비트 해상도로 변경하고 [0,1023]범위의 센서값을 PWM 으로 매핑하는 예는 다음과 같다.


analogWriteResolution(12);

analogWrite(12, map(sensorVal, 0, 1023, 0, 4095));


여기서 sensorVal 변수에는 10비트 아날로그 센서값이 저장되었다고 가정한다.

PWM 주파수 변경

 아두이노 Due의 PWM 주파수는 1KHz 로 정해져 있다. 그런데 응용 분야에 따라서 이 주파수를 변경해 주어야 하는 경우가 있다. 하지만 아두이노에서 PWM의 주파수를 바꿔주는 공식 API 는 없어서 무척이나 불편하다. 그래도 AVR 계열의 아두이노에서는 이런 불편을 해소하기 위해서 사용자가 작성한 라이브러리 (PWM.h)라도 있는 것 같은데 Due의 경우에는 아직까지 그런 라이브러리는 없는 것 같다.


 구글링을 해본 결과 아주 방법이 없는 것은 아니었다. 일단 다음의 헤더 파일을 연다.(윈도의 경우)


Program Files > Arduino > hardware > arduino > sam > variants > arduino_due_x > variant.h


64비트 윈도라면 Program Files(x86) 폴더 밑을 뒤져야 한다. 이 파일을 열면 다음과 같이 정의된 부분이 나온다.


/*
* PWM
*/
#define PWM_INTERFACE PWM
#define PWM_INTERFACE_ID ID_PWM
#define PWM_FREQUENCY 1000
#define PWM_MAX_DUTY_CYCLE 255
#define PWM_MIN_DUTY_CYCLE 0
#define PWM_RESOLUTION 8


이 상수값들을 변경하면 PWM의 주파수나 기본 분해능을 설정할 수 있다고 한다. 예를 들어서 주파수를 10KHz로 변경하고 싶다면 PWM_FREQUENCY 를 10000 으로 바꾸면 된다.


[그림 3] dc모터 실험 (2V 이상 인가되어야 회전이 시작됨)


조그만 장난감 모터는 1KHz 주파수로도 충분하다. 필자가 가지고 있는 모터는 조금 용량이 큰데 (12V/12.9W) 이 정도만 되도 주파수를 조금 키워야 한다. 몇 번 실험해보니 12KHz 정도가 적당한 것 같다.



Posted by 살레시오
,

 이탈리아어로 due 는 두에 라고 읽고 '둘'이라는 뜻이다. 숫자 1, 2, 3 이 uno, due, tre ... 이다. 다른 것들은 모두 AVR계열의 프로세서를 사용해서 최대 클럭 속도(16MHz)나 배정도(double) 실수 사용에 제약이 있으나 이것은 ARM Cortex-M3 프로세서를 사용하여 훨씬 높은 성능을 가지고 있다.


[그림 1] 아두이노 Due 의 외형

일단 클럭주파수가 84MHz이고 내부적으로 3.3V를 사용 (보통 다른 아두이노 보드는 5V로 동작한다)하므로 라즈베리파이의 GPIO와 핀끼리 바로 연결할 수 있다는 장점도 있다. 또한 AVR 기반의 아두이노 보드와 달리 DAC도 내장하고 있으며 프로그램에서 64bit double형도 다룰 수 있다고 한다. 성능이 높은 만큼 가격은 다소 비싼 편이다. 동작 클럭이 84MHz이므로 단순히 비교하면 우노보드보다 5배 이상 성능이 높으며 디지털 핀수가 굉장히 많아졌고 PWM 개수도 우노보드보다 더 많으며 해상도도 12bit까지 지정할 수 있다. 그리고 모든 디지털핀에 인터럽트를 설정해 줄 수 있다는 것도 큰 장점이다. 우노의 경우 두 개의 외부 인터럽트만 사용할 수 있다.


 자세한 사양은 다음 표와 같다.

[표 1] 아두이노 Due 보드의 사양

Microcontroller

AT91SAM3X8E

Operating Voltage

3.3V

Input Voltage (recommended)

7-12V

Input Voltage (limits)

6-16V

Digital I/O Pins

54 (of which 12 provide PWM output)

Analog Input Pins

12

Analog Outputs Pins

2 (DAC)

Total DC Output Current on all I/O lines

130 mA

DC Current for 3.3V Pin

800 mA

DC Current for 5V Pin

800 mA

Flash Memory

512 KB all available for the user applications

SRAM

96 KB (two banks: 64KB and 32KB)

Clock Speed

84 MHz

 두에보드에는 USB연결단자가 두 개가 있는데 기본적으로 DC잭에 가까운 마이크로USB포트와 PC를 연결하면 전원이 공급되며 프로그램을 업로드할 수 있는 환경이 된다. 이 경우 별도로 DC잭으로 전원을 공급할 필요는 없으나 필요할 경우 7V~12V를 연결해야 한다.


[그림 2] 아두이노 Due의 프로그래밍 포트

 한 가지 주의할 점은 기존 아두이노보드들은 5V로 구동되는데 비해서 이것은 구동 전압이 3.3V라는 것이다. 입출력 핀에 5V신호를 인가하면 보드에 손상이 올 수도 있다고 하니 주의해야 한다.


 PC와 USB를 연결하고 스케치를 실행한 후 도구>보드>아두이노Due(Programming port)를 선택하고 도구>포트>COM? 에서 올바른 포트를 선택하면 일단 환경설정이 끝난 것이다. 예제의 Blink 를 열어서 업로드하면 보드상의 LED 가 깜빡이는 것을 볼 수 있다.

핀의 구조를 도시한 다이어그램은 다음과 같다.

[그림 3] 아두이노 Due의 핀맵

 한 가지 주의할 점은 클럭이 84MHz 이니까 16MHz 를 사용하는 우노보다 6배 이상 성능이 높을 것이라고 기대하면 안된다는 것이다. 성능 테스트를 위해서 간단한 프로그램으로 테스트를 해 보았다. 프로그램은 다음과 같이 2번 핀을 연속적으로 on/off 시키는 것이다. 그리고 이 핀의 주파수가 어떻게 나오는가를 스코프로 찍어보는 것이다.


void setup() {
   pinMode(2, OUTPUT);
}
void loop() {
   while(1) {
       digitalWrite(2, HIGH);
       digitalWrite(2, LOW);
   }
}

2번 핀을 스코프로 찍어서 본 결과는 다음과 같다. 화질이 안 좋지만 세로 줄 한 칸이 1us이므로 구형파의 한 주기가 5us 이다. 따라서 주파수는 200kHz라는 것을 알 수 있다. 가로줄은 한 칸이 1V이므로 on 상태에서 3.3V 의 값을 갖는것을 알 수 있다.

[그림 4] 실험 결과

똑같은 프로그램을 아두이노 우노에 집어 넣고 실행 시킨 결과 구형파의 한 주기가 8us 가 나왔다. 주파수로 따지면 125kHz이다.


 이것만으로 단순하게 성능비교를 하기에는 부족하지만 두에가 우노보다 약 1.6배의 성능을 보여준다. 우노의 클럭주파수가 16MHz 이고 두에가 84MHz이다. 내부적인 연산 속도는 5배 이상(실수 연산의 경우에는 더 높은 성능을 기대할 수 있을 것이다.)의 성능을 가질 것으로 짐작할 수 있으나 디지털 핀과 같은 하드웨어를 제어하는 경우에는 우노에 비해서 5배 이상의 성능을 기대한다는 것이 무리라는 결론이 나온다.



Posted by 살레시오
,

 ATmega8(A)의 PDIP(parallel dual in-line, 핀 배치가 평행한 두 줄 모양) 패키지의 외형은 다음 그림과 같이 14 핀씩 두 줄이며, 각 핀의 번호 및 명칭은 다음과 같다.

[그림 1] ATmega8(A) PDIP 패지키의 핀 배열


[표 1] 핀의 이름과 기능

핀이름

기능

비고

Vcc/GND

uC를 구동시킬 전원 연결

동작 필수 기능

/RESET

리셋핀

XTAL1/XTAL2

클럭신호 입력 핀

PB0,PB1,…,PB7

8bit 범용 입출력 포트

포트

PD0,PD1,…PD7

8bit 범용 입출력 포트

PC0,PC1,…PC6

7bit 범용 입출력 포트

RXD, TXD, XCK

시리얼 통신을 위한 핀

통신

SCK,MISO,MOSI, /SS

SPI통신을 위한 핀 (ISP에 사용)

SCL, SDA

Two-Wire Interface (TWI)

INT0, INT1

외부 인터럽트 핀

T0, T1

TOSC0, TOSC1

타이머 클럭 입력 핀

타이머/카운터

OC1A, OC1B, OC2

타이머/카운터 출력핀

ICP1

타이머/카운터 1의 입력캡춰 핀

AVCC

ADC의 전원 인가 핀

ADC

AREF

ADC의 기준전압 인가 핀

ADC0,…,ADC5

ADC를 수행할 노드 연결 핀

AIN0, AIN1

아날로그 비교를 위한 핀


 ATmega8(A)는 AVR계열 중에서 28개의 핀을 가진 uC이다. (AVR중 tiny계열에는 8핀만을 가지는 uC도 있다). 핀의 명칭을 보면 P로 시작하는 핀들이 가장 많이 눈에 띄는데 이들은 포트(port)를 뜻한다. ATmega8(A)는 8bit로 입출력을 제어할 수 있는 2개의 양방향 포트(port)를 가지며 포트B(PB0~PB7), 포트D(PD0~PD6)라고 칭한다. 포트라는 것은 μC가 입력 신호를 받거나 출력 신호를 내보내는 통로라고 이해하면 된다. 하나의 핀은 2가지 전압(0V와 5/3.3V)만을 가질 수 있으므로 하나의 bit를 표현할 수 있다. 8개의 핀을 조합해서 8bits 즉 1byte를 구성한다. 즉 사용자 프로그램에 의해서 포트 핀은 0V 전위를 가질 수도 5V전위를 가질 수도 있으며 (출력일 경우) 외부의 0V 혹은 5V의 전압값을 읽어 들일 수도 있다(입력일 경우). 양방향이라는 것은 동일한 포트가 입력과 출력으로 모두 사용할 수 있다는 의미이다.


 총 28개의 핀들 중에 전원을 인가하는 8/20/21번(VCC, AVCC, AREF)과 8/22번(GND)을 제외한 나머지 23개의 핀이 모두 포트의 기능을 가지고 있다. 또한 핀 수가 28개로 제한이 되어있기 때문에 하나의 핀이 두 개의 기능을 가지는 경우도 있다. 이 경우 내부 I/O레지스터를 조작하여 어떤 기능으로 사용할 것인가를 지정할 수 있다.


[그림 2] ATmega8(A)의 내부 구조도


 [그림 2]에 ATmega8A의 전체 기능별 블럭도가 도시되어 있다. 이 그림을 보면 8bit 데이터버스가 모든 구성요소에 연결되어 있다. 하지만 레지스터와 ALU간에는 전용선로가 깔려있어서 ALU가 레지스터에서 데이터를 읽고 쓰는 것이 가장 빠르다. ALU는 연산에 필요한 데이터를 레지스터에서 읽어오며 또한 연산 결과를 레지스터에 바로 반영한다.


 PC(program counter)는 현재 실행되는 프로그램의 번지를 저장하는 메모리이다. 오류가 없는 프로그램이 어셈블되어서 ISP기능 등을 이용하여 프로그램이 플래쉬롬에, 그리고 데이터가 EEPROM에 저장이 되어 있을 것이다. uC는 전원과 적합한 클럭이 인가되고 리셋핀에 high(5/3.3V) 신호가 인가되면 PC(program counter)는 $000으로 초기화되고 프로그램 메모리의 $000번지부터 명령어를 하나씩 명령레지스터(instruction register)로 읽어 들인다. 이때 현재 실행해야 할 프로그램의 번지가 저장되어 있는 곳이 바로 PC이고 16bit 로 구성되어 있다. 따라서 초기에는 PC에 $0000값이 입력되고 명령어를 하나(대부분 1word 이지만 어떤 명령어는 2word) 읽어 들이고 1(혹은 2)가 증가한다. 읽어 들인 명령어는 명령레지스터에 저장된 후 명령 해독기(instruction decoder)에서 어떤 일을 수행하라는 명령어인지를 해독한다. 해독이 끝나면 해당되는 작업을 수행하기 위해 적절한 제어신호가 제어선(cotnrol lines)에 의해서 전달된다. 현재의 명령어를 해독하고 수행하는 동시에 다음 명령어(즉 PC가 가리키는 번지에 저장된 명령어)를 명령레지스터로 읽어 들인다. 그렇기 때문에 거의 모든 명령어가 1클럭 싸이클에 수행되는 것이고, 만약 시스템이 4MHz 클럭으로 동작한다면 최대 4MIPS의 수행속도를 낼 수 있는 것이다.


 AVR은 하버드 구조(Harvard structure)를 채택하여 프로그램과 데이터를 위한 메모리와 버스가 서로 분리되어 있다. 즉 프로그램메모리와 데이터메모리가 따로 존재하고, 각각의 메모리를 접근하기 위한 주소 및 데이터 버스선도 따로 존재한다. 프로그램 메모리는 2단계 파이프라인(2-stage pipeline) 방식으로 동작하여 프로그램이 수행되는 동안에 다음 명령어를 읽어 들인다. 데이터 버스를 통해서 SRAM이나 EEPROM에서 데이터를 레지스터로 읽어오거나 반대로 쓸 수도 있다. 그리고 모든 주변장치들이 데이터버스를 통해서 레지스터와 연결되어 있다.




Posted by 살레시오
,

 여기에서는 AVR에 입문하는데 적합한 디바이스로 ATmega8(A)의 개략적인 특징에 대해서 설명하도록 하겠다. AVR의 이름을 보면 끝에 A가 붙는 것들이 있는데 (ATmega8A, ATmega128A등) 이것은 기존에는 5V용과 저전압(3.3V)용이 따로 구분되어 있었는데 (ATmega8, ATmega8L이 각각 존재했었다.) ATmega8A는 이 두 AVR을 하나의 uC로 통합한 것이다. 즉, ATmega8A는 5V와 3.3V 두 전압에서 모두 구동이 가능하고 (데이터쉬트상의 구동전압은 2.7V~5.5V이다.) 전력 특성을 개선하였으면서 사용법은 기존의 ATmega8/8L과 동일하다.


 실습용으로 ATmega8A를 선택한 이유는 일단 28핀 PDIP패키지가 제공되어 (TQFP, MLF패키지도 있음) 초보자들이 납땜을 해서 (혹은 빵판에 꽂아서) 실험을 하기에 편리하며 이 칩과 내장 주변기기를 제어하는 방법을 잘 알아두면 상위계열이나 하위 계열의 디바이스들을 모두 쉽게 다룰 수 있게 된다는 점이다. 따라서 만약 ATmega8A의 하드웨어를 충분히 숙지하고 개발이 익숙해진다면 거의 모든 (ATmega2560과 같은 최상위의 디바이스도 포함해서) AVR디바이스를 별다른 추가 학습 없이 다룰 수 있게 된다. 본 절에서는 ATmega8A의 특징에 대해서 알아보도록 한다.


[그림 1] ATmega8(A)의 외형. 좌측으로부터 PDIP, TQFT,  MLF


 ATmega8(A)는 AVR RISC 구조로 제조된 저전력 소모용 CMOS 8bit μC이다. 한 개의 클록 사이클 안에 강력한 명령을 수행하여 1MHz 당 최대 1MIPS(million instructions per second)의 처리속도를 낼 수 있으며 시스템 디자이너가 처리속도 대비 전력 소모를 최적화 할 수 있도록 제조되었다. AVR의 핵심은 산술연산장치 (ALU)에 직렬로 연결된 32개의 범용레지스터를 가지며 이들을 이용한 풍부한 명령어들이 마련되어 있다는 것이다. 단일 클록 사이클 이내 실행되는 한 개의 단일 명령어로써 두 개의 독립적인 레지스터를 처리할 수 있도록 하였다. 이러한 구조는 재래식 CISC uC보다 10배 이상 빠른 처리속도를 낼 수 있을 정도로 보다 효과적인 코드 방식을 지원한다.


 ATmega8(A)는 내부에 프로그램 가능한 8K바이트의 프로그램 가능한 플래시 메모리, 128byte 의 SRAM이 있고 128byte의 프로그램 가능한 EEPROM이 내장되어 있다. AVR계열의 μC는 ISP (in-system programming) 기능을 가지고 있다고 앞에서 말한 바가 있다. 즉 롬라이터(rom writer)같은 부가적인 장비 없이 PC와 연결하여 SPI 직렬 인터페이스를 통해서 내부의 플래시메모리에 프로그램을 써 넣을 수 있어서 편리하게 실험하는데 아주 유용한 기능이다. 한 개의 단일 칩에 기능이 향상된 RISC 8bit μC를 내장형 프로그래머블 플래시 및 다양한 부가장치를 조합함으로 사용자가 사용하기 쉽고 수많은 다른 제어 응용 분야에서도 비용면에서 효과적인 강력한 uC이다.


 데이터쉬트에 소개된 ATmega8A의 하드웨어 특징을 정리하면 다음과 같다.

  • 고성능, 저전력 소모용 RISC 구조 설계

  • 130개의 강력한 명령어 (대부분 단일 클록에 실행 가능)

  • 32×8 범용 레지스터

  • 16MHz에서 최대 16MIPS의 처리 속도

  • 2사이클 곱셈기 내장

  • 데이터와 비휘발성 프로그램 메모리 구조

  • 8K byte 플래시메모리 내장 (최대 10,000번 읽기/쓰기 가능)

  • 512 byte EEPROM 내장 (최대 100,000번 읽기/쓰기 가능)

  • 1K byte의 내부 SRAM

  • 상온(25도)에서 100년간 데이터 보존 (플래시롬/EEPROM)

  • 크기 조절 가능한 부트로더 영역 (부트 프로그램에 의한 ISP가능)

  • 플래시롬과 EEPROM 데이터 보호용 프로그래밍 잠금 기능.

  • 주변장치의 특성

  • 23개의 프로그램 가능한 I/O 포트

  • 2개의 8bit 타이머/카운터 내장

  • 1개의 16bit 타이머/카운터 내장

  • 별도의 오실레이터 연결 가능한 실시간 카운터

  • 6채널(PDIP) 10bit ADC 내장

  • 별도의 오실레이터가 내장된 프로그램 가능한 워치도그 타이머

  • 마스터/슬레이브 SPI (serial programming interface) 내장

  • 프로그램 가능한 직렬 USART 내장

  • 아날로그 비교기 내장

  • 휴식모드 (idle mode) 및 절전모드 (power down mode)로 전환 가능

  • 동작 전압 및 클럭 주파수 : 2.7~5.5V, 0~16 MHz

  • 패키지 : 28핀의 PDIP형, 32핀의 TQFP와 MLF


초보자가 실험하기에는 28핀을 갖는 PDIP 패키지가 좋은데 빵판에 꼽아서 회로를 꾸밀수 있기 때문이다.



Posted by 살레시오
,

 AVR은 미국의 Atmel사에서 제공하고 있는 8비트 마이크로컨트롤러(이하 uC)이다. Atmel은 마이크로프로세서, 플래시메모리, 센서 등을 개발하여 공급하고 있는 다국적 반도체 회사로서 플래시 메모리의 기술과 장점을 살린 다양한 uC를 출시하고 있다. 그중 AVR은 저가형 8비트 마이크로컨트롤러로서 1990년에 Norwegian 공과대학의 컴퓨터 일렉트로닉스/ 컴퓨터 사이언스 과의 학생인 Alf Bogen과 Vegard Wollan의 두 사람이 연구한 RISC CPU가 원형이다. 이 후 Atmel사에 입사해서 연구된 CPU가 AVR uC가 되어 1997년 출시된 이후 현재 산업계 및 교육 현장에서도 폭넓게 보급되어 사용되고 있다.


[그림 1] www.atmel.com 홈페이지


 AVR은 Atmel사의 비휘발성 메모리 기술을 기반으로 플래시 메모리, SRAM, 그리고 EEPROM을 기본적인 사양으로 내장하도 있으며 개발/양산의 편의성과 외부 회로를 최소화할 수 있도록 고려하여 설계하였다는 특징이 있다, 특히 ISP (in-system programming)가 가능하다는 큰 장점을 가지고 있다으며 개발자는 이 기능을 이용하여 uC에 프로그래밍하는데 별도의 롬라이터 없이 타겟 보드 상에서 PC의 직렬/병렬 포트와 연결하여 프로그램/데이터를 플래시롬/EEPROM에 다운로드할 수 있다.


 AVR은 프로그램 메모리와 데이터 메모리를 접근하기 위한 버스를 독립적으로 사용하는 하바드 구조(Harvard architecture)와 파이프라인 처리 방식을 기반으로 하는 RISC(reduced Instruction set computer) 기술을 적용하여 1명령 싸이클이 내부 클록의 1클록에 의해 처리되는 매우 높은 성능을 발휘한다. 또한 Atmel사에서 개발하여 무료로 공급하고 있는 Atmel Studio (예전에는 AVR Studio라는 avr 전용 IDE가 있었으나 요즘에는 ARM 개발도구와 통합되어 Atmel Studio라는 이름으로 배포하고 있다.) 라는 강력한 IDE가 있으며 역시 무료로 사용할 수 있는 C/C++ 컴파일러가 있어서 손쉽게 저가로 개발 환경을 갖출수 있다는 큰 장점을 가지고 있다.


 이러한 장점으로 인해 AVR은 가장 늦게 출시되었음에도 불구하고 8051시리즈나 PIC계열의 uC를 능가하는 인기를 단시간에 얻게 되었다. 또한 2007년에 출시되ㅓㅇ 전세계적으로 널리 사용되고 있는 아두이노(arduino)라는 프로토타이핑(prototyping) 보드의 메인 프로세서로 사용되면서 그 인기를 이어가고 있다.



Posted by 살레시오
,

 아두이노의 디지털핀은 오직 HIGH(5V) 아니면 LOW(0V) 두 가지 신호 외에는 출력할 수 없으며 전압의 관점에서 보면 5V와 0V만 가질 수 있다. 하지만 PWM (pulse width modulation, 펄스 폭 변조) 기능을 이용하면 마치 아날로그 전압처럼 0V와 5V 사이의 전압으로 (예를 들면 2V, 3.5V 등) 출력을 낼 수 있다. 따라서 LED의 밝기를 제어한다든가 모터의 회전 속도를 제어하는데 사용할 수 있다.

 PWM은 진정한 의미의 아날로그 출력은 아니고 흉내를 내는 것인데 그 원리는 다음 그림과 같다. (출처 : arduino.cc)


[그림 1] PWM의 원리


이 그림에서 보면 주기적인 구형파를 발생하고 이 구형파의 폭을 조절하여 그 듀티비 (HIGH 구간 대비 LOW 구간의 비율)로 아날로그 전압값을 가지도록 한다. 이 구형파의 주기를 매우 빠르게 (아두이노 우노의 경우 490Hz 혹은 980Hz이다.) 하면 상대적으로 반응 속도가 느린 기계 장치(모터 등)는 이것을 아날로그 전압으로 인식하게 된다.


 예를 들어서 그림 1(b)의 경우 주기의 1/4동안만 on 이 되므로 평균 출력 전압도 5V * ¼ 인 1.25V 정도가 된다. 만약 LED가 연결되었다면 LED는 정확하게 on구간에서만 켜지고 off구간에서는 꺼진다. 하지만 눈으로 보기에는 이것이 인식하지 못 할만큼 고속으로 동작하므로 밝기가 다르게 보이는 것이다.


 아두이노의 모든 핀이 PWM 출력을 낼 수 있는 것은 아니고 아두이노 우노의 경우 3, 5, 6, 9, 10, 11번 핀이 PWM출력을 낼 수 있으며 이것은 정품 보드의 경우 다음 그림과 같이 ~로 표시되어 있다.


[그림 2] 아두이노 우노의 PWM 핀들

PWM의 동작 주파수는 다음과 같다.

  • 3, 9, 10, 11번 핀 - 490Hz

  • 5, 6번 핀 – 980Hz (5,6번 핀이 좀 더 고속으로 동작)


PWM기능을 사용하기 위해서는 다음과 같은 analogWrite()함수를 이용한다.


analogWrite(pin, value)

  • pin : 3, 5, 6, 9, 10, 11 중 하나 (아두이노 우노의 경우)

  • value : 0에서 255 사이의 정수.


그리고 PWM 기능을 사용하기 위해서는 해당 핀을 출력으로 설정하여야 한다.



Posted by 살레시오
,