Arduinoって anchor.png

Arduino(アルドゥイーノ)は,ATMEL社のAVRチップ(ATmega8, ATmega168, ATmega328Pなど)を搭載した基板と,Arduino言語とそれらを使用して開発するための統合開発環境(IDE)から構成されるシステムのことらしい。

イタリアのIDIIで学んでいたHernando Barragán氏が修士論文のテーマとして,「電子回路のハードウェアを抽象化して,より一般的な人が開発できるようにすること」を研究していた。実際に開発したものが後にArduinoというプラットフォームとなったようだ。当時のハードウェアや開発ツールに比べてできるだけ安価にすることがポイントだったらしい。
Hernando Barragán氏の論文はここで読むことが出来る。

ハードウェアの情報は公開されていて,誰でも機能が同じボードを作成することが出来る。実際にオリジナルボード以外にも,多くのボードが市販されている。

現在では,入門用IoT機器の定番として扱われるようになり,世界的に人気になっているみたい。

最近まで知らなかったんだけど便利らしいんで,試しに自分の作成した基板で試してみた。

Page Top

ハードウェア anchor.png

ハードウェアは,自作したATmega168PA-20AUとFT232BMを実装した基板があるんで,それを試しに使用してみる。ポートの使用方法(LEDはPB0など)が多少違うぐらい。

Arduino IDEからプログラムを書き込む時には,ソフトウェア的にはUART経由で書き込む。自作の基板は,シリアル-USBコンバーターのFTDIのFT232BMを実装しているんで,PCからは仮想COMポートでアクセスする。

Page Top

ソフトウェア anchor.png

Arduinoの統合開発環境はクロスプラットフォームで動作するJavaアプリケーションで,エディタ,コンパイラ,基板へのファームウェア転送機能,さらに各種ライブラリ,サンプルプログラム,Java JREなどを含んだALL IN ONEツール。
下回りには,コンパイラはAVR-GCCで,基板へプログラムを書き込むのには avrdude といったAVR開発時に使われる一般的なツールが使われている。

プログラミングスタイルは,C/C++言語風の構文で,AVRの基板向けに最適化されているみたい。ちなみに,Arduinoではプログラムのことをスケッチと呼んでいる。

Page Top

Arduino IDEのインストール anchor.png

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環境変数を削除した。


*1 現在では,arduino-1.8.19-windows.zipが最新バージョン。

Page Top

いくつかのファイルの変更 anchor.png

自作の基板で使えるように,いくつかのファイルを編集する。

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ディレクトリの中に,filepins_arduino.hを作成する。
これは,ATmega168PのPB6,PB7を使えるようにしたり,LEDの接続位置の違いだったりに対応するため。

hardware\tools\avr\etc\avrdude.confに自作のAVRライター用の定義を追加しておく。バージョン1.8.19なんかの新しいバージョンでは最新版のavrdudeが入っているのでこの作業は必要ない。
1.0.1用:fileavrdude.conf ATmega168P用の定義はすでにあった。ATmega328用の定義を追加しておく。

Page Top

bootloader anchor.png

Arduinoの直接の機能ではないが,Arduino IDEから直接プログラム(スケッチ)を基板のFlash ROMに書き込めるようにするには,Arduino IDEからスケッチをコンパイルしたオブジェクトを基板に書き込む機能を持ったbootloaderを基板に書き込んでおく必要がある。

bootloaderもArduinoのパッケージに含まれているんだけど,ATmega168Pに対応していない事やオンボードLEDのポートが違うなんかがあって,ソースを修正して自分の基板にあうように変更してビルド後書き込だ。fileATmegaBOOT_168P_piramp_8mhz.hexfileATmegaBOOT_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から書き込む必要がある。(この操作が少しめんどくさい。)

Page Top

Arduino IDEでblinkプログラムを試して見る anchor.png

まず,ターゲットのボードをPCのUSBポートに接続する。
Arduino IDEを起動して,「ツール>マイコンボード」からYuji's PIRAMP Board(8MHz)を選択する。
「ツール>シリアルポート」で,ボードのCOMポートを設定する。

「ファイル>スケッチの例>01.Basics>Blink」を開く。
少し以下のように,

int led = 13;
 ↓
int led = 8;

変更する。

ツールアイコンの左から2番めにある→を押す。
これでソースコードがビルドされ,ボードに書き込まれる。(この時,手動のリセットが必要)

プログラムが書き込まれ後,しばらくするとボード上のLEDが1秒毎に点滅した。

Page Top

Arduino IDEはどうか? anchor.png

Arduino IDEは,ソースコードを編集する機能(エディター)とオブジェクトをターゲット基板に書き込むI/Fが主な機能になっている。
また,Arduino言語と呼ばれているdefineで定義したマクロを使用して,多少プログラムが書きやすくなるように工夫をしている。

しかし,使い慣れたエディターとmakeツールでも同様な作業は行えるので,特にArduino IDEを使う必要があるかと言うと,必要はないなってのが感想。

Page Top

Arduino IDE 1.8.5でコンパイルエラー anchor.png

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

に変更。
これで無事コンパイル出来るようになった。

Page Top

Arduino言語について anchor.png

Arduino言語の日本語リファレンスを参照。

  • setup()
    setup()は,ボードの電源を入れたときやリセットしたときに,最初に一度だけ実行される。
    変数やピン端子の設定・初期化や,ライブラリの準備などに使用する。
    setup()は,省略できない。
  • loop()
    loop()は,実行したいプログラムを書いときます。
    loopという名前のとおり,この部分は繰り返し実行される。
    loop()は,省略できない。
Page Top

main()は無いの? anchor.png

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で開発を行う時には,これらをユーザーに負担にならないようにあらかじめ用意してあるわけです。

Page Top

Arduinoボード・スペック anchor.png

Arduino UnoArduino LeonardoArduino DueArduino MEGA 2560Arduino MEGA ADK
特徴人気Arduino UNOの廉価版
USBはCPU内蔵
動作電圧が3.3VATmega2560で,Flash ROM大きいUSBでAndroid端末に接続
価格2520円2100円4980円4910円6420円
CPUATmega328PATmega32u4AT91SAM3X8EATmega2560ATmega2560
Clock16MHz16MHz84MHz16MHz16MHz
Flash ROM32KB
(内0.5KBはbootloader用)
32KB
(内4KBはbootloader用)
512KB256KB
(内8KBはbootloader用)
256KB
(内8KBはbootloader用)
SRAM2KB2.5KB96KB8KB8KB
EEPROM1KB1KB-4KB4KB
デジタルI/Oピン14本
(内6本はPWM出力)
20本
(内7本はPWM出力)
54本
(内12本はPWM出力)
54本
(内15本はPWM出力)
54本
(内15本はPWM出力)
PWMピンNo3, 5, 6, 9, 10, 113, 5, 6, 9, 10, 11, 132〜132〜13,44〜462〜13,44〜46
LEDピンNo1313131313
Analog入力6本12本12本16本16本
Analog出力--2本--
動作電圧5V5V3.3V5V5V
電源電圧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 EthernetArduino MiniLilyPad ArduinoLilyPad Arduino USBArduino Micro
特徴イーサネットポート付
USB-シリアルドライバチップ無し
ブレッドボード用
USB-シリアルドライバチップ無し
ウェアラブルデバイス用
USB-シリアルドライバチップ無し
USB接続Adafruitと共同開発
価格5030円2995円2195円2495円2260円
CPUATmega328ATmega168 or ATmega328ATmega168V or ATmega328VATmega32u4ATmega32u4
Clock16MHz16MHz8MHz8MHz16MHz
Flash ROM32KB
(内0.5KBはbootloader用)
32KB
(内2KBはbootloader用)
16KB
(内2KBはbootloader用)
32KB
(内4KBはbootloader用)
32KB
(内4KBはbootloader用)
SRAM2KB2KB1KB2.5KB2.5KB
EEPROM1KB1KB512B1KB1KB
デジタルI/Oピン14本
(内4本はPWM出力)
14本
(内6本はPWM出力)
14本
(内6本はPWM出力)
9本
(内4本はPWM出力)
10本
(内7本はPWM出力)
PWMピンNo3, 5, 6, 9, 103, 5, 6, 9 10, 113, 5, 6, 9, 10, 113, 9 ,10, 11, 133, 5, 6, 9, 10, 11, 13
LEDピンNo913131313
Analog入力6本8本6本4本12本
Analog出力-----
動作電圧5V5V2.7-5.5V3.3V5V
電源電圧7-12V
(6-20V)
7-9V2.7-5.5V3.8-5V7-12V
(6-20V)
電源Ethernet (PoE) モジュール or FTDI ケーブル/USBシリアルコネクター外部電源(5Vピン or 9Vピン)USB or 外部電源micro USB or 3.7V LiPoバッテリーUSB or 外部電源
 
Arduino NanoArduino Pro MiniArduino ProArduino FioArduino Esplora
特徴Arduino Duemilanoveと同等で小さい
ブレッドボード用
製品組込用
USB-シリアルドライバチップ無し
製品組込用
USB-シリアルドライバチップ無し
ワイヤレスアプリケーション用
SparkFun生産
オンボードセンサー実装
価格4200円1895円1995円2495円-
CPUATmega168 or ATmega328ATmega328PATmega168 or ATmega328ATmega328PATmega32u4
Clock16MHz8MHz8MHz or 16MHz8MHz16MHz
Flash ROM16KB or 32KB
(内4KBはbootloader用)
16KB
(内2KBはbootloader用)
16KB or 32KB
(内2KBはbootloader用)
32KB
(内2KBはbootloader用)
32KB
(内4KBはbootloader用)
SRAM1KB or 2KB1KB1KB or 2KB2KB2.5KB
EEPROM512B or 1 KB512B512B or 1KB1KB1KB
デジタルI/Oピン14本
(内6本はPWM出力)
14本
(内6本はPWM出力)
14本
(内6本はPWM出力)
14本
(内6本はPWM出力)
-
PWMピンNo3, 5, 6, 9, 10, 113, 5, 6, 9, 10, 113, 5, 6, 9, 10, 113, 5, 6, 9, 10, 11-
LEDピンNo13131313-
Analog入力8本6本6本8本-
Analog出力-----
動作電圧5V3.3V or 5V3.3V or 5V3.3V5V
電源電圧7-12V
(6-20V)
3.35-12V or 5-12V3.35-12V or 5-12V3.35-12V-
電源Mini-B USB or 外部電源FTDIケーブル or ブレイクアウトボードUSB or 外部電源 or JSTコネクターFTDIケーブル or ブレイクアウトボードUSB

新しくコメントをつける

題名
ゲスト名
投稿本文
より詳細なコメント入力フォームへ

Front page   Freeze Diff Backup Copy Rename Reload   New Page Page list Search Recent changes   Help   RSS of recent changes (RSS 1.0) RSS of recent changes (RSS 2.0) RSS of recent changes (RSS Atom)
Counter: 615, today: 2, yesterday: 3
Last-modified: 2020-12-26 (Sat) 15:07:42 (JST) (548d) by yuji