사용자:Dolicom/전자공학/아두이노

위키백과, 우리 모두의 백과사전.
아두이노
아두이노 우노 R3 SMD 에디션
사용 마이크로컨트롤러
ARMCortex-M0+/M3
통합 개발 환경
컴파일러avr-gcc[1]
라이브러리avr-libc[2], 라이브러리[3], 공개 오픈소스
웹사이트
API 사용설명
예제
LGPL 또는 GPL 라이선스

아두이노(Arduino)는 오픈소스를 기반으로 한 단일 보드 마이크로컨트롤러로 완성 된 보드(상품)와 관련 개발 도구 및 환경을 말한다. 처음에 AVR을 기반으로 만들어졌으며, 아트멜 AVR 계열의 보드가 현재 가장 많이 판매되고 있다. ARM 계열의 Cortex-M0(Arduino M0 Pro)과 Cortex-M3(Arduino Due)를 이용한 제품도 존재한다.

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

아두이노 통합 환경(IDE)을 제공하며, 소프트웨어 개발과 실행코드 업로드도 제공한다.[4] 또한 어도비 플래시, 프로세싱, Max/MSP와 같은 소프트웨어와 연동할 수 있다.[5]

아두이노의 가장 큰 장점은 마이크로컨트롤러를 쉽게 동작시킬 수 있다는 것이다. 일반적으로 AVR 프로그래밍이 AVRStudio(Atmel Studio[6]로 변경, ARM 도구 추가됨)와 WinAVR(avr-gcc)의 결합으로 컴파일하거나 IAR E.W.나 코드비전(CodeVision)등으로 개발하여, 별도의 ISP장치를 통해 업로드를 해야하는 번거로운 과정을 거쳐야 한다. 이에 비해 아두이노는 컴파일된 펌웨어를 USB를 통해 업로드를 쉽게 할 수 있다. 또한 아두이노는 다른 모듈에 비해 비교적 저렴하고, 윈도를 비롯해 맥 OS X, 리눅스와 같은 여러 OS를 모두 지원한다. 아두이노 보드의 회로도가 CCL에 따라 공개되어 있으므로, 누구나 직접 보드를 만들고 수정할 수 있다.

아두이노가 인기를 끌면서 이를 비즈니스에 활용하는 기업들도 늘어나고 있다. 장난감 회사 레고는 자사의 로봇 장난감과 아두이노를 활용한 로봇 교육 프로그램을 학생과 성인을 대상으로 북미 지역에서 운영하고 있다. 자동차회사 포드는 아두이노를 이용해 차량용 하드웨어와 소프트웨어를 만들어 차량과 상호작용을 할 수 있는 오픈XC라는 프로그램을 선보이기도 했다.[7]

역사[편집]

아두이노 시리얼 보드 RS-232 직렬 통신[8]
  • 2005년, 이탈리아 Ivrea에서 초기 프로젝트가 만들어졌다.
  • 2008년 10월, Arduino Duemilanove가 출시되었다.[9]
  • 2009년 3월, Arduinio Mega가 출시되었다.[9]
  • 2011년 3월, 전 세계적으로 30만 개 이상의 아두이노 유닛을 사용할 수 있다.[10][11]
  • 2015년 3월, 아두이노가 10주년을 맞았다.

초기의 아두이노 보드는 UARTRS-232을 결합한 통신을 사용하였다. 그러나 개인용 컴퓨터의 직렬포트(COM) 퇴조로 USB을 UART 방식으로 바꾸는 방식을 사용하고 있다. 개인용 컴퓨터나 노트북의 경우 직렬포트 연결 자체가 없는 경우가 많아 이 방식을 사용하면 현실적인 어려움이 있다. 이것을 고려하여 아두이노 보드에 USB와 UART을 변환하는 별도의 칩을 추가하여 프로그램 코드의 업로드를 한다. 목표 MCU 입장에서 보면 여전히 UART을 통해 업로드와 통신을 하는 방식이다.

아두이노 업로드와 시리얼 통신을 위해, 다음과 같은 UART의 입출력 신호 변환을 사용한 회로로 발전 하였다:

  1. [ 호스트 직렬 포트 (COM 포트, RS-232) ] === [ [ RS-232 - TTL 변환 ] --- [ MCU ] ] : BJT, D, R, C 등의 소자로 단순 전압 변환을 통해 직렬 포트를 아두이노에 연결[8]
  2. [ 호스트 USB ] === [ [ FTDI FT232계열 ] --- [ MCU ] ]  : 호스트의 통신에서 FTDI(FT232RL 등)를 사용하여 USB와 UART 간의 변환을 통해 시리얼 구현하였다.[12] 호스트에서 FTDI용 USB 드라이버와 USB 버스 드라이버가 필요하고, FTDI 개발사에서 제공한다. 아두이노를 설치하면 호스트용 드라이버는 자동 설치된다.
  3. [ 호스트 USB ] === [ [ ATmega8U2 ] --- [ MCU ] ]  : ATmega8U2를 사용하여 USB - UART 변환을 통해 MCU의 TTL 연결. 아두이오 우노 초기버전에서 사용.[13]
  4. [ 호스트 USB ] === [ [ ATmega16U2 ] --- [ MCU ] ] : USB - UART 변환.[14][15]

아두이노 하드웨어[편집]

보드[편집]

아두이노의 보드는 아트멜(Atmel)사의 8비트 AVR 마이크로컨트롤러와 프로그래밍 및 다른 서킷들과의 결합을 용이하게 해 주는 부속품들로 구성되어 있다. 공식 보드의 마이크로컨트롤러에는 주로 ATmega8, ATmega168, ATmega328과 같은 megaAVR 시리즈가 주로 사용된다. 보드에는 기본적으로 5V 리니어 레귤레이터와 16MHz 결정 진동자(크리스털)가 내장되어 있으며, 프로그램의 업로드를 용이하게 하기 위한 부트로더가 마이크로컨트롤러에 미리 내장되어 있다.

개념적인 수준에서 볼 때, 아두이노에 프로그램을 탑재함에 있어 있어 모든 보드는 RS-232 직렬 커넥터를 통해 프로그램되지만, 구현되는 방식은 하드웨어의 버전에 따라 달라진다. 직렬 아두이노 보드는 RS-232 수준의 신호를 TTL 수준의 신호로 변환해주는 변환 장치(Shifter)를 내장하고 있다. 지금의 아두이노 보드들은 모두 USB를 통해 프로그래밍 가능하며, FT232와 같은 USB-시리얼 변환 칩을 통해 사용 가능하다.

아두이노 보드는 마이크로컨트롤러 I/O핀의 대부분을 다른 서킷에서도 사용할 수 있도록 공개하고 있다. Diecimila, Duemilanove, 현재의 Uno와 같은 주요 모델들은 14개의 디지털 I/O핀을 제공하고 있으며, 그 중 6개의 핀은 PWM(pulse-width modulated)신호를, 다른 6개의 핀은 디지털 I/O핀으로 혼용이 가능한 아날로그 입력 단자를 제공한다.

아두이노 업로드[편집]

아두이노 우노 R3 업로드 경로. 1번:리셋 신호, 2번:UART(TTL레벨) 통신, 3번:USB 호스트 통신.
아두이노 우노 R3, 업로드 구조

아두이노 우노의 경우 기계어 코드의 업로드는 시리얼 통신을 통해 이루어 진다. 우선 개인용 컴퓨터와 USB로 연결되면 ATmega16U2(초기의 FTDI FT232R와 같은 역할로 USB-Serial 변환)에 의해 시리얼로 변환된다. 업로드의 전제 조건은 목표 마이크로컨트롤러(우노의 경우 ATmega328P)에 부트로더가 장착되어 있어야 한다. 부트로더가 동작하면 시리얼 통신으로 부터 오는 기계어 코드를 플래쉬 메모리에 쓰게 되어, 프로그래밍에 의해 완성된 응용 프로그램 코드가 장착된다. 응용 프로그램의 코드를 변경할 필요가 없다면, 전원 인가와 동시에 마이크로컨트롤러에 장착된 코드가 실행되면서 원하는 동작을 한다. 리셋 신호 입력시 부트로더는 플래시 쓰기를 할 것인지 또는 응용 프로그램을 바로 실행할 것인지를 선택적으로 결정하고 동작한다. 만약 플래쉬에 코드를 새로 써서 다시 변경할 필요가 없다면 응용 프로그램으로 바로 점프한다. 아두이노 통합 개발 환경에서 업로드가 실행되면, 부트로더가 동작하기 위해 그림의 (1)번 DTR 신호가 타겟 마이크로컨트롤러에 전달되어 리셋되고 부트로더가 실행된다. 리셋 신호를 ATmega16U2에서 전달하기 위해 캐패시터(0.1~0.22uF)를 사용하여 타깃과 연결되어 있다. 코드를 포함한 여러가지 데이터를 전달하기 위한 신호는 그림의 (2)번 선으로 이루어 진다.

업로드가 완료되면, 응용프로그램이 동작한다. 응용 프로그램에서 시리얼 통신을 사용했다면 코드가 실행되면서 시리얼 통신이 이루어진다. 그림의 (2)번 선으로 시리얼 통신이 이루어진다. 결국 부트로더 동작 시 코드 데이터와 응용 프로그램의 데이터가 같은 신호선을 따라 전달된다.

아두이노 부트로더[편집]

AVR 부트로더 플래시 메모리 구조

AVR 칩을 사용한 아두이노의 부트로더는 AVR의 부트로더 체계를 사용한다.[16] 따라서 아두이노의 부트로더는 AVR의 부트로더와 같은 의미이다. 아두이노의 개발 방법은 기본적으로 부트로더가 장착되는 방식을 사용하므로 부트로더를 기본적으로 장착한다. 따라서 퓨즈 비트를 부트로더가 실행 되로록 설정되고, 부트로더에서 플래시에 응용 프로그램 코드를 쓸지 아니면 코드 변경없이 바로 0번지의 응용프로그램으로 점프해서 실행할지를 결정한다. 개발 과정에서는 수 많은 코드 변경이 필요하므로 부트로더가 수시로 작동 하여야 하기 때문이다. 따라서 부트로더를 아예 장착되어 있고, 코드 실행 위치 벡터 및 크기가 결정되어 레지스터 비트 값이 퓨징 되어있다.

설정되는 비트는 다음 파일에서 확인할 수 있다:

[아두이노 설치 폴더]/hardware/arduino/avr/boards.txt

##############################################################

uno.name=Arduino Uno

uno.vid.0=0x2341
uno.pid.0=0x0043
uno.vid.1=0x2341
uno.pid.1=0x0001
uno.vid.2=0x2A03
uno.pid.2=0x0043

uno.upload.tool=avrdude
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.maximum_data_size=2048
uno.upload.speed=115200

uno.bootloader.tool=avrdude
uno.bootloader.low_fuses=0xFF
uno.bootloader.high_fuses=0xDE
uno.bootloader.extended_fuses=0x05
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.bootloader.file=optiboot/optiboot_atmega328.hex

##############################################################

mega.name=Arduino Mega or Mega 2560

mega.vid.0=0x2341
mega.pid.0=0x0010
mega.vid.1=0x2341
mega.pid.1=0x0042
mega.vid.2=0x2A03
mega.pid.2=0x0010
mega.vid.3=0x2A03
mega.pid.3=0x0042

mega.upload.tool=avrdude
mega.upload.maximum_data_size=8192

mega.bootloader.tool=avrdude
mega.bootloader.low_fuses=0xFF
mega.bootloader.unlock_bits=0x3F
mega.bootloader.lock_bits=0x0F

mega.build.f_cpu=16000000L
mega.build.core=arduino
mega.build.variant=mega
# default board  may be overridden by the cpu menu
mega.build.board=AVR_MEGA2560

## Arduino Mega w/ ATmega2560
## -------------------------
mega.menu.cpu.atmega2560=ATmega2560 (Mega 2560)

mega.menu.cpu.atmega2560.upload.protocol=wiring
mega.menu.cpu.atmega2560.upload.maximum_size=253952
mega.menu.cpu.atmega2560.upload.speed=115200

mega.menu.cpu.atmega2560.bootloader.high_fuses=0xD8
mega.menu.cpu.atmega2560.bootloader.extended_fuses=0xFD
mega.menu.cpu.atmega2560.bootloader.file=stk500v2/stk500boot_v2_mega2560.hex

mega.menu.cpu.atmega2560.build.mcu=atmega2560
mega.menu.cpu.atmega2560.build.board=AVR_MEGA2560

Fuse Byte 구조[편집]

  • 상위 퓨즈 바이트(High Fuse Byte)
UNO: high_fuses=0xDE=B11011110
MEGA2560: high_fuses=0xD8=B11011000
비트 상위 퓨징
바이트
기능 초기설정(default) UNO Mega2560
7 RSTDISBL 외부 RESET 비활성 1 (unprogrammed) 1 1
6 DWEN 디버그와이어 활성화 1 (unprogrammed) 1 1
5 SPIEN 시리얼 프로그램 활성화,
그리고 데이터 다운로딩
0 (unprogrammed,
SPI 프로그래밍 활성화)
0 0
4 WDTON 워치독 타이머 항상 켜기 1 (unprogrammed) 1 1
3 EESAVE 칩 소거 시, EEPROM 보존 1 (unprogrammed), EEPROM 보존 1 1
2 BOOTSZ1 부트영역 크기 1 0 (programmed) 1 0
1 BOOTSZ0 부트영역 크기 0 0 (programmed) 1 0
0 BOOTRST RESET 벡터 선택 1 (unprogrammed) 0 0
  • 하위 퓨즈 바이트(Low Fuse Byte)
UNO: low_fuses=0xFF=B11111111
MEGA2560: low_fuses=0xFF=B11111111
Bit 7 6 5 4 3 2 1 0
L_Fuse CKDIV8 CKOUT SUT1 SUT0 CKSEL3 CKSEL2 CKSEL1 CKSEL0
초기설정
default
1 1 1 1 1 1 1 0
UNO 1 1 1 1 1 1 1 1
Mega2560 1 1 1 1 1 1 1 1
CKDIV8 : 입력된 클럭을 내부에서 8분주 후 사용
CKOUT: CKOUT기능이 있는 핀으로 클럭을 출력
SUT[1: 0]: 두 비트의 설정에 따라 변경되고, 옵션은 MCU가 동작하지 않다,
클럭입력 후 명령을 수행할 수 있는 상황까지의 지연시간을 결정한다.
CKSEL[3:0]: 주 클럭으로 사용 할것인 결정한다. (설정 주의)
  • 확장 퓨즈 바이트(Extanded Fuse Byte)
UNO:extended_fuses=0x05=B00000101
MEGA2560: extended_fuses=0xFD=B11111101
Bit 7 6 5 4 3 2 1 0
L_Fuse - - - - - - - SELFPRGEN
초기설정
default
1 1 1 1 1 1 1 1
UNO 0 0 0 0 0 1 0 1
Mega2560 1 1 1 1 1 1 0 1
SELFPRGEN: AVR시리즈 중에 부트섹터 영역이 분리되지 않은 경우 SELFPRGEN =0이면, 전체 플래시에 대해 SPM명령어를 가능하게 한다.
  • BOOTSZ[1:0]
BOOTSZ1 BOOTSZ0 부트 크기
(words)
페이지
(pages)
플래시
응용 영역
플래시
부트 영역
부트영역
시작주소
1 1 128 4 0x000-0xF7F 0xF80-0xFFF 0xF80
1 0 256 8 0x000-0xEFF 0xF00-0xFFF 0xF00
0 1 512 16 0x000-0xDFF 0xE00-0xFFF 0xE00
0 0 1024 32 0x000-0xBFF 0xC00-0xFFF 0xC00

아두이노 퓨즈 비트[편집]

Arduino Fuses
Low High Extended
Arduino Uno 0xFF 0xDE 0x05
Arduino Duemilanove or Nano w/ ATmega328 0xFF 0xDA 0x05
Arduino Diecimila, Duemilanove, or Nano w/ ATmega168 0xFF 0xDD 0x00
Arduino Mega 2560 0xFF 0xD8 0xFD
Arduino Mega (ATmega1280) 0xFF 0xDA 0xF5
Arduino Mini 0xFF 0xDD 0x00
Arduino Fio 0xFF 0xDA 0x05
Arduino BT w/ ATmega328 0xFF 0xD8 0x05
Arduino BT w/ ATmega168 0xFF 0xDD 0x00
LilyPad Arduino w/ ATmega328 0xFF 0xDA 0x05
LilyPad Arduino w/ ATmega168 0xE2 0xDD 0x00
Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328 0xFF 0xDA 0x05
Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168 0xFF 0xDD 0x00
Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328 0xFF 0xDA 0x05
Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168 0xC6 0xDD 0x00
Arduino NG or older w/ ATmega168 0xFF 0xDD 0x00
Arduino NG or older w/ ATmega8 0xDF 0xCA

AVR 부트로더[편집]

AVR 내의 플래시 메모리 중에 부트로더 영역에 부트로더 프로그래밍 코드가 장착된다. 마이크로컨트롤러의 동작 목적을 수행하는 응용 프로그램은 플래시의 0000번지에 써지고 RESET에 의해 시작되어야 한다. 부트로더를 사용한다면 결국 부트로더와 응용 프로그램 2개가 동시에 플래시에 존재하게 된다. RESET 신호에 의해 마이크로컨트롤러가 시작하면 둘 중 하나를 실행해야 한다. AVR의 시작 방법은 퓨즈 비트의 설정으로 시작을 정한다.

AVR 내에 부트로더가 장착되어 있을 때, RESET 시 2개의 프로그램 중 하나를 선택해서 실행해야 한다. 만약 AVR 내의 BOOTRST비트가 1이면 0000번지가 실행되고, 0이면 부트로더 영역 주소(Boot Reset Address)가 선택적으로 실행된다. 부트 영역의 공간은 BOOTSZ1, BOOTSZ0에 의해 4가지 영역의 크기가 선택적으로 결정된다. 즉, 부트로더 시작 주소는 BOOTSZx의 비트 퓨즈에 따라 자동 결정된다. 부트로더 시작 주소는 플래시 끝 주소에서 부터 공간의 크기를 빼면 된다. 그러나 아두이노 입장에서 BOOTRST 비트 퓨징을 매번하는 과정은 그리 쉬운 일은 아니다. 따라서 아두이노는 RESET 시 무조건 부트로더로 점프(BOOTRST=0)하고 부트로더 프로그램에서 업로드를 할 지 응용 프로그램을 실행할 지를 결정한다.

부트로더가 작동하면 우선 프로그래밍 코드를 쓰는 과정을 실행할지, 아니면 바로 개발자가 개발한 응용 프로그램을 실행할 지를 결정한다. 부트로더는 포트 D의 특정 입력 핀을 읽어 LOW이면 부트로더 기능을 실행하도록 결정한다.

AVR 부트로더 실행 절차[16]
  • 부트로더 실행 순서는 다음과 같다:
  1. 우선 포트 D을 입력할 수 있도록 설정을 하고,
  2. 만약 포트 D의 특정 핀의 입력이 HIGH로 호스트로 부터 아무것도 오지 않으면, 응용 프로그램이 있는 0000 번지를 실행하여 부여된 기능을 수행한다.
  3. 만약 포트 D가 LOW이면, 응용 프로그램의 코드 쓰기 절차(명령줄 처리)로 진행한다. 부트로더의 원래 기능이다.
    1. 호스트로부터 오는 프로그램을 받는다.
    2. 부트로더를 위해 정해진 명령줄에 따라 해석을 하여 명령줄을 검증하고,
    3. 명령줄에 오류가 없으면, 수신된 명령에 따라 동작한다.

아두이노 제품[편집]

종류[편집]

제품에 사용된 MCU는 아트멜의 megaAVR, tinyAVR시리즈와 ARM MCU로 만들어 진다.

MCU 아두이노 보드
AVR
ATmega168 Pro(168), Mini(168), LilyPad (168V)
ATmega328 UNO, Fio, Nano, Pro(328), Mini(328, Rev5, 5V), Pro Mini, LilyPad (328V)
ATmega2560 Mega 2560, Mega ADK
ATmega32U4 Yún, Leonardo, Esplora, Micro
ATtiny85 GEMMA
ARM
Cortex-M0+ Zero, Zero PRO, M0, M0 PRO
Cortex-M3 Due

쉴드[편집]

쉴드(Shield)는 특정 기능을 갖는 보드로, 아두이노와 결합하여 호환 가능한 여러 부가 모듈과 연결하는 커넥터 구조를 포함한 부품이다. 특정 입출력 기능을 담당하는 부품으로, 아두이노에서 중요한 부품 중 하나이다. 아두이노의 입출력 커넥터에 연결할 수 있는 커넥터를 사용하고 각 부분품은 커넥터에 연결함으로써 적층 구조로 서로 연결한다.

아두이노 MCU 보드는 마이크로컨트롤러 기능 만 존재하기 때문에 센서나 기타 입출력 장치가 필요한 경우가 생긴다. 따라서 이 모듈들을 연결하는 방법으로 쉴드를 사용할 수 있다. 쉴드가 연결되면 커넥터를 통해 각 층으로 모든 필요한 핀이 연결된다. 아두이노 쉴드는 보드와 보드를 결합하여 여러가지 기능적 모듈들을 연결하는 방식이다.

쉴드 적층

연결 핀들이 위와 아래로 연결되면서 각 층에서 모두 사용할 수 있도록 구성되었다. 따라서 각 핀의 기능의 중복은 개발자가 판단하여 각층에서 선택적으로 사용하여야 한다. 몇몇 쉴드는 다른 복잡한 핀들을 거쳐서 보드와 직렬로 연결되지만, I²C 시리얼 버스를 사용하는 경우 고유 주소를 할당받을 수 있기 때문에 병렬로 연결하여 사용할 수 있다.

소프트웨어[편집]

아두이노 통합 개발 환경
개발자아두이노 소프트웨어
안정화 버전
1.6.5-r2 / 2015년 6월 17일(8년 전)(2015-06-17)[17]
프로그래밍 언어C++
운영 체제크로스 플랫폼
종류통합 개발 환경
라이선스LGPL 또는 GPL 라이선스
웹사이트arduino.cc

아두이노의 통합 개발 환경(IDE)은 JavaC를 기반으로 개발되는 크로스 플랫폼 응용 소프트웨어이며, 구문 강조, 괄호 찾기, 자동 들여쓰기 기능이 포함된 에디터와 한 번의 클릭으로 컴파일과 업로드가 가능한 컴파일러 기능을 포함하고 있다. 아두이노 동작을 위해서 C++ 언어 기반을 사용한다. 컴파일러는 avr-gcc[18]을 사용한다. 따라서 avr-gcc가 제공하는 많은 C언어의 표준라이브러리를 함수를 사용할 수 있다.

아두이노 개발환경은 C++을 사용하여 원하는 동작을 하도록 코딩을 하고 이것을 보드에 업로드하면 아두이노가 동작한다.아두이노 업로드는 플래시 메모리에 써지므로 다음부터는 전원만 인가하면 동작한다. 만약 PC나 안드로이드에서 아두이노에 오는 데이터를 받아 처리하고 싶다면, 해당 운영 체계에 맞는 개발 도구를 활용하여 프로그램을 작성해야 한다. PC의 비주얼 스튜디오나 안드로이드의 SDK 등이 대표적이다. 이러한 개발도구가 좀 어렵다고 느낀다면, 프로세싱[19]을 사용하여 쉽게 코딩 할 수 있다. 프로세싱은 아두이노 개발환경과 별개로 PC에서 동작하며, 아두이노에서 COM포트로 통신을 하고 이 데이터를 화면 등에 처리하여 보여 줄수 있다. 그래픽 처리를 할 수 있는 함수도 제공한다. 프로세싱에서 안드로이드 모드로 변경하면 안드로이드에서 처리할 수도 있다.

소프트웨어 개발에 생소한 사용자들도 쉽게 프로그래밍할 수 있도록 설계되어 있다. 이러한 아두이노 IDE를 통해 작성된 프로그램이나 코드를 "스케치(Sketch)"라고 부른다.

아두이노 통합 개발 환경[편집]

아두이노 통합환경은 편집기, 컴파일러, 업로드 등이 합쳐진 환경이다. 이와 더불어 기타 개발에 필요한 각종 옵션 및 라이브러리 관리를 할 수 있다. 실행 시, 개인용 컴퓨터와 시리얼 통신을 할 수 있는 모니터를 제공한다. 보통 USB을 통해 업로드를 하므로 아두이노 보드는 USB를 UART 통신으로 바꾸는 방법이 제공되고, MCU가 실행할 때는 이 UART 통신을 이용하여 필요한 통신을 할 수 있다. 이렇게 되려면 아두이노의 MCU는 부트로더가 올라가 있어야 한다.

아두이노 통합환경 기능은 :

  • 편집기 : UTF-8을 기반으로 하는 편집기 이다.
  • 컴파일러 : ATmega의 경우, AVR-GCC을 이용하여 컴파일 한다.
  • 업로드 : USB-UART 변환을 하고, MCU의 부트로더가 동작하여 기계어 코드가 업로드 된다.
  • 라이브러리 관리 : 등록 된 라이브러리 목록 및 예제를 지원한다. 공개 된 아두이노 라이브러리 찾아 파일을 받아 등록하면 초기에 장착되지 않은 각종 라이브러리를 등록 사용할 수 있다. 라이브러리 관리 프로그램도 검색 기능과 등록 기능을 제공한다.
  • 기타 옵션

USB가 없는 아두이노 보드는 USB-시리얼 변환 모듈을 별도 구매하여 연결할 수 있다.


아두이노 프로그램 절차[편집]

우선 응용 프로그램을 작성하기 위해 보드와 시리얼 통신을 설정한다. 업로드를 위해서는 아두이노 보드를 호스트에 연결하여 통합 개발 환경과 AVR의 부트로드가 동작하여 연결해야 한다.

윈도 COM 포트 선택 리눅스에서 시리얼 포드 선택 아두이노 보드 선택

만약 연결이 되지 않았거나 되었어도 제대로 동작하지 않았다면 업로드 실패로 나타난다.

아두이노 USB를 통한 시리얼 업로드 실패 업로드 완료

프로젝트를 만들고 빌드에 성공 했다해도 업로드가 불가능하다.

문제없이 연결되어 있다면 다음과 같이 업로드가 완료된다.


우선 프로젝트를 만드어야 한다. 프로젝트는 프로그램을 작성하고 파일을 저장하면 폴더 단위로 프로젝트가 자동 설정된다. 특별한 프로젝트 생성과정은 필요없다. 만약 여러개의 파일을 만들고 싶다면 탭에 파일을 추가하면 폴더 단위로 관리되고 여러파일 빌드가 된다.

우선 프로젝트를 만들고 응용 프로그램을 작성하여 빌드한다.

응용프로그램 빌드 빌드 오류

만약 프로그램 코딩에서 문법 오류가 발생하면 수정하고 재 빌드하면 된다.

필요한 라이브러리는 다음과 같이 초기에 설정된 파일과 사용자가 추가하는 라이브러리가 존재한다.

라이브러리 항목 라이브러리에 연결된 예제

아두이노 프로그래밍[편집]

라이브러리[편집]

아두이노는 AVR의 ATmega의 MCU을 기반으로 만들어진 것이므로 ATmega의 내에 장착된 기본 모듈을 함수 화하여 쉽게 접근할 수 있다. 이외에 다른 여러 가지 부품을 적용할 수 있도록 다양한 라이브러리가 존재한다.

아두이노 개발 IDE에 기본적으로 내장된 라이브러리도 있고, 외부의 많은 공개 라이브러리가 존재한다.

ATmega 내부 모듈[편집]

마이크로컨트롤러 하드웨어 포트를 사용하여 디지털 입출력을 구현한다.
pinMode() - 입출력 방향을 설정한다.
digtalRead(), digitalWrite() - 입출력 함수
하드웨어 시리얼 함수는 마이크로컨트롤러의 내부 시리얼 하드웨어 모듈을 사용한다.
Serial 객체
begin(), print(), read(), write(), available(), serialEvent()
if (Serial), find(), findUntil(), flush(), parseFloat(), parseInt(), peek(), readBytes(), readBytesUntil()
readString(), readStringUntil(), setTimeout()
하드웨어 모듈을 사용하므로 보드에 따라 제한된다.
Arduino UNO - Serial(핀0 RX, 핀1 TX)
Arduino Mega - Serial(핀0 RX, 핀1 TX), Serial1(핀19 RX, 핀18 TX), Serial2(핀17 RX, 핀16TX), Serial3(핀15 RX,핀14 TX)
AVR SPI 동기식 시리얼 인터페이스 하드웨어 모듈을 사용한다.
MISO (Master In Slave Out) - 슬래이브(slave)에서 마스터(master)로 보내는 전송라인.
MOSI (Master Out Slave In) - 마스터(master)에서 출력장치로 전송하는 라인,
SCK (Serial Clock) - 마스터(master)에서 만들어 주는 데이터 동기 신호.
SS (Slave Select) - 각 장치를 선택할 수 있는 신호선으로 마스터에서 활성화(enable) 또는 비활성화(disable)할 수 있다. 아두이노에서 위의 3개의 신호는 하드웨어에 의해 동작하지만 이 칩선택 신호는 디지털 출력을 사용하여 별도로 디지털 출력을 사용하여 제어해야 한다. 따라서 임의의 핀으로 설정이 가능하다.그러나 위의 3개 신호는 하드웨어와 연결되어 변경이 불가능하다.
SPI객체
begin(), end() , beginTransaction(), transfer() , endTransaction(),usingInterrupt()
setBitOrder(),setClockDivider(),setDataMode()
AVR I²C 동기식 시리얼 인터페이스 하드웨어 모듈을 사용한다.
SDA (data) - 데이터 전송 라인.
SCL (clock) - 데이터 동기신호 라인.
하드웨어 모듈을 사용하므로 각 보드에 따라 핀이 결정되어 있다.
Uno, Ethernet - A4 (SDA), A5 (SCL)
Mega2560 - 20 (SDA), 21 (SCL)
Leonardo - 2 (SDA), 3 (SCL)
Due - 20 (SDA), 21 (SCL), SDA1, SCL1
Wire 객체
begin(), beginTransmission(), endTransmission(), write(), read()
requestFrom(), available(), onReceive(), onRequest()
시간 읽기 함수
millis(), micros()
시간 지연 함수
delay(), delayMicroseconds()
  • PWM
PWM을 만들기 위해 타이머를 사용한다. 따라서 출력 핀은 해당 타이머 모듈에 의해 정해진 핀으로 제한된다.
analogWrite() - 특별한 설정없이 핀 번호 만을 가지고 자동으로 타이머를 할당한다. OCnA, OCnB핀을 사용하고, 여기서 n는 타이머 모듈를 지정하는 숫자이고, 보통 각 타이머 마다 2개의 핀이 할당 되어있다. 마이크로컨트롤로 마다 내장 타이머의 숫자가 다르고 핀번호 역시 다르므로 확인하여 사용하면 된다.
  • 외장 타이머 라이브러리
마이크로컨트롤로의 디지털 하드웨어 회로에 의해 동작하는 타이머를 사용한다. 다음 함수는 아두이노 1.6.5버전에서 라이브러리에 내장되지 않았다.
Timer 객체
Timer1 라이브러리 객체
Timer3 라이브러리 객체
  • ADC
AVR의 ADC 모듈 사용하고, 10비트가 내장되어 있다. ADC 모듈이 한개가 있기 때문에 여러 포트를 사용하려면 내부의 아날로그 MUX을 사용한다. 핀 번호에 의해 자동 설정된다.
함수
analogRead(), analogReference()

부가 모듈과 인터페이스[편집]

  • 소프트웨어 시리얼
소프트웨어로 처리하므로 핀을 임의로 정할 수 있으며, 하드웨어를 사용하지 않는다.
SoftwareSerial 클래스]
SoftwareSerial(rxPin, txPin) 생성자
SoftwareSerial 함수 - available(), begin(), read(),write(), print(), println()
isListening(), overflow(), peek(), listen()
NewSoftSerial 클래스
SoftwareSerial 보완 버전이다.
  • LCD
문자 LCD
Hitachi사의 HD44780( 또는 호환) 드라이브 칩을 기반으로 하는 문자 LCD 제어 함수이다. 이 칩은 8비트 또는 4비트 단위로 선택적 액세스할 수 있다. 따라서 클래스 생성자도 여러가지로 만들어 질수 있다. 만약 R/_W 신호를 사용하지 않는다면 0V(GND)에 연결하고, 클래스 생성에서 이 신호선이 없는 것으로 선택하면 된다. R/_W 신호를 사용하지 않는다면, W(쓰기)만 사용한다는 말이 된다. 따라서 칩의 레지스터 값을 읽을 수 없다.
LiquidCrystal 클래스
LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
LiquidCrystal 클래스 함수 - begin(), clear(),
home(), setCursor(), write(), print(), cursor()
noCursor(), blink(), noBlink(), display(), noDisplay(), scrollDisplayLeft(), scrollDisplayRight()
autoscroll(), noAutoscroll(), leftToRight(), rightToLeft(), createChar()
RTC 시간함수
Time Library
시간읽기
hour(); // 현재 시간 (0-23)
minute(); // 현재 분 (0-59)
second(); // 현재 초 (0-59)
day(); // 현재 날짜 (1-31)
weekday(); // 현재 요일, 일요일=1
month(); // 현재 월 (1-12)
year(); // 현재 년 (2009, 2010 etc)
setTime(hours, minutes, seconds, days, months, years); // 날짜와 시간 설정.
adjustTime(number);
DS1307RTC Library
RTC.get(); - 현재 시간과 날짜를 읽는다. 32비트 'time_t' 형태이다. 만약 DS1307동작하지 않으면, 0으로 리턴한다.
RTC.set(t); - 시간과 날짜를 설정한다. 32비트 'time_t' 형으로 인수를 넘긴다. 리턴값 true=성공, false=실패.
RTC.read(tm); - TimeElements(Time library) 변수로 시간과 날짜를 읽는다. 리턴값 true=성공, false=읽기 실패.
RTC.write(tm); - TimeElements을 사용한 시간과 날짜 설정.
RTC.chipPresent(); - 리턴값 true=DS1307가 존재해서 동작.

표준 함수의 사용 예 : printf[편집]

마이크로컨트롤러는 보통 입출력 장치가 컴퓨터와 다른다. PC에서 사용하는 모니터와 키보드를 보통 사용하지 않는다. 시리얼 통신으로 별도의 컴퓨터로 연결하여 사용하는 방식이 일반적이다. 따라서 표준 입력장치가 없을 때, 시리얼 통신을 사용하여 printf 함수에서 완성된 스트링을 출력할 수 있다. 즉, printf 결과를 개발자가 원하는 장치로 연결할 수 있다. 시리얼 통신 뿐만 아니라, 문자-LCD 등 원하는 장치로 출력할 수 있다.

아두이노는 avr-gcc를 사용하므로 이 규칙에 맞추어 사용하면 된다.

#include <stdio.h>

// 우선 FILE 선언을 사용하고, UART와 연결하여 사용한다.
static FILE uartout = {0} ;

// printf에서 완성된 스트링을 한 글자 씩 출력하는 함수가 있어야 한다.
// 스트링를 한바이트 씩 출력한다.
static int uart_putchar (char c, FILE *stream)
{
    Serial.print(c);  // 원하는 장치로 출력 한다.
    return 0 ;
}

void setup(void)
{
   Serial.begin(9600);  // 시리얼을 시작한다.

   // UART 출력을 위한 FILE 디스크립터를 사용한다.
   fdev_setup_stream (&uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE);
   stdout = &uartout ;  // 표준 출력 STDOUT을 선언한다.
}

void loop(void)
{
    float seconds ;
   
    seconds = (float) millis() /1000.0;
    printf("%d sec\n", (int) seconds);

    delay(1000) ;  // 1초를 기다리고
}

실수형 변환[편집]

printf, sprintf 등의 함수에서 %f로 지정된 float 실수형의 값 변환은 avr-gcc의 빌드 옵션 설정 상, 초기설정(default)에서는 지원하지 않는다. 다음과 같이 프로그래밍을 하고:

 printf("%f sec\n", seconds);

이 함수의 실행 결과를 보기 위해 시리얼 모니터를 보면 숫자 부분에 '?'가 나타난다.

이것은 초기설정(default) 값이:

-lprintf_min

으로 최소 옵션이기 때문이다. %f와 같은 변환은 불가능하다. -lprintf_flt으로 변경이 필요하다.

이것을 확인하기 위해 빌드 화면을 캡처하면 다음과 같은 컴파일 옵션으로 링크한다 (환경 아두이노 우노):

[아두이노 설치 폴더]\hardware\tools\avr/bin/avr-gcc -w -Os -Wl,--gc-sections -mmcu=atmega328p \
-o [사용자폴더]\AppData\Local\Temp\build6852210290743851828.tmp/스케치프로그램파일.cpp.elf \
[사용자폴더]\AppData\Local\Temp\build6852210290743851828.tmp\스케치프로그램파일.cpp.o \
[사용자폴더]\AppData\Local\Temp\build6852210290743851828.tmp/core.a \
-L[사용자폴더]\AppData\Local\Temp\build6852210290743851828.tmp -lm

아두이노 개발환경에서 avr-gcc의 옵션을 쉽게 추가 및 변경하는 메뉴가 없기 때문에, 아두이노 실수형 변환은 쉽게 구현하기가 힘들다. AtmelStudio 등의 개발도구에서 옵션을 넣는 방법을 제공하는 것과 대조적이다.

만약 실수형의 변환이 필요하다면 다음과 같은 2가지 방법으로 설정을 변경할 수 있다.

  • 개발도구를 재 빌드 하기
인터넷에서 제공되는 개발도구의 소스[20]를 바탕으로 다음 옵션을 변경하여 개발도구 자체를 재 빌드하는 방법이 있다.
링커 옵션에 추가:
-Wl,-u,vfprintf -lprintf_flt
  • platform.txt 파일 수정하여 옵션 변경 하기
다른 방법으로 platform.txt 파일을 수정해서 옵션을 변경할 수 있다.
[아두이노 설치 폴더]/hardware/arduino/avr/platform.txt (버전1.6.5에서)
compiler.c.elf.flags={compiler.warning_flags} -Os -Wl,--gc-sections
다음과 같이 수정한다.
compiler.c.elf.flags={compiler.warning_flags} -Os -Wl,-u,vfprintf,--gc-sections -lprintf_flt 

이러한 실수형의 계산은 대부분의 마이크로컨트롤러의 FPU(Floating-Point Unit)이 없기 때문에, 기계어 코드의 집합으로 된 함수를 호출하여 정수형 ALU을 통해 계산이 이루어 진다. 따라서 계산 속도와 메모리 차원에서 부담이 될 수 있다.

시리얼 통신을 지원하는 클래스 Serial에 실수형 변수값을 출력할 수 있는 방법이 존재하므로 경우에 따라 적절히 사용하면 더 효율적일 때가 있다.

Serial.print(실수형변수)
    float seconds ;
    seconds = (float) millis() /1000.0;
    Serial.print(seconds);
    Serial.println(" sec");

응용 프로그램[편집]

디지털 출력과 LED[편집]

핀 13에 LED 장착

아두이노 우노 R3에서는 LED가 13번 핀에 연결되어 있다. 따라서 다음과 같이 코딩하면 별도의 하드웨어 추가없이 우노에서 확인할 수 있다.

#define LED_PIN 13

void setup () {                     //처음 시작 할때만 실행
    pinMode (LED_PIN, OUTPUT);     // 13번 핀을 디지털 출력 핀으로 설정
}

void loop () {                        // 아래의 명령문을 반복
    digitalWrite (LED_PIN, HIGH);    // LED 점등
    delay (1000);                   // 1000ms(1초) 대기
    digitalWrite (LED_PIN, LOW);   // LED 소등
    delay (1000);                 // 1000ms(1초) 대기
}

우선 해야할 일이 포트 설정이다. LED를 제어하기 위해 핀의 모드를 출력으로 설정한다. 실정이 완료되면 원하는 시점에서 디지털 입출력을 할수 있다.


디지털 입력[편집]

스위치 입력 연결 회로

디지털 입력에서 일반적인 게이트 입력은 그림과 같이 많이 연결한다. 보통 스위치를 GND쪽에 연결하고 풀업저항을 통해 입력한다. 이렇게 되면 스위치가 눌리지 않으면 HIGH가 입력되고 스위치가 눌리면 LOW가 입력되어 프로그램에서 판단하면 된다.

#define SW_PIN  8

void setup () {
    pinMode (SW_PIN, INPUT); // 8번 핀을 디지털 입력 핀으로 설정
}

void loop () {
    char key = digitalWrite (SW_PIN); // 키의 상태를 읽는다.
    if (! key) {
       // 키 입력 시 처리해야할 일  
    }

    delay(200);                   // 200ms 마다 반복한다.
}

이런 경우 간단히 처리를 하기 위해 코드인데, 실제의 키에서 보통 이런경우 까다롭은 문제를 발생한다.

  1. 스위치 등의 물리적 소자는 디지털 입력에서 간단한 입력 신호가 발생하지 않는다. 채터링 문제는 입력시 HIGH에서 바로 LOW로 안정적으로 입력되지 않고, 스위치 상태 변화 시 HIGH LOW가 잛은 시간에 반복적으로 나타난다. 이것을 잘못 처리하면 한번의 키 동작으로 두번의 키 입력으로 동작할 수 있다. 이런 경우 상태도를 이용하여 키의 상태를 관리하는 방법이 효과적이다.
  2. delay 함수는 시간이 길수록 복잡한 동작할 때 블럭킹 현상을 초래한다. 따라서 타이머 등의 조합으로 시간 지연이 바람직하다.

아두이노에서 풀업 문제는 회로에 저항을 달아야 하므로 AVR의 내부 풀업을 이용할 수 있다.

void setup () {
    pinMode (SW_PIN, INPUT_PULLUP); // AVR의 내부 풀업을 이용, 외부의 저항이 필요없다.
}

LCD 표시[편집]

아두이노 LCD LiquidCrystal Constructor


/*
 * 소스 : http://www.arduino.cc/en/Tutorial/LiquidCrystal
 *
 * 회로:
 * LCD RS 핀 - 12
 * LCD Enable 핀 - 11
 * LCD D4 핀 -  5
 * LCD D5 핀 -  4
 * LCD D6 핀 -  3
 * LCD D7 핀 -  2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

 */

#include <LiquidCrystal.h>

// 아두이노 라이브러리에서 제공하는 인터페이스를 사용하였다.
//   R/W 신호는 사용하지 않으므로 회로에서 GND에 연결한다.
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS, E, D4,D5,D6,D7

void setup() {
  // LCD의 화면 크기가 2줄에, 줄당 16문자 표시 장치 일때
  lcd.begin(16, 2);
  // 초기 출력을 하여 처음 표시되는 문자를 출력한다. 초기 위치는 (0,0) 이다.
  lcd.print("hello, world!");
}

void loop() {
  // 첫번째 컬럼 0, 두번째 줄 1 설정
  lcd.setCursor(0, 1);
  // reset으로 부터의 시간을 초 단위로 표시한다:
  lcd.print(millis()/1000);
}

버저에 의한 소리[편집]

PWM

디지털 PWM 출력 함수

  • Tone 라이브러리

Tone 라이브러리


아두이노 버저
int pinBuzzer = 5;   // 버저 출력 핀 5번 - Timer0사용 OC0A PWM 출력
void setup()
{
  pinMode(pinBuzzer, OUTPUT);   // 핀 모드를 출력으로 설정
}

void loop() {

   analogWrite(pinBuzzer, 127);  // 127은 듀티 50%, 8비트 카운터 이므로 255까지의 반이다.
   delay(1000);

   analogWrite(pinBuzzer, 0);  // 소리를 없앤다.
   delay(1000);
}

analogWrite함수를 사용했을 때, PWM 출력은 1kHz가 되지 않는다. 따라서 버저의 특성을 파악해서 주파수 변경을 할 필요가 있다. 만약 주파수가 다르다면 주기를 정밀하게 출력할 수 있는 타이머를 선택해야 한다. Timer0,2는 8비트 카운터를 사용하므로 주파수 조절은 CSx 비트 설정에 의해 프리스케일의 설정에 의해 주파수를 변경할 수 있으나 분해능이 떨어져 정확한 소리를 만들수 없다.

Time1,3 등의 16비트 카운터 타이머를 사용하고 tone() 함수를 적절히 사용하면 원하는 주파수를 얻을 수 있다.

PIR 인체 감시[편집]

Buzzer


아두이노 그림[편집]

아두이오
아두이오
아두이오 우노

아두이노 하드웨어 개발환경[편집]


아두이노 연결[편집]

통신 및 인터페이스[편집]

입출력 장치[편집]

출력 제어[편집]

상업용 아두이노 보드[편집]


아두이노 쉴드[편집]

쉴드 적층

각 층은 다음과 같은 소켓을 이용하여 연결할 수 있다.

쉴드용 소켓

같이 보기[편집]

주석[편집]

  1. “아두이노 빌드”. 2015년7월9일에 확인함. 
  2. “AVR Libc”. 2015년7월9일에 확인함. 
  3. “아두이노 라이브러리”. 2015년7월9일에 확인함. 
  4. “아두이노 개발환경 - 다운로드”. 2015년6월19일에 확인함. 
  5. “Arduino - Introduction”. 
  6. “Atmel Studio”. 
  7. 류한석 (2013년 7월 9일). “아두이노, 상상력을 실현하는 플랫폼”. 주간경향. 2013년 7월 12일에 확인함. 
  8. Arduino Board - Serial Interface
  9. News; Arduino.cc
  10. Phillip Torrone (2011년 5월 12일). “Why Google Choosing Arduino Matters and Is This the End of "Made for iPod" (TM)?”. makezine.com. 2012년 1월 1일에 확인함. 
  11. Smart Projects
  12. Arduino Diecimila 회로도
  13. Arduino Mega2560 회로도
  14. Arduino UNO Rev3 회로도
  15. Arduino Mega2560 Rev3 회로도
  16. “Self Programming” (PDF). 
  17. “Arduino Software Release Notes”. Arduino Project. 2015년6월25일에 확인함. 
  18. “AVR gcc 사이트”. 2015년6월19일에 확인함. 
  19. “Processing 사이트”. 2015년6월19일에 확인함. 
  20. 아두이노 개발 도구 소스 버전1.6.5

바깥 고리[편집]