Arduino とは何か

今まで何度も取り上げていて、いまさら何かと切り出すのもなんだが、一度整理しておく。
はじめてArduinoのをみたのはおそらく2010年の年末だ、なんと近所のRadio Shackで入門本と一緒に売っていた。 (RadioShackが昔のように、電子工作の小物を置くようになったというのは非常にうれしいことである。最近はRaspberry PiとかBeaglebone Blackの入門キットも売っている。 閑話休題)
BasicStampに比べると値段が手ごろだったので購入したのだが、このときの解釈は Arduino = 開発ボード

しかし、入門本を読み、LEDの点灯を試み、サーボモーターやリレーの操作、さらには16×2ケタのLCDを表示するという一応のイニシエーションを行ったあと、改めて眺めてみれば、Arduino というのは開発ボード(だけ)ではなかった。

ボードを購入したあと、ユーザーはArduinoのサイトから開発環境をダウンロードしてプログラミングすることになる。 このときSketchという言語でプログラムを書くのだが、これはWiringという言語がもとになっている。 そしてWiringもSketchも基本的にはC言語を使ったFrameWorkだ。

IDEのGUIはJavaでできているものの、そのバックグランドで動いているものはAVRマイコン用に特化したGCC(AVR-GCC)であり、AVRDUDE(AVR Downloader/UploaDEr) という、マイコンプログラムの先人達によって鍛えられたAVRマイコン用のTool chainである。

ではArduino環境は従来のマイコン開発環境と比べると何が違うのか。
-ハードもソフトもできる限りのアブストラクト化がなされている。
という一点につきる。 AVR8はportB,C,D それぞれ8ビットが入出力になっており、本来のATMEL のC言語の操作ではこれらのポートレジスターにビット操作での書き込みをおこなっていた、つまりPortBの ビット0とか6とかを気にしてコーディングしていくのだが、 アブストラクション(抽象化)を行った結果、 ArduinoのユーザーはDigital pin 0~13, Analog input pin 0~5 という入出力ピンの操作だけを考えればよいようになっている。
スケッチもSetup()という初期化ルーチンとloop()という繰り返しルーチンを書けば、あとはTool chainがコンパイルし、プログラムをアップロードしてくれる。 このからくりはArduino のプログラムフォルダー(自分のWindows環境ではC:\Program Files (x86)\Arduino\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;
}

何故にwhileを使わず、for(;;) という構文を使っているのか、という疑問はさておき、Arduino のスケッチはこの上のmain.cppに組み込まれるsetup()とloop()関数を定義しているというわけで実際にコンパイルされるのはC++のソースだった。

Arduinoでは多くの周辺デバイスとのインターフェース、通信プロトコルなどはすでにライブラリーで提供されている。 またArduino自体にマイコンチップをプログラムできるような周辺回路およびブートローダーが組み込んてあるからチップにコードを焼くための専用プログラマが必要ない。

下のコードは、入門本で一番最初に出てくるLEDを点滅させるためのスケッチコード

int led = 13;
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

ところがArduinoのIDEがインストールされたPC環境ではすでに上に述べたようにGCCとかtoolchainとかが導入済みになっているため、 以下のようなプログラムををCで書いて、コマンドラインを使ってコンパイルし、Arduinoへ書き込みをすることが可能になっている。 下のコードでやっているのは上 のスケッチと同じくPin 13を点滅させることだが、ArduinoスケッチのProgramがコンパイルしてアップロードするサイズが1000バイト以上あるのに対し、下のプログラムは200バイト以下になる。abstractionの代償はプログラムのサイズということらしい。


#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>

#define LED      PB5
#define LED_DDR  DDRB
#define LED_PORT PORTB
#define DELAYTIME 500 //delay 500ms. See _delay_ms definition

#define setBit(sfr, bit)     (_SFR_BYTE(sfr) |= (1 << bit))
#define clearBit(sfr, bit)   (_SFR_BYTE(sfr) &= ~(1 << bit))
#define toggleBit(sfr, bit)  (_SFR_BYTE(sfr) ^= (1 << bit))
long i;
int main(void)
{
    // setup()
    setBit(LED_DDR, LED);                      /* set LED pin for output */

    // loop()
    while (1) {

	    setBit(LED_PORT, LED);
	    _delay_ms(DELAYTIME);
	    clearBit(LED_PORT, LED);
		_delay_ms(DELAYTIME);
	    
    }
}

while分がArduinoスケッチのloop()に相当し、その上がsetup()に相当する。
上をblink.c というファイル名で保存し、Arduinoがつながった状態でコマンドラインから以下を実行するとLEDの点滅を始める。(もちろんserial portによってCom5部分は異なる)

>avr-gcc -Os -mmcu=atmega328p blink.c -o blink.o
>avr-objcopy -O ihex blink.o blink.hex
>avrdude -p atmega328p -c arduino -P com5 -U flash:w:blink.hex:i

コマンドライン3行をターミナルモードで打ち込むわけだが、Batch file にしてもよい。その実行はarduinoのアップロード機能を使うのに比べて恐ろしく早い、ということも実感できると思う。
Arduinoを使うのは野球のグローブをつけて裁縫をやるようなものだ、とかなんとか言った人がいる。 抽象化が過ぎてマイコンをプログラムしている気がしない、ということで、たしかに熟練者の目からみればもっともな話かもしれないが、Arduinoの一番の目的はマイコン学習を始めるための第一歩を容易にすることにある。(と思う) 豊富なサンプルコードやライブラリーを見るとその楽ちんさは尋常ではない。ハードとソフトの両方への入門が可能な環境になっている。 ずうっとArduinoとスケッチでいいじゃない、十分だよ、という気にもなってくる。 それにArduino IDEのサンプルメニューを眺めているとわかるが、Arduino自体をAVRマイコンのプログラマにしてしまうスケッチがご丁寧に同梱されている。 Arduinoにものたりなくなってきたら、(入出力が6本以下のマイコンでできることを、何が悲しゅうて28ピンのマイコンプラス不要な回路を載せたボードでやってまんねん、自分はミニマリスト的なアプローチがすきやねんとか思いはじめたら)ATtinyのチップだけ100円で購入してArduinoを使ってプログラムを焼くことも可能になっているわけだ。

PICAXE -Basicで動かすマイクロコントローラ

20年以上前になるがBasicStampというベーシックで動かせるマイクロコントローラーが世の中に出てきた。(今でも健在) それなりに興味があったわけだけれど、始めるのに100ドルくらいはかかりそうだったので、それがバリアになり、手を出さずにいた。 PICマイコンというのが世の中に出回り始め, Basic StampというのはこのPICをベースにしたBasic 内蔵のボードだったわけで、 面白そうだったけれど開発環境を作るのが面倒くさそうで手を出さずにいた。
そのうちAVRマイコンを使ったArduinoが開発され、これは30ドルのボードを買ってきて手持ちのパソコンにつなげればすぐに開発が始められるという手軽さ。 多くの電子工作入門者、あるいはメーカーと呼ばれる人々はArduinoでこの世界に足を踏み入れた、というのが現在の状況だと思う。
今回、ひょんなことからPICAXEというチップの存在を知った。PICベースでBASICを内蔵させた開発環境だという。一番小さな8ピンのPIXACE08M2というのがsparkfunで購入して一個$2.95.プログラミングに必要な3.5ミリのステレオジャックを含んだプロトキットが4ドル。 一番高いのがパソコンに接続するためのUSB/シリアルの変換ケーブルで、これが25ドルしているのだが、Sparkfunのオリジナルで15ドルのUSB Programmer が代用できる(ただし、別途ステレオプラグケーブルが必要) というわけで入門価格として
PICAXE 08M2 X 2 = $5.90
PROTOKIT X 1 = $3.95
PROGRAMMER X 1 =$14.95
ステレオプラグケーブル:手持ち品を流用
USB – MINI USB CABLE 手持ち品を流用
5v 電源 手持ち品を流用
送料 $6.00
合計$30.80 となり、 価格バリアもクリア  したので購入し、試してみた。

開発環境はPICAXE のホームサイトからダウンロードできる。 オリジナルのpicaxeは4mHZで動いていたようだが、最新のM2シリーズは32MHzと高速になっている ただし、普通に動かすとBasicは4Mhzで動作し、疑似的に4本までの並列処理が可能になる。

8ピンのチップと言っても電源とグランド以外のピンは6本とも入出力ピンに使えるし、PWM出力やアナログ入力もこなせる。なかなか使い勝手のよさそうなチップである。 ピンの出力も20mAまでOKなのでArduinoと同等だ。

LEDを点滅させるプログラムは以下のようになる。

main:
high c.1
pause 500
low c.1
pause 500
goto main

昔なつかしのBASIC言語である。 いまとなってはGoto文が新鮮に見える。 プログラム用のメモリーは2048byteあるが、Tokenizeされてチップ上にアップロードされる上のコードは14バイトにおさまる。

これで出力ピンにLEDと抵抗を直列に接続すれば、1秒ごとに点滅するLED回路となるわけだが、 32Mhzで動かした場合、どれくらいの速さで出力ピンを操作できるのか試してみた。 最初のコマンドでBasic を8倍速させている。

setfreq m32
main:
high c.1
low c.1
goto main

これでC.1のピン波形をとらえたのが以下

Manupulate picaxe pin

PICAXEピン出力

 

Hi出力の幅が36マイクロ秒に対し、Lo出力の幅は126マイクロ秒, 周波数6.156Kということになる。Hi,の出力にくらべてLowの出力が長いのは、gotoコマンドの実行に時間がかかっている、ということだろうが、 32Mhzのマシンサイクルに対して出力できたのが6Khz。 Basic Interpreterで動作させることのオーバーヘッドがいかに大きいかがわかる。 ちなみにPICAXEのサイトでは1秒間に実行できるBASIC命令文は約4000と説明されている。

実際にいたずらするには問題のない実行時間だと思う。 さらに、もっと細かいパルスを出力するためのServo や 内蔵PWM出力用のコマンド、あるいは可聴域信号を発生するためのtune コマンドなどが別に用意されているから、パワフルなマイコンであることに変わりはないが


Pause 1

できっちり1ミリ秒遅らせられるわけではない、ということがわかる。

それにしても、何度もいうけど電子工作するのに本当に便利な世の中になったもんだ。