아두이노 보드들 중에서 가장 작은 크기를 가지는 보드로 arduino pro mini 가 있다. 동작 전압에 따라 두 가지 모델이 분리되어 있다. (5V 동작 모델/ 3.3V동작 모델)

[그림 1] 아두이노 프로 미니

스펙은 다음과 같으며 단순 스펙 상으로는 아두이노 우노보다 핀수가 조금 더 많다.

  • 메인 프로세서 : ATmega328 (초기 버전에서는 ATmega168)

  • 디지털핀 16개 (6개의 PWM포함)

  • 아날로그핀 8개

  • 크기 : 1.3" x 0.7" (약 33 mm x 18 mm)

  • 클럭 : 16MHz (5V 모델) / 8MHz (3.3V 모델)

  • 가격 : US $9,95 (정품)

  • 전원 : 3.35 -12 V (3.3V model) or 5 - 12 V (5V model)

전원을 인가할 때 한 가지 주의할 점은 정전압 (즉, 정류된 정확한 3.3V/5V 전압) 은 VCC핀에 연결해야 한다는 것이다. 정류되지 않은 전압(즉 정확히 3.3V/5V 가 아니라면)은 RAW핀에 연결해야 하는데 내장된 레귤레이터가 필요한 전압으로 바꿔준다. 그리고 VCC 와 RAW 핀 두 개에 동시에 전원을 인가하면 안된다. 보드가 상할 수도 있다고 한다.

 핀아웃 다이어그램은 다음 그림과 같다.

          [그림 2] 아두이노 프로미니의 핀 기능 다이어그램

 아두이노 우노와의 차이점은 핀 배치가 틀리므로 표준 쉴드(shield)를 사용할 수 없다는 것과 크기를 줄이기 위해서 usb 인터페이스가 생략되어 있다는 점이다. 따라서 프로그램을 다운로드 하려면 별도의 UART to USB 변환기를 사용해야 한다. (아래 그림 참조)

[그림 3] usb-to-serial 장치로 프로그래밍을 하는 모습

따라서 이 제품은 다량의 완성품을 만들어야 하는 경우에 하나의 변환기로 여러 개의 보드를 프로그램할 수 있으므로 단가를 낮출 수 있어 유리하다. 쇼핑몰 sparkfun.com 에서 정품이 개당 9.95$ 이고 ebay.com 같은 곳에서는 3.00$ 짜리 중국산 저가 복제품도 쉽게 찾을 수 있다.(그 가격에 팔면서 이윤이 남는다는 것이 정말 신기하다.) 또한 크기가 작으므로 소형 제품을 설계할 때에도 유리하게 작용한다. 그리고 3.3V 모델이 별도로 마련되어 있어서 라즈베리 파이와의 인터페이스도 용이할 것 같다.

 이것과 유사한 소형 보드로는 아두이노 나노(nano)와 아두이노 미니(mini) 가 있는데 모두 Atmega328 기반의 제품들이다. 나노는 usb시리얼 변환 칩과 usb단자가 있다는 점이 프로미니와 다르다. 미니와 프로미니는 핀배열이 조금 다르고 입력 전압을 인가하는 방식이 약간 틀린 것 같다. 즉 다음과 같은 모델들이 ATmega328 기반의 유사한 스펙이라고 보면 될 것 같다.

  • 아두이노 우노 (uno)

  • 아두이노 나노 (nano)

  • 아두이노 미니 (mini)

  • 아두이노 프로미니 (pro mini)


또 다른 소형 보드로 아두이노 마이크로(micro)라는 제품도 있는데 이것은 레오나르도를 소형화 시켜놓은 것이라고 보면 된다. ( 개인적인 경험으로 레오나르도 보드를 가지고 개발하는 것은 별로 권하고 싶지 않은데, 프로그램을 다운로드 하고 리셋이 걸릴 때마나 가상 시리얼 포트를 매번 잡아주는 것이 영 번거로웠기 때문이다. 우노 계열이 개발하기에 제일 편하다.)

 이것을 프로그램하려면 아두이노IDE에서 [도구]>[보드]>[Arduino Pro or Pro Mini] 메뉴를 선택한다. (아래 그림 참조) 그러면 [도구] 메뉴에 [프로세서] 라는 새로운 메뉴가 생성된다. 여기서 프로세서(328/168)와 전압(5V/3.3V)을 선택하면 된다. 최근의 모델은 모두 ATmega328을 사용한다.

  

[그림 4] 아두이노 프로미니 선택

올바르게 설정한 이후에는 일반적인 아두이노를 프로그램하는 방식과 동일하게 다룰 수 있다.


Posted by 살레시오
,

 아두이노의 인터럽트 기능을 이용하면 추가적인 하드웨어 없이 로터리 엔코더 (rotaty encoder)의 출력을 간단하게 읽어들일 수 있다. 여기에서는 아두이노 Due와 오토닉스(autonics)사의 1800펄스/1회전 분해능의 고정밀 로터리 엔코더를 이용해서 실험을 진행해 보겠다.


 기본적인 아이디어는 다음과 같다.


[그림 1] 오토닉스사의 로커리 엔코더 (E40H8-1800-6-L-5 )


엔코더에서는 세 가지 신호가 나오는데 각각 A상, B상, 그리고 Z상이라고 한다. A상과 B상은 축이 회전하면 위 그림과 같은 펄스를 발생하는데 자세히 보면 위상이 90도 만큼 엇갈려 있다. 일단 회전각은 A상을 기준으로 rising edge 혹은 falling edge 에서 인터럽트를 발생하여 내부 변수를 하나씩 증가하는 식으로 저장하면 된다. 회전 방향은 B상을 참조하면 되는데 예를 들어 시계방향으로 회전시에는 A상의 falling edge에서 B상이 1이고 반대 방향에서는 0이다. 이것으로 회전방향을 판단하면 된다. Z상의 펄스는 1회전에 한 번 발생하므로 이것으로 영점을 잡으면 된다. 즉 Z상의 펄스가 발생하면 카운트를 0으로 리셋시킨다.


 이제 아두이노Due 쪽의 프로그램을 살펴보면 Due는 다른 아두이노와 달리 고성능 보드 답게 모든 핀에 인터럽트를 설정할 수 있다. (다른 아두이노는 보통 2개 많아야 6개이다.) 필자는


  • 26번핀: A상

  • 28번핀: B상

  • 30번핀: Z상

이렇게 연결하였다. 한 가지 주의할 것은 autonics사이 이 엔코더는 datasheet에서 5V로 동작한다고 쓰여져 있는데 그렇다고 5V전원을 연결하면 신호선에 과전압이 걸려서 Due보드에 무리를 줄 수 있다.(Due보드는 동작 전압이 3.3V임) 다행히 3.3V를 연결해도 잘 동작하는 것 같았다. 테스트 프로그램은 다음과 같다.


int pA = 26; // phase-A of rotary encoder
int pB = 28; // phase-B of rotary encoder
int pZ = 30; // phase-B of rotary encoder

volatile signed long cnt = 0;
volatile signed char dir = 1;

void setup() {
   Serial.begin(115200);
   attachInterrupt(pA, encoderCount, FALLING);
   pinMode(pB, INPUT);
   attachInterrupt(pZ, encoderReset, FALLING);
}

void loop() {
   Serial.print(micros());  Serial.print(',');
   Serial.println(cnt);
}

void encoderCount() { // A상 신호의 폴링 에지에서 호출됨
   //B상의 값에 따라 방향을 결정한다.
   dir = (digitalRead(pB)==HIGH)? 1:-1;
   cnt += dir;
}
void encoderReset() { // Z상 신호의 폴링 에지에서 호출됨
   cnt = 0;
}


이렇게 구현하면 매우 간단하게 로터리 엔코더 신호를 읽어들일 수 있다.



Posted by 살레시오
,

 라스베리파이(이하 RPi)의 GPIO 핀들은 파이썬으로 제어할 수 있다는 점에서 무척 매력적이지만 GPIO 자체의 기능이 아두이노에 비해서도 빈약하다. 포트핀으로 흘릴 수 있는 전류가 수mA 정도로 제한되어 있으며 특히 PWM핀은 하나이고 아날로그 핀(ADC)은 없어서 아쉽다.

 

 그래서 아두이노의 기능을 얹은 RPi 인터페이스 보드들이 이러한 단점을 상쇄해 줄 수 있으리라 기대가 되어서 구글링 해보니 다음과 같이 몇 가지가 눈에 띄어서 정리해 보았다.

arduberry

 RPi 위에 장착하여 RPi에서 아두이노 IDE를 이용하여 프로그래밍 가능하다. getting start 를 대충 읽어보았는데 이것은 PC대신 RPi 로 프로그래밍한다는 개념인 것 같다. 필요한 프로그램을 설치하면 아두이노 IDE 의 다운로더 메뉴에 'Arduino GPIO' 메뉴가 생기고 이것을 선택하여 RPi에서 직접 코딩을 하고 컴파일과 다운로딩을 할 수 있다.



단순히 PC대신 RPi를 사용할 수 있도록 설계되었기 때문에 PC가 없는 환경이라면 초저가 아두이노 프로그래머를 RPi로 꾸밀 수 있겠으나,  PC를 이미 가진 사용자들에게 어떤 장점을 가지는 지는 의문이다.

 

2. alamode

 RPi 위에 장착가능한 아두이노 호환보드이며 아듀베리와 유사하게 시리얼포트가 연결되어서 RPi가 호스트가 되어 alamode 를 프로그래밍 할 수 있다.

그 뿐만 아니라 alamode 가 RPi를 이더넷쉴드로 사용할 수 있는 등 양방향 통신을 한다고 한다.

3. RPino GOGO

  아듀베리와 비숫한 개념의 국산 아두이노 보드이다. 특이한 점은 전용 스케치로더를 이용하면 독립적인 아두이노보드로 사용할 수 있다는 점이다. RPi 연결모드와 독립 사용 모드를 설정할 수 있다. RPi와 I2C 통신을 하기 위한 전압 레벨 변환기도 내장하고 있다. 개인적으로 구입해서 구동해 보았는데 잘 동작한다.

하지만 아듀베리와 마찬가지로 단순히 PC대신 RPi를 사용할 수 있도록 설계되었기 때문에 PC가 없는 환경이라면 초저가 아두이노 프로그래머를 RPi로 꾸밀 수 있겠으나,  PC를 이미 가진 사용자들에게 어떤 장점을 가지는 지는 의문이다.

 위의 세 가지 제품들은 라즈베리파이가 단순히 컴파일/다운로드를 수행하는 PC대신으로 사용하는 방식인데 사실 보통의 아두이노보드를 라즈베리파이와 USB로 연결해서 프로그램할 수 있으므로 확장보드로서의 의미가 크지 않다는게 필자의 생각이다. 단지 usb케이블을 이용하지 않고 깔끔하게 결합된다는 점과, alamode 의 경우 라즈베리파이를 이더넷쉴드 대용으로 사용할 수 있다는 점은 장점이라 할 수 있다.

4. piFace

 아두이노 호환은 아니지만 RPi GPIO핀에 장착하여 여러가지 IO실험을 할 수 있는 확장보드로 해외에서는 교육용으로 많이 사용되는 것 같다. 영국 맨체스터대에서 교육용으로 개발하였으며 파이썬 모듈을 제공하며 스크래치 언어와의 통합기능을 제공한다. 스크래치 언어를 지원한다는 것은 저학년 아이들의 교육에 무척 유용할 것이라는 예상을 할 수 있다.

piFace (왼쪽) 와 아두이노에 장착한 모습(오른쪽)


 입출력에 RPi의 GPIO 핀을 직접 사용하지 않고 MCP23S17 칩을 사용하며 I2C로 이를 제어하므로 대전류 구동이 가능하며 arduberry, alamode, RPino 와 다르게 독립적으로 구동되지 않고 반드시 RPi쪽에서 제어 프로그램을 구동하여야 한다.

 

5. pcDuino / 갈릴레오 보드 / udoo neo 보드

 이것들은 종류가 다른 보드이지만 리눅스 머신과 아두이노를 아예 하나의 보드 위에 섞어놓은 것이다. 아예 리눅스 보드 위에 아두이노 호환 핀들이 있는 것들이다. 따라서 아두이노가 지원하는 아날로그 핀이나 pwm 등을 바로 사용할 수 있다.

pcDuino3 nano : 아두이노 핀과 호환되기 때문에 아두이노 쉴드들을 바로 사용할 수 있다.

인텔 갈릴레오 gen 2 보드 : 피씨두이노와 마찬가지로 아두이노 쉴드를 바로 장착하여 사용할 수 있다.

 갈릴레오보드는 특이하게도 리눅스를 OS로 사용하지만 비디오 아웃풋 포트가 없으며, 호스트PC를 이용하여 아두이노IDE 와 동일한 인터페이스를 사용하여 프로그래밍할 수 있다는 것이 특징이다. 보드 자체는 아두이노에 비해서 훨씬 고성능이지만 포트핀들의 동작 속도는 아두이노보다 더 떨어지는 단점이 있다. ( 따라서 당연하게도 그렇다면 왜 궂이 이것을 사용해야 하는 지 의문이 드는 제품이다.)


 그리고 현재 (2015년 5월) udoo neo 라는 보드가 킥스타터에서 캠페인을 진행 중이다.



리눅스 보드인데 아두이노 호환 외부핀을 가지고 있으며 와이파이, 블루투스, 9축 가속센서를 내장하면서 $49불 정도의 가격에 판매될 거라고 한다.

6. 비글본블랙(beaglebone black)

  라즈베리파이를 사용하고 있는데 아두이노의 기능이 필요하다면 필자는 개인적으로 비글본블랙을 추천하고 싶다.

비글본 블랙 보드. 저 넘치도록많은 gpio 핀들에서 알 수 있듯이 왠만한 기능은 다 가지고 있다.

 최근에 출시된 dev C는 아예 데비안리눅스가 내장된 eMMC 플래시메모리(용량은 4G)에 올려져서 출시된다. 따라서 추가적인 외부메모리가 필요치 않다. 사진에서 보듯이 GPIO핀이 많을 뿐만 아니라 PWM과 ADC 핀도 넉넉하다. 라즈베리파이보다 약간 고성능인데다 개발에 편리한 기능(예를 들면 usb로 연결하면 바로 터미널 접속이 가능하다던지)들이 있다. 또한 파이썬으로 GPIO핀들을 제어할 수 있으므로 보다 복잡한 제어 알고리듬을 바로 적용해 볼 수 있다. 단 가격은 $55 정도로 라즈베리파이보다는 비싸고 USB포트도 하나 밖에 없는 것이 조금은 불편하다.




Posted by 살레시오
,

 아두이노 제로(zero) 라는 보드가 출시 예정이다.

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

아두이노와 Atmel사가 공동 개발한 것 같고 (뒷면에 그렇게 표기되어 있다.) 프로세서는 AVR 이 아니라 ATSAMD21 이라는 ARM 계열의 32비트 프로세서를 채용하였다. 48MHz 의 클럭 주파수로 동작하는데 (이것만 놓고 단순 비교하기는 무리지만) 성능이 아두이노 우노의 3배이다.

 클럭 속도 외에 우노와 비교하여 특이한 점은 0번과 1번을 제외한 모든 디지털 핀에서 PWM 기능을 사용할 수 있다는 점과 플래시메모리가 256KB 로서 우노의 8배 정도로 늘었다는 것이다. 개발 환경에서도 별도의 usb 통신 단자를 통해서 atmel 의 Embedded Debugger (EDBG) 기능을 사용할 수 있어서 디버깅에 별도의 장치가 필요없다는 점도 눈에 띈다.

 우노와의 차이점을 정리하면 다음과 같다.

  • 32비트 프로세서 채용

  • 3.3V로 동작

  • 48MHz의 클럭 주파수 (우노대비 4배)

  • 12개의 PWM핀 (우노의 PWM핀은 6개)

  • 256KB의 플래시메모리 (우노대비 8배)

  • 디버깅(EDBG)을 위한 별도의 usb 단자 내장

  • 12비트 ADC (우노는 10비트 ADC임)

문제는 가격인데 개인적인 짐작으로는 아두이노 우노에 비해서 많이 비쌀 것 같지는 않다.



Posted by 살레시오
,

 센서(sensor)란 자연계의 물리량을 그에 비려/반비례하는  전기적인 신호(전압, 저항값 등)로 변환시켜주는 소자이다. 아두이노를 이용한 실험에서 자주 사용되는 센서를 나열해 보면 다음과 같다.


초음파 센서

 초음파를 발생하여 반사되어 오는 시간을 측정하여 장애물과의 거리를 재는 센서이다. 이동 로봇의 거리 측정이나 차량의 후방 장애물 감지에 널리 사용되고 있다.

[그림 1] 초음파 센서 모듈


적외선 센서

 적외선(infrared rays)은 전자기파의 일종으로 가시광선보다는 파장이 길고 전자레인지에 사용되는 마이크로파보다는 파장이 짧다. 적외선을 발광하는 IRED (infrared ray emitting diode)는 일반적인 LED와 외형과 구동 회로면에서 유사하며 정방향 전압을 걸면 적외선이 나오는 전기소자이다. 흔히 사용되는 리모콘의 머리 부분에 달려있다.

[그림 2] 적외선 송수신 센서

광량 센서

 CdS 광전도 셀(CdS photoconductive cell) 또는 CdS셀은 황화카드뮴을 주성분으로 하는 광전도 소자로, 빛의 양에 따라 저항값이 변하는 일종의 가변 저항으로 생각할 수 있다. 빛의 양에 따라 내부 저항값이 변하는 특성이 있으므로 광 가변 저항기라고도 불리는데, 조사되는 빛의 양이 클수록 저항값이 낮아지지만 입사광이 거의 없으면 거의 절연체에 가까워질 정도록 저항값이 커지게 된다. 따라서 광량에 의해서 개폐되는 전기적인 스위치로도 생각할 수 있다.


[그림 3] CdS 광전도 센서

온도 센서

 온도에 비례하는 전압 발생하는 소자이다.

[그림 4] 온도 센서


기울기 센서

  기울기 센서는 기울기에 반응하는 센서이다. 일정 각도 이상 기울어지면 내부의 접점이 on되는 디지털식 센서와 각도에 비례하는 전기적인 신호를 발생하는 아날로그식 센서로 구분할 수 있다.

  

[그림 5] 디지털/아날로그 기울기 센서

 

터치 센서

 도전체나 피부의 접촉에 반응하는 센서이다.

[그림 6] 터치 센서 모듈


인체 감지 센서

인체감지센서 모듈은 적외선을 감지하는 센서를 장착하고 있으며 약 6미터 이내의 인간이나 동물의 움직임을 감지할 수 있다. 인체나 동물의 몸과 같이 열을 발산하는 곳에서 발생하는 적외선을 감지하는 원리이다.

[그림 7] 인체 감지 센서


이 밖에도 습도 센서, 소리에 반응하는 음향 센서, 각종 가스 센서, 등 많은 것들이 있다.





Posted by 살레시오
,

 오랜만에 아두이노 due 로 프로그래밍할 일이 있어서 새로 나왔다는 arduino ide 1.6.4 버전을 설치하고 프로그래밍을 시작하려는데 보드 메뉴에 새로운 보드들이 몇몇 추가된 것은 보이는데 정작 기존에 있던 arduino due 가 없어서 살짝 당황했다.


 조금 헤매다가 도구>보드>boards manger (맨 위에 있음) 옵션으로 타고 들어가니 다음과 같은 메뉴창이 뜬다.



위 그림처럼 Arduino SAM Boards 항목의 우하단에 설치 버튼이 있는데 그걸 눌러서 설치하면 보드 메뉴에 추가된다. (위 그림은 이미 인스톨한 후 캡쳐해서 설치 버튼이 안 보이는데 처음에는 install 버튼이 있다.



처음에 다운로드 받은 설치 프로그램 이전 버전보다 용량이 많이 줄어서 의아했었는데 이런 식으로 필요한 컴포넌트를 다운로드 받아서 설치하도록 구조가 바뀌어서 그런가 보다하는 짐작이 든다.




Posted by 살레시오
,

 초음파 센서로 다음과 같이 작동하는 아두이노 프로그램을 작성해 보자.

    ❶ 장애물이 30cm 밖에 있다면 부저는 울리지 않는다.

    ❷ 30cm 이내 10cm 바깥에 있다면 0,5초 주기로 삑삑거린다.

    ❸ 10cm보다 안쪽에 있다면 연속적인 삐~ 신호를 울린다.

마치 자동차의 후방 경고음과 같이 동작하게끔 하는 것이다.


 실험에서는 초음파 센서는 7번 핀에, 부저는 11번 핀에 달려있다고 가정한다. 다음 예제를 잘 분석해 보고 각자 응용해 보자.


#define ULTRA_SONIC_SENSOR  7
#define BUZ 11
void setup() {
 Serial.begin(9600);
 pinMode(BUZ, OUTPUT);
}
void loop() {
 float fDist = measureDist();
 int iTmBuzOn = 0;
 int iTmBuzOff = 0;
        
 if (fDist > 30) {
   iTmBuzOn = -1;
 } else if (fDist > 10) {
   iTmBuzOn = 50;
   iTmBuzOff = 450;
 }  else {
   iTmBuzOn = 0;
 }
 
 if (iTmBuzOn == 0) {
   digitalWrite(BUZ, HIGH);
 } else if (iTmBuzOn > 0) {
   digitalWrite(BUZ, HIGH);
   delay(iTmBuzOn);
   digitalWrite(BUZ, LOW);
   delay(iTmBuzOff);
 } else {
   digitalWrite(BUZ, LOW);
 }
   Serial.print(fDist);
   Serial.println(" cm");
}
#define MS_PER_CM           58.31f
float measureDist() {
pinMode(ULTRA_SONIC_SENSOR, OUTPUT); //(1)단계
digitalWrite(ULTRA_SONIC_SENSOR, LOW); //(2)단계
delayMicroseconds(2);
digitalWrite(ULTRA_SONIC_SENSOR, HIGH); //(3)단계
delayMicroseconds(5);
digitalWrite(ULTRA_SONIC_SENSOR, LOW); //(4)단계
pinMode(ULTRA_SONIC_SENSOR, INPUT);
// (5) 단계
unsigned long ulPulseTime = pulseIn(ULTRA_SONIC_SENSOR, HIGH);
if (ulPulseTime == 0 )
  return -1.0f;
else
  return ulPulseTime / MS_PER_CM;
}


여기서 measureDist()함수는 이전 포스트에서 작성한 함수를 그대로 사용하였다.


C++ 언어 전체 강좌 목록 >>>

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 살레시오
,

 아두이노의 TWI 통신 (I2C라고도 한다)은 두 가닥의 선(SDA, SCL)만으로 여러 개의 디바이스와 통신을 할 수 있다는 장점을 가진다. 이것의 통신 속도는 마스터 기기에서 발생시키는 클럭(SCL)신호를 기준으로 정해지며 보통 많이 사용되는 표준 주파수는 100kHz 와 400kHz 이다. 단순하게 이론적으로 계산하면 100kHz 의 주파수라면 초당 100k 비트(바이트 아님)를 전송할 수 있으며 초당 약 12.5k 바이트를 전송할 수 있다.


 아두이노의 I2C 통신에 사용되는 클럭 주파수는 100kHz로 맞추어져 있다. 아두이노에서 쓰이는 AVR은 400kHz 의 주파수도 지원을 하며 대부분의 I2C 통신 기기들이 이 주파수를 지원한다. 그런데 아두이노 API에서는 이 클럭 주파수를 조절하는 함수나 메쏘드가 없다. 이것을 400kHz로 상향시키기 위해서는 다음과 같이 약간 번거로운 과정을 거쳐야 한다.


 아두이노 IDE 1.5.5 와 윈도즈를 기준으로 설명하도록 하겠다. 먼저 다음 파일을 연다

C:\Program Files \ Arduino \ hardware \ arduino \ avr \ libraries \ Wire \ utility \ twi.h

이 코드의 윗 부분에 보면 다음과 같은 상수가 있다.


#ifndef TWI_FREQ
#define TWI_FREQ 100000L
#endif


이름에서 알 수 있듯이 TWI_FREQ 상수가 I2C 통신의 클럭 주파수를 정의한 상수이다. 이 상수를 400000L 로 바꾸면 된다.


#ifndef TWI_FREQ
#define TWI_FREQ 400000L
#endif

이렇게 변경하고 저장한 후 한 가지 과정을 더 거쳐야 한다. 현재 프로젝트의 (과거에 100kHz 상수 값으로 생성되었던)오브젝트 파일들인 wire.cpp.o , twi.c.o 파일들을 제거해야 하는데 이것을 제거하지 않으면 과거에 컴파일된 오브젝트파일을 가지고 링크를 하기 때문에 변경 사항이 적용되지 않는다.

다음의 폴더를 열어보자. (윈도7의 경우임)

C:\ Users \ [user id] \ AppData \ Local \ Temp

이 폴더 하위에 많은 build***********.tmp 폴더는 아두이노 프로젝트가 컴파일되면서 생성되는 임시파일들을 저장하는 폴더이다. 이것들을 모두 삭제한 다음 다시 컴파일하면 변경된 속도가 적용된다. 만약  위와 같이 오브젝트 (임시)파일을 삭제하는 절차가 번거로우면 아예 프로젝트를 새로 생성해서 코드를 붙여넣은 후 컴파일하면 된다.



Posted by 살레시오
,

 아두이노의 TWI로 한 바이트나 문자열을 주고 받는 것은 Wire.read(), Wire.write() 함수를 사용하면 쉽게 수행할 수 있으므로 전혀 문제가 없다. 문제는 멀티 바이트로 구성된 short, long, float 등의 데이터를 주고 받는 것이다. 예를 들어서 signed short형 (아두이노에서는 2 bytes임) 데이터를 전송하려고 하면 바이트로 쪼개서 보낸 다음, 받는 곳에서 다시 이를 조합해서 원래의 데이터로 복구시켜야 하는데 무척 번거롭다.


 이런 경우에 union 이라는 자료형을 사용하면 문제를 쉽게 해결할 수 있다. 예를 들어서 다음과 같이 (signed) short 형 데이터를 저장하기 위한 union을 정의한다. volatile 은 인터럽트 루틴 안에서 사용되기 때문에 붙인 것이다.


union UShort{
   volatile short sVal;
   volatile byte byArr[2];
};


union자료형은 포함된 변수의 메모리를 공유하기 때문에 여기서 보면 byArr[0]은 short형 sVal 변수의 하위바이트를, byArr[1]은 상위 바이트를 가진다.


이제 이것을 이용해서 변수를 생성한다. volatile 을 붙인 이유는 이전과 같다.


volatile UShort uMtr; // pwm value to motor
volatile UShort usv; // encoder value


그러면 usv.sVal 변수를 보통의 short형 변수처럼 사용하다가 TWI로 전송할 때는 usv.byArr[0]과 usv.byArr[1] 두 바이트를 차례로 보내주면 된다. 예를 들어서 슬레이브의 TWI 전송함수는 다음과 같다.


void requestEvent()
{
   Wire.write( (const byte *)usv.byArr, 2);
   usv.sVal = 0;
}


주의할 것은 usv.byArr 을 반드시 (const byte *) 형으로 캐스트해줘야 한다는 점이다. 그렇지 않으면 컴파일 시에 에러가 발생한다.


 수신단에서도 동일한 union을 정의해 놓고, 받은 데이터를 바이트 배열 byArr 에 차례로 넣어주면 곧바로 sVal 변수를 통해서 short형 변수 값을 쓸 수 있다.


void receiveEvent(int howMany)
{
   uMtr.byArr[0] = Wire.read(); // 하위바이트 받음
   uMtr.byArr[1] = Wire.read(); // 상위 바이트 받음
   MotorInput( uMtr.sVal ); // 받은 short형 데이터를 바로 사용한다.
}


이 함수에서 보면 uMtr.byArr[0] 과 uMtr.byArr[1] 을 차례로 전송받은 후 바로 uMtr.sVal 변수값을 사용하였다. 이렇게 별도로 원래 데이터를 쪼개서 보내고, 받은 후에 (비트 연산자 같은 것을 사용해서)복구하는 과정이 전혀 필요가 없는 것이다.



Posted by 살레시오
,