Arduino(アルドゥイーノ)は,ATMEL社のAVRチップ(ATmega8, ATmega168, ATmega328Pなど)を搭載した基板と,Arduino言語とそれらを使用して開発するための統合開発環境(IDE)から構成されるシステムのことらしい。
イタリアのIDIIで学んでいたHernando Barragán氏が修士論文のテーマとして,「電子回路のハードウェアを抽象化して,より一般的な人が開発できるようにすること」を研究していた。実際に開発したものが後にArduinoというプラットフォームとなったようだ。当時のハードウェアや開発ツールに比べてできるだけ安価にすることがポイントだったらしい。
Hernando Barragán氏の論文はここで読むことが出来る。
ハードウェアの情報は公開されていて,誰でも機能が同じボードを作成することが出来る。実際にオリジナルボード以外にも,多くのボードが市販されている。
現在では,入門用IoT機器の定番として扱われるようになり,世界的に人気になっているみたい。
最近まで知らなかったんだけど便利らしいんで,試しに自分の作成した基板で試してみた。
ハードウェアは,自作したATmega168PA-20AUとFT232BMを実装した基板があるんで,それを試しに使用してみる。ポートの使用方法(LEDはPB0など)が多少違うぐらい。
Arduino IDEからプログラムを書き込む時には,ソフトウェア的にはUART経由で書き込む。自作の基板は,シリアル-USBコンバーターのFTDIのFT232BMを実装しているんで,PCからは仮想COMポートでアクセスする。
Arduinoの統合開発環境はクロスプラットフォームで動作するJavaアプリケーションで,エディタ,コンパイラ,基板へのファームウェア転送機能,さらに各種ライブラリ,サンプルプログラム,Java JREなどを含んだALL IN ONEツール。
下回りには,コンパイラはAVR-GCCで,基板へプログラムを書き込むのには avrdude といったAVR開発時に使われる一般的なツールが使われている。
プログラミングスタイルは,C/C++言語風の構文で,AVRの基板向けに最適化されているみたい。ちなみに,Arduinoではプログラムのことをスケッチと呼んでいる。
ArduinoのサイトのSOFTWAREからArduino 1.0.1のWindows版*1をダウンロードした。
適当なディレクトリに解凍すればセットアップは完了。
Windows版のArduino 1.0.1はavr-gccにはWinAVR-20081205が使われている。すでにWinAVR-20100110をPCに入れてあるんだけど気にしないでおく。
なぜかMinGWをインストールしていてCPLUS_INCLUDE_PATH環境変数を設定していると,Arduinoでコンパイルがうまく行かなくなっちゃうので,CPLUS_INCLUDE_PATH環境変数を削除した。
自作の基板で使えるように,いくつかのファイルを編集する。
hardware\arduino\boards.txtの先頭に以下を追加。
############################################################## piramp8.name=Yuji's AVR Board(8MHz) piramp8.upload.tool=avrdude piramp8.upload.protocol=arduino piramp8.upload.maximum_size=14336 piramp8.upload.speed=19200 piramp8.bootloader.low_fuses=0xc2 piramp8.bootloader.high_fuses=0xdd piramp8.bootloader.extended_fuses=0xf8 piramp8.bootloader.file=atmega/ATmegaBOOT_168P_piramp_8mhz.hex piramp8.bootloader.unlock_bits=0x3F piramp8.bootloader.lock_bits=0x0F piramp8.build.mcu=atmega168p piramp8.build.f_cpu=8000000L piramp8.build.board=AVR_PIRAMP8 piramp8.build.core=arduino piramp8.build.variant=piramp ############################################################## piramp16.name=Yuji's AVR Board(16MHz) piramp16.upload.tool=avrdude piramp16.upload.protocol=arduino piramp16.upload.maximum_size=14336 piramp16.upload.speed=19200 piramp16.bootloader.low_fuses=0xcf piramp16.bootloader.high_fuses=0xdd piramp16.bootloader.extended_fuses=0xf8 piramp16.bootloader.file=ATmegaBOOT_168P_piramp_16mhz.hex piramp16.bootloader.unlock_bits=0x3F piramp16.bootloader.lock_bits=0x0F piramp16.build.mcu=atmega168p piramp16.build.f_cpu=16000000L piramp16.build.board=AVR_PIRAMP16 piramp16.build.core=arduino piramp16.build.variant=piramp ##############################################################
hardware\arduino\programmers.txtへ追加
avrisp2.name=ISP2 old one avrisp2.communication=serial avrisp2.protocol=stk500v2 yujiisp.name=Yuji Ueno's ISP Cable yujiisp.communication=par yujiisp.protocol=yuji
これはbootloaderを書き込む時に使用するライターを指定する時に使われる。
手持ちの古いAVR ISP(V2プロトコル版にしてある)を使用するため。
hardware\arduino\variants\pirampディレクトリを新規に作成する。
作成したpirampディレクトリの中に,pins_arduino.hを作成する。
これは,ATmega168PのPB6,PB7を使えるようにしたり,LEDの接続位置の違いだったりに対応するため。
hardware\tools\avr\etc\avrdude.confに自作のAVRライター用の定義を追加しておく。バージョン1.8.19なんかの新しいバージョンでは最新版のavrdudeが入っているのでこの作業は必要ない。
1.0.1用:avrdude.conf ATmega168P用の定義はすでにあった。ATmega328用の定義を追加しておく。
Arduinoの直接の機能ではないが,Arduino IDEから直接プログラム(スケッチ)を基板のFlash ROMに書き込めるようにするには,Arduino IDEからスケッチをコンパイルしたオブジェクトを基板に書き込む機能を持ったbootloaderを基板に書き込んでおく必要がある。
bootloaderもArduinoのパッケージに含まれているんだけど,ATmega168Pに対応していない事やオンボードLEDのポートが違うなんかがあって,ソースを修正して自分の基板にあうように変更してビルド後書き込だ。ATmegaBOOT_168P_piramp_8mhz.hex
ATmegaBOOT_168P_piramp_16mhz.hex
ビルドしてbootloaderを基板に書き込んだら,bootloaderのロックビットでプロテクトしておく。
bootloaderはArduino IDEからも書き込むことが出来る。IDEのツール>マイコンボードで基板を選んで,ツール>書き込み装置で使用する書き込みライターを指定して,ISPコネクタを使用して「ツール>ブートローダーを書き込む」で書き込むことが出来る。
スケッチを書き込む時は,基板をリセットしbootloaderを立ち上げる必要がある。
この目的のために市販されているArduinoボードは,シリアル-USBコンバーターのDTR信号とCPUのReset間に0.1uFのコンデンサーを実装して,DTR信号でCPUのリセットを行えるようになっている。
自作の基板にはリセットSWもこのような回路も無いため,ISPコネクタのRSTをGNDとショートさせて手動でリセットさせる。
ユーザープログラムが立ち上がるまでにArduino IDEから書き込む必要がある。(この操作が少しめんどくさい。)
まず,ターゲットのボードをPCのUSBポートに接続する。
Arduino IDEを起動して,「ツール>マイコンボード」からYuji's PIRAMP Board(8MHz)を選択する。
「ツール>シリアルポート」で,ボードのCOMポートを設定する。
「ファイル>スケッチの例>01.Basics>Blink」を開く。
少し以下のように,
int led = 13; ↓ int led = 8;
変更する。
ツールアイコンの左から2番めにある→を押す。
これでソースコードがビルドされ,ボードに書き込まれる。(この時,手動のリセットが必要)
プログラムが書き込まれ後,しばらくするとボード上のLEDが1秒毎に点滅した。
Arduino IDEは,ソースコードを編集する機能(エディター)とオブジェクトをターゲット基板に書き込むI/Fが主な機能になっている。
また,Arduino言語と呼ばれているdefineで定義したマクロを使用して,多少プログラムが書きやすくなるように工夫をしている。
しかし,使い慣れたエディターとmakeツールでも同様な作業は行えるので,特にArduino IDEを使う必要があるかと言うと,必要はないなってのが感想。
Arduino IDE 1.8.5でコンパイルしてみると,エラーが出て失敗した。
エラー直前の処理がctagsだったので,ctagsを単独で動かすと,appendモードについてのエラーが出ていた。
ctags: append mode is not compatible with tags to stdout
%HOME%/.ctagsを確認すると,
--append=yes --recurse=yes --langmap=PHP:+.inc --php-kinds=cfd
になっていた。しょうがないんで,
--append=no --recurse=yes --langmap=PHP:+.inc --php-kinds=cfd
に変更。
これで無事コンパイル出来るようになった。
arduino-1.0.1\hardware\arduino\cores\arduino\main.cppを覗いてみると,
#include <Arduino.h> int main(void) { init(); #if defined(USBCON) USBDevice.attach(); #endif setup(); for (;;) { loop(); if (serialEventRun) serialEventRun(); } return 0; }
となっていた。(バージョン1.0.1)
なので,setup()とloop()を書き忘れると,エラーとなるわけです。
それでは,init()はどこに書かれているかというと,arduino-1.0.1\hardware\cores\arduino\wiring.cにありました。
void init() { // this needs to be called before setup() or some functions won't // work there sei(); // on the ATmega168, timer 0 is also used for fast hardware pwm // (using phase-correct PWM would mean that timer 0 overflowed half as often // resulting in different millis() behavior on the ATmega8 and ATmega168) #if defined(TCCR0A) && defined(WGM01) sbi(TCCR0A, WGM01); sbi(TCCR0A, WGM00); #endif // set timer 0 prescale factor to 64 #if defined(__AVR_ATmega128__) // CPU specific: different values for the ATmega128 sbi(TCCR0, CS02); #elif defined(TCCR0) && defined(CS01) && defined(CS00) // this combination is for the standard atmega8 sbi(TCCR0, CS01); sbi(TCCR0, CS00); #elif defined(TCCR0B) && defined(CS01) && defined(CS00) // this combination is for the standard 168/328/1280/2560 sbi(TCCR0B, CS01); sbi(TCCR0B, CS00); #elif defined(TCCR0A) && defined(CS01) && defined(CS00) // this combination is for the __AVR_ATmega645__ series sbi(TCCR0A, CS01); sbi(TCCR0A, CS00); #else #error Timer 0 prescale factor 64 not set correctly #endif // enable timer 0 overflow interrupt #if defined(TIMSK) && defined(TOIE0) sbi(TIMSK, TOIE0); #elif defined(TIMSK0) && defined(TOIE0) sbi(TIMSK0, TOIE0); #else #error Timer 0 overflow interrupt not set correctly #endif // timers 1 and 2 are used for phase-correct hardware pwm // this is better for motors as it ensures an even waveform // note, however, that fast pwm mode can achieve a frequency of up // 8 MHz (with a 16 MHz clock) at 50% duty cycle #if defined(TCCR1B) && defined(CS11) && defined(CS10) TCCR1B = 0; // set timer 1 prescale factor to 64 sbi(TCCR1B, CS11); #if F_CPU >= 8000000L sbi(TCCR1B, CS10); #endif #elif defined(TCCR1) && defined(CS11) && defined(CS10) sbi(TCCR1, CS11); #if F_CPU >= 8000000L sbi(TCCR1, CS10); #endif #endif // put timer 1 in 8-bit phase correct pwm mode #if defined(TCCR1A) && defined(WGM10) sbi(TCCR1A, WGM10); #elif defined(TCCR1) #warning this needs to be finished #endif // set timer 2 prescale factor to 64 #if defined(TCCR2) && defined(CS22) sbi(TCCR2, CS22); #elif defined(TCCR2B) && defined(CS22) sbi(TCCR2B, CS22); #else #warning Timer 2 not finished (may not be present on this CPU) #endif // configure timer 2 for phase correct pwm (8-bit) #if defined(TCCR2) && defined(WGM20) sbi(TCCR2, WGM20); #elif defined(TCCR2A) && defined(WGM20) sbi(TCCR2A, WGM20); #else #warning Timer 2 not finished (may not be present on this CPU) #endif #if defined(TCCR3B) && defined(CS31) && defined(WGM30) sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64 sbi(TCCR3B, CS30); sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode #endif #if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 sbi(TCCR4B, CS41); sbi(TCCR4B, CS40); sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D #else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ #if defined(TCCR4B) && defined(CS41) && defined(WGM40) sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 sbi(TCCR4B, CS40); sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode #endif #endif /* end timer4 block for ATMEGA1280/2560 and similar */ #if defined(TCCR5B) && defined(CS51) && defined(WGM50) sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64 sbi(TCCR5B, CS50); sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode #endif #if defined(ADCSRA) // set a2d prescale factor to 128 // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. // XXX: this will not work properly for other clock speeds, and // this code should use F_CPU to determine the prescale factor. sbi(ADCSRA, ADPS2); sbi(ADCSRA, ADPS1); sbi(ADCSRA, ADPS0); // enable a2d conversions sbi(ADCSRA, ADEN); #endif // the bootloader connects pins 0 and 1 to the USART; disconnect them // here so they can be used as normal digital i/o; they will be // reconnected in Serial.begin() #if defined(UCSRB) UCSRB = 0; #elif defined(UCSR0B) UCSR0B = 0; #endif }
AVRマイコンを使用するプログラムを作成する場合,ポートの入出力方向の設定,クロック速度の設定,割込処理の設定など・・・,AVRマイコンの動作を決定する各種設定を行うためのプログラムが必要になります。
sbi()関数は,レジスタの任意のビットを有効にするためのgccで定義されているマクロです。
Arduino IDEで開発を行う時には,これらをユーザーに負担にならないようにあらかじめ用意してあるわけです。
Arduino Uno | Arduino Leonardo | Arduino Due | Arduino MEGA 2560 | Arduino MEGA ADK | |
特徴 | 人気 | Arduino UNOの廉価版 USBはCPU内蔵 | 動作電圧が3.3V | ATmega2560で,Flash ROM大きい | USBでAndroid端末に接続 |
価格 | 2520円 | 2100円 | 4980円 | 4910円 | 6420円 |
CPU | ATmega328P | ATmega32u4 | AT91SAM3X8E | ATmega2560 | ATmega2560 |
Clock | 16MHz | 16MHz | 84MHz | 16MHz | 16MHz |
Flash ROM | 32KB (内0.5KBはbootloader用) | 32KB (内4KBはbootloader用) | 512KB | 256KB (内8KBはbootloader用) | 256KB (内8KBはbootloader用) |
SRAM | 2KB | 2.5KB | 96KB | 8KB | 8KB |
EEPROM | 1KB | 1KB | - | 4KB | 4KB |
デジタルI/Oピン | 14本 (内6本はPWM出力) | 20本 (内7本はPWM出力) | 54本 (内12本はPWM出力) | 54本 (内15本はPWM出力) | 54本 (内15本はPWM出力) |
PWMピンNo | 3, 5, 6, 9, 10, 11 | 3, 5, 6, 9, 10, 11, 13 | 2〜13 | 2〜13,44〜46 | 2〜13,44〜46 |
LEDピンNo | 13 | 13 | 13 | 13 | 13 |
Analog入力 | 6本 | 12本 | 12本 | 16本 | 16本 |
Analog出力 | - | - | 2本 | - | - |
動作電圧 | 5V | 5V | 3.3V | 5V | 5V |
電源電圧 | 7-12V&br:(6-20V) | 7-12V (6-20V) | 7-12V (6-20V) | 7-12V (6-20V) | 7-12V (6-20V) |
電源 | USB or 外部電源(2.1mmプラグ) | USB or 外部電源(2.1mmプラグ) | USB or 外部電源(2.1mmプラグ) | USB or 外部電源(2.1mmプラグ) | USB or 外部電源(2.1mmプラグ) |
Arduino Ethernet | Arduino Mini | LilyPad Arduino | LilyPad Arduino USB | Arduino Micro | |
特徴 | イーサネットポート付 USB-シリアルドライバチップ無し | ブレッドボード用 USB-シリアルドライバチップ無し | ウェアラブルデバイス用 USB-シリアルドライバチップ無し | USB接続 | Adafruitと共同開発 |
価格 | 5030円 | 2995円 | 2195円 | 2495円 | 2260円 |
CPU | ATmega328 | ATmega168 or ATmega328 | ATmega168V or ATmega328V | ATmega32u4 | ATmega32u4 |
Clock | 16MHz | 16MHz | 8MHz | 8MHz | 16MHz |
Flash ROM | 32KB (内0.5KBはbootloader用) | 32KB (内2KBはbootloader用) | 16KB (内2KBはbootloader用) | 32KB (内4KBはbootloader用) | 32KB (内4KBはbootloader用) |
SRAM | 2KB | 2KB | 1KB | 2.5KB | 2.5KB |
EEPROM | 1KB | 1KB | 512B | 1KB | 1KB |
デジタルI/Oピン | 14本 (内4本はPWM出力) | 14本 (内6本はPWM出力) | 14本 (内6本はPWM出力) | 9本 (内4本はPWM出力) | 10本 (内7本はPWM出力) |
PWMピンNo | 3, 5, 6, 9, 10 | 3, 5, 6, 9 10, 11 | 3, 5, 6, 9, 10, 11 | 3, 9 ,10, 11, 13 | 3, 5, 6, 9, 10, 11, 13 |
LEDピンNo | 9 | 13 | 13 | 13 | 13 |
Analog入力 | 6本 | 8本 | 6本 | 4本 | 12本 |
Analog出力 | - | - | - | - | - |
動作電圧 | 5V | 5V | 2.7-5.5V | 3.3V | 5V |
電源電圧 | 7-12V (6-20V) | 7-9V | 2.7-5.5V | 3.8-5V | 7-12V (6-20V) |
電源 | Ethernet (PoE) モジュール or FTDI ケーブル/USBシリアルコネクター | 外部電源(5Vピン or 9Vピン) | USB or 外部電源 | micro USB or 3.7V LiPoバッテリー | USB or 外部電源 |
Arduino Nano | Arduino Pro Mini | Arduino Pro | Arduino Fio | Arduino Esplora | |
特徴 | Arduino Duemilanoveと同等で小さい ブレッドボード用 | 製品組込用 USB-シリアルドライバチップ無し | 製品組込用 USB-シリアルドライバチップ無し | ワイヤレスアプリケーション用 SparkFun生産 | オンボードセンサー実装 |
価格 | 4200円 | 1895円 | 1995円 | 2495円 | - |
CPU | ATmega168 or ATmega328 | ATmega328P | ATmega168 or ATmega328 | ATmega328P | ATmega32u4 |
Clock | 16MHz | 8MHz | 8MHz or 16MHz | 8MHz | 16MHz |
Flash ROM | 16KB or 32KB (内4KBはbootloader用) | 16KB (内2KBはbootloader用) | 16KB or 32KB (内2KBはbootloader用) | 32KB (内2KBはbootloader用) | 32KB (内4KBはbootloader用) |
SRAM | 1KB or 2KB | 1KB | 1KB or 2KB | 2KB | 2.5KB |
EEPROM | 512B or 1 KB | 512B | 512B or 1KB | 1KB | 1KB |
デジタルI/Oピン | 14本 (内6本はPWM出力) | 14本 (内6本はPWM出力) | 14本 (内6本はPWM出力) | 14本 (内6本はPWM出力) | - |
PWMピンNo | 3, 5, 6, 9, 10, 11 | 3, 5, 6, 9, 10, 11 | 3, 5, 6, 9, 10, 11 | 3, 5, 6, 9, 10, 11 | - |
LEDピンNo | 13 | 13 | 13 | 13 | - |
Analog入力 | 8本 | 6本 | 6本 | 8本 | - |
Analog出力 | - | - | - | - | - |
動作電圧 | 5V | 3.3V or 5V | 3.3V or 5V | 3.3V | 5V |
電源電圧 | 7-12V (6-20V) | 3.35-12V or 5-12V | 3.35-12V or 5-12V | 3.35-12V | - |
電源 | Mini-B USB or 外部電源 | FTDIケーブル or ブレイクアウトボード | USB or 外部電源 or JSTコネクター | FTDIケーブル or ブレイクアウトボード | USB |
新しくコメントをつける