144Labの入江田です。 Arduinoの開発にはArduinoIDEを使う方法が主流ですが、 今回はまだマイナーな「arduino-cli」を使った開発方法を紹介します。
2020/09/14にarduino-cliのv0.13.0がリリースされました。
初期にあった不具合もほとんど解消され安定してきたのでそろそろ実用フェーズに組み込んでもいいんじゃないかという状況になってきました。
ArduinoIDEのツラミ
GUI操作でボードサポートや依存ライブラリのインストールや更新ができCUIを一切使わずに済むことに関してはよく考えられた環境ではありますが、
- 内包されたエディタがnotepadにほんの少し機能追加したレベル
- 複数ファイルの取り扱いがわかりにくい
- 世の中にはC/C++に関する便利なツールがあるがそのほとんどは使えない
- 今時のIDEのように複数のプロジェクトを横断する機能はない
- 他人の起こした環境と同じ環境を構築するのが手間がかかる(見比べて合わせる必要がある)
- 成果物を保存する機能や保存した成果物を書き込むだけなどが簡単にはできず、開発ではない関係者であっても同じように開発環境を整えてもらう必要がある
手慣れた開発者は新規プロジェクトをArduinoIDEで起こして、慣れたエディタを使ってコードを編集し、IDEにもどってコンパイルやターゲットへの書き込みを行うという操作を行っています。
これはつまり「開発環境の構築」、「コンパイル」、「フラッシュ」さえできればIDEである必要はないということなのです。
そこで「arduino-cli」
Arduino陣営が開発した「arduino-cli」というツールがあります。これはArduinoコア機能を提供するコマンドラインツールです。
ArduinoIDEとarduino-cliは互いにボードサポートやライブラリの保存場所を共有していますので、ArduinoIDEで環境構築しておいてその他の機能はarduino-cliを利用することもできますし、逆もまた可能です。
arduino-cliはArduinoIDEにあるエディタとシリアルモニタ以外の機能は全てあります。
arduino-cliインストール
macOSユーザー
> brew install arduino-cli
Linuxユーザー
> mkdir ~/bin > curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/bin sh
PATH=$HOME/bin:$PATH
をお使いのシェルのprofileファイルに追記してください。(例:~/.bash_profile
など)
Windows10ユーザー
- ダウンロード https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_64bit.zip
- 展開してarduino-cli.exeをパスの通ったフォルダに移動
arduino-cliインストールの確認
> arduino-cli version arduino-cli Version: 0.13.0 Commit: 693a045eea420c29ca7027e668eee31bce37365d
ターゲットサポートの追加
設定ファイルの初期化(すでにある場合は以下を実行しても何もしません)
> arduino-cli config init Config file written to: /Users/USERNAME/Library/Arduino15/arduino-cli.yaml
上記のarduino-cli.yamlに以下のURLを追記(開発に使うボードのガイドに書かれたURLなど)
board_manager: additional_urls: - https://www.adafruit.com/package_adafruit_index.json
インデックスの更新とターゲットサポートの検索
> arduino-cli core update-index Downloading missing tool builtin:ctags@5.8-arduino11... builtin:ctags@5.8-arduino11 downloaded Installing builtin:ctags@5.8-arduino11... builtin:ctags@5.8-arduino11 installed Downloading missing tool builtin:serial-discovery@1.0.0... builtin:serial-discovery@1.0.0 downloaded Installing builtin:serial-discovery@1.0.0... builtin:serial-discovery@1.0.0 installed Updating index: library_index.json downloaded Updating index: package_index.json downloaded Updating index: package_index.json.sig downloaded Updating index: package_adafruit_index.json downloaded Updating index: package_index.json downloaded Updating index: package_index.json.sig downloaded Updating index: package_adafruit_index.json downloaded > arduino-cli core search nrf52 ID Version Name adafruit:nrf52 0.21.0 Adafruit nRF52 arduino:mbed 1.1.6 Arduino nRF528x Boards (Mbed OS) arduino:nrf52 1.0.2 Arduino nRF52 Boards
ターゲットサポートのインストール
> arduino-cli core install adafruit:nrf52
このインストール状況はArduinoIDEにも反映されるし、 ArduinoIDEの方が探したり入れたりしやすいと思う場合は ArduinoIDEでインストールしてもらっても構いません。
ライブラリのインストール
サーチ
> arduino-cli lib search --names ArduinoJson Name: "ArduinoJson" Name: "CTBot" Name: "Constellation" Name: "DarkSkySevenDay" Name: "Effortless-SPIFFS" Name: "IFTTTMaker" Name: "Kaa IoT Platform" Name: "OpenWeatherOneCall" Name: "cloud4rpi-esp-arduino" Name: "jsonlib" Name: "weatherLocation"
インストール
> arduino-cli lib install ArduinoJson ArduinoJson depends on ArduinoJson@6.16.1 Downloading ArduinoJson@6.16.1... ArduinoJson@6.16.1 downloaded Installing ArduinoJson@6.16.1... Installed ArduinoJson@6.16.1
このインストール状況はArduinoIDEにも反映されるし、 ArduinoIDEの方が探したり入れたりしやすいと思う場合は ArduinoIDEでインストールしてもらっても構いません。
アプリケーション開発
以下のようなフォルダツリーを起こしましょう。
- プロジェクトルート
- APP_NAME/
- APP_NAME.ino
- APP_NAME/
APP_NAMEはドットを含まない任意のアプリケーション名です。 守るべき注意事項として親フォルダ名とメインのAPP_NAME.inoの名前は一致している必要があります。
APP_NAME.ino
void setup() { ... } void loop() { ... }
ターゲットボード名、ポート名の調べ方
ターゲットをUSB接続した状態で以下のコマンドを実行すると 適合するボード名のリストが表示されます。
> arduino-cli board list Port Type Board Name FQBN Core /dev/tty.usbmodem1422401 Serial Port (USB) Nordic nRF52840DK (PCA10056) adafruit:nrf52:pca10056 adafruit:nrf52
または対応可能ボードの全てを表示または検索することもできます。
> $ arduino-cli board listall nrf52 Board Name FQBN Adafruit Bluefruit Metro nRF52840 Express adafruit:nrf52:metro52840 Adafruit Feather nRF52832 adafruit:nrf52:feather52832 Adafruit Feather nRF52840 Express adafruit:nrf52:feather52840 Adafruit ItsyBitsy nRF52840 Express adafruit:nrf52:itsybitsy52840 Nordic nRF52840DK (PCA10056) adafruit:nrf52:pca10056
ピン番号について
ピン番号はターゲットボードサポートライブラリ側とターゲットボードの組み合わせで決まります。異なる組み合わせで利用する場合やCPU互換な別のボードを利用する場合は自前でピン番号割当をする必要があります。
あと、CPUモジュールのスペックシートみると、ピンに名称をつけている場合があったりするので番号との対応は確認する必要があったりします。
一例としてはnRF51/nRF52シリーズでは「P0##」「P1##」というような名称が付与されています。名称と番号の関係は以下の通り。
Pm_nn
に対し 32*m+nn
という計算で番号が決められています。
- P0_00: 0
- P0_01: 1
- P0_31: 31
- P1_00: 32
- P1_01: 33
nRFシリーズは概ねこの形になっていますが、ボードによってはボードのシルクに従う必要があったりしますので、ボードごとのサンプルを参考にしてください。
アプリケーション例
いわゆるLチカです。APP_NAMEを仮に「sample1」とします。 この場合、親フォルダも「sample1」という名前である必要があります。
sample1/sample1.ino
#define LED1 6 // ターゲットによってピン番号は異なります。 void setup() { pinMode(LED1, OUTPUT); } void loop() { Serial.println("loop"); digitalWrite(LED1, 0); delay(500); digitalWrite(LED1, 1); delay(500); }
ビルド
sample1.inoのあるフォルダにて以下のコマンドでビルドできます。
> arduino-cli compile -b adafruit:nrf52:pca10056 . Sketch uses 38404 bytes (4%) of program storage space. Maximum is 815104 bytes. Global variables use 6756 bytes (2%) of dynamic memory, leaving 230812 bytes for local variables. Maximum is 237568 bytes.
この場合、「build/」フォルダが作られ、成果物一式はその配下に出力されます。
- sample1/build/adafruit.nrf52.pca10056/
- sample1.ino.elf
- sample1.ino.map
- sample1.ino.hex
- sample1.ino.zip
elfがバイナリ、mapはマップファイルというデバッグ情報ファイルです。 hexやzipがファーム書きこみ用のファイルです。
書き込み
開発の際はターゲットボードをPCと接続しておき、 以下のコマンドで書き込みを実行します。
> arduino-cli upload -b adafruit:nrf52:pca10056 -p /dev/tty.usbmodem142101 . Upgrading target on /dev/cu.usbmodem142101 with DFU package /Users/nobo/Dropbox/Work/Articles/arduino-cli/sample1/build/adafruit.nrf52.pca10056/sample1.ino.zip. Flow control is disabled, Single bank, Touch disabled ######################################## #################################### Activating new firmware Device programmed.
もし成果物だけを配布してファームウェアを書き換えたい場合は以下のコマンドのように「-i 成果物.ino.zip」で書き換えができます。
> arduino-cli upload -b adafruit:nrf52:pca10056 -p /dev/tty.usbmodem142101 -i build/adafruit.nrf52.pca10056/sample1.ino.zip
デバッグ
Arduino開発のデバッグは主にシリアルモニターによるプリントデバッグを行います。
APP_NAME.inoのsetup関数の冒頭にSerial.begin(115200);
を入れておきましょう。
void setup() { Serial.begin(115200); }
以下のようにしてデバッグプリントをする場合、シリアルモニターには「param: <paramの値>」というようなログが出力されます。
Serial.print("param: ");
Serial.println(param);
シリアルモニタを入手しましょう。以下のどちらかがお勧めです。 (もちろん使い慣れたシリアルターミナルソフトを使っても構いません)
- miniterm.py(All platform)
- Go言語を使った自作コマンド
python3およびpipコマンドが環境に利用可能であれば、「pip3 install pyserial」にて「miniterm.py」というコマンドが利用可能になります。
使い方: ポート名とボーレート指定を引数に指定します。
miniterm.py /dev/tty.usbmodem142101 115200
モニターの止め方は「Ctrl+[」を押します。
Go言語を利用可能な環境であれば「go get github.com/144lab/miniterm」にて「miniterm」というコマンドが利用可能になります。 使い方:ポート名を指定します(ボーレートは115200固定です)
miniterm /dev/tty.usbmodem142101
モニターの止め方は「Ctrl+C」を押します。
まとめ
単一のinoファイルだけでアプリケーションを構築する形を紹介しました。 この形が基本なので、なにか試したいことなどはこの形で試すと間違いにくいのでお勧めです。
GUIスタイルのIDEは模索する動作には向きますが、反復や再現する必要が出た時に効率が落ちます。こう言ったCUIなツールは最初のとっつきは悪いですが、慣れれば慣れるほどに効率が上がっていきますので是非挑戦してみてください。また、エディタはお気に入りのものを使えば良いので開発効率自体も上がるはずです。
arduino-cliはesp8266やesp32の開発も問題なくできるようになりました。 M5Stackシリーズの開発にもどうぞ!