SPRESENSE で Firmata を動かす
はじめに
SPRESENSE のメインボードと拡張ボードを購入したので、
SPRESENSE に Firmata ライブラリを移植してみます。
SPRESENSE ボードは、Arduino 互換なのであっさり移植できるはず。
なんといっても拡張ボードは Arduino UNO と同じ形状です、動かないはずがない。
Firmata とは?
ホストPCと通信するためのプロトコルを定義したライブラリです。
Firmata の詳しい説明は、正式な呼び名さえ知らないので...、他に譲りますが、ホストPC側のツールは、Processing をはじめとして、Python, Perl, Ruby, Java, Go, Rust, ... と一通り揃っています。(ファーマタなのか...ファルマータなのか...)
SPRESENSE 上で Firmata スケッチを一回焼いておくだけで、あとはホストPC側から SPRESENSE のポート制御を行うことができるようになります。SPRESENSE のピン仕様を調べるのと、これを使ってゆくゆくはスクラッチ「Scratch」等のビジュアルプログラミング言語からSpresenseを制御できるようにする予定(野望)です。
SPRESENSEボード開発環境構築
開発環境のセットアップ手順は Spresense Arduino スタートガイド に詳しく載ってます。(手抜き詳細は割愛)
Arduinoを使ったことがある人なら、
- ボードマネージャのURLにpackage_spresense_index.json を追加して
- ボードマネージャからインストールするだけ、です
Firmata 移植
移植した Firmata ライブラリを GitHub にアップしました。
https://github.com/baggio63446333/Firmata
移植といっても Board.h に SPRESENSE 用の定義を追加しただけです。
あまりにもアッサリしすぎたので勢いあまって本家にプルリク出してみました。
(2019/10/21追記) 本家(https://github.com/firmata/arduino) にもマージされました。
いずれ Arduino IDE をインストールするだけで Firmata on SPRESENSE が使えるようになります。
// SPRESENSE
#elif defined(ARDUINO_ARCH_SPRESENSE)
#define TOTAL_ANALOG_PINS NUM_ANALOG_INPUTS
#define TOTAL_PINS NUM_DIGITAL_PINS + 4 + NUM_ANALOG_INPUTS // + 4 built-in led
#define VERSION_BLINK_PIN LED_BUILTIN
#define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < (NUM_DIGITAL_PINS + 4))
#define IS_PIN_ANALOG(p) ((p) >= (TOTAL_PINS - NUM_ANALOG_INPUTS) && (p) < TOTAL_PINS)
#define IS_PIN_PWM(p) ((p) == 6 || (p) == 5 || (p) == 9 || (p) == 3)
#define IS_PIN_SERVO(p) ((p) < NUM_DIGITAL_PINS)
#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
#define IS_PIN_SPI(p) ((p) == 10 || (p) == 11 || (p) == 12 || (p) == 13)
#define PIN_TO_DIGITAL(p) (((p) < NUM_DIGITAL_PINS) ? (p) : (_LED_PIN((p) - NUM_DIGITAL_PINS)))
#define PIN_TO_ANALOG(p) ((p) - (TOTAL_PINS - NUM_ANALOG_INPUTS))
#define PIN_TO_PWM(p) (p)
#define PIN_TO_SERVO(p) (p)
#define analogRead(p) analogRead(_ANALOG_PIN(p)) // wrap function for analogRead()
これから SPRESENSE を使うにあたって何度も参照することになると思うので、
ここに SPRESENSE ボードのピン定義をまとめておきます(適宜、加筆予定)。
-
ピン番号を調べるときのコネクタ図はこちら
-
拡張ボード
- デジタル:PIN_D00 ~ PIN_D15
- デジタルI/O電圧: 3.3V or 5V (ジャンパ切り替え)
- レベルシフタを通してデフォルトでプルアップされている
- アナログ:A0 ~ A5
- アナログ入力範囲:0 ~ 5V
-
メインボード
- デジタル:PIN_D14 ~ PIN_D28
- デジタルI/O電圧:1.8V
- アナログ:A2 ~ A3
- アナログ入力範囲:0 ~ 0.7V
-
ソースコード上のピン定義はこちら
-
デジタルピン
- コネクタに出ているのは 29 本ですが、NUM_DIGITAL_PINS はトータル 45 本も定義されています
- 拡張ボードを自作する人向けですかね
-
アナログ入力ピン
- NUM_ANALOG_INPUTS はアナログ専用ピンで計 6 本あります
- analogRead() 関数の引数は単純な数字ではなく A0, A1, A2, A3, A4, A5 という名前を使います
- A0, A1, A2, A3 の 4 本は低速ADC、A4, A5 の 2 本は高速ADC、と二種類に分かれている
-
LED
- メインボードに LED が 4つもついてます
- これは助かる~。さすが分かってらっしゃる>SONYさん
- せっかくなので Firmata 経由でも LED を触れるようにしておきました
Firmata 動作
Target (SPRESENSEボード) 側
-
Arduino IDE の Library Manager を使って Firmata をダウンロード
-
StandardFirmata
サンプルスケッチを実行してボードに焼く
Arduino 初心者でここの手順が分からないというコメントがあればもっとちゃんと書きます ^^;
ホストPC 側
前述したようにホストPC側のツールはいろいろありますが、ここでは Firmata Test ツール を使います。
▼ここから各プラットフォーム用のツールがダウンロードできます。
https://github.com/firmata/firmata_test/downloads
http://firmata.org/wiki/Main_Page
-
Windows 版バイナリをダウンロードして firmata_test.exe を実行します
-
Pin 番号が次のように並んでいます。
00 ~ 44 : Digital
45 ~ 48 : LED
49 ~ 54 : Analog
例えば、Pin45 ~ 48 にOutput
を選択したまま、High
/Low
を切り替えると L チカします。
どこかの Pin をInput
に切り替えて、電源 / GND につなぐとステータスがHigh
/Low
に切り替わります。
Anglog ピンは周期的に読み出しを行った値がリアルタイムに表示されます。
さいごに
Firmata を使ってホストPCから SPRESENSE ボードを制御する環境が整いました。
SPRESENSE の Arduino 互換は本当でした。