C++ / Arduino CLI / NeoVim でArduinoで遊ぶ環境を整える

Arduino IDEは使わず頑張ってNeoVim/C++で開発する環境を整えました。
2021.04.16

こんにちは、CX事業本部のうらわです。

最近Arduino Unoを購入したのですが、Arduino IDEには一切触れずにC++/NeoVimとコマンドラインでコーディング・コンパイル・アップロードを行う方法を模索しました。

なんとか(個人的に)満足いく環境構築ができたのでご紹介します。

環境

Macで作業します。 NeoVimを使っていますがNeoVimに特化したことはやっていないのでVimでも大丈夫だと思います。

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.7
BuildVersion:   19H15

$ nvim --version
NVIM v0.4.4

Arduino CLIを使う準備

Arduino CLIはまだバージョン1.0.0がリリースされておらずまだまだ開発途中のようですが、コマンドラインからコンパイルやアップロードできるので私が求めている開発環境に合致します。

Homebrewでインストールできるのさっそく使ってみます。

$ brew install arduino-cli
$ arduino-cli version
arduino-cli alpha Version: 0.18.1 Commit: b3cf8e19b801b2855ccd2a18c69c673315839231 Date:

デフォルトでは$HOME/Library/Arduino15内に各種設定ファイルやライブラリ類がインストールされます。私は別のディレクトリに保存したかったため、設定ファイルを新規作成して編集します。

$ mkdir ~/.arduino15
$ arduino-cli config init --dest-dir ~/.arduino15

directoriesの内容を修正しました。

参考: Configuration - Arduino CLI

board_manager:
  additional_urls: []
daemon:
  port: "50051"
directories:
  data: /path/to/.arduino15
  downloads: /path/to/.arduino15/staging
  user: /path/to/.arduino15
library:
  enable_unsafe_install: false
logging:
  file: ""
  format: text
  level: info
metrics:
  addr: :9090
  enabled: true
sketch:
  always_export_binaries: false

この設定ファイルを利用してArduino CLIを実行するには、--config-fileオプションで作成した設定ファイルを指定します。

C++で実装する

以下のコマンドで新しいスケッチを作成します。

$ arduino-cli sketch new MyTestSketch --config-file ./arduino15/arduino-cli.yaml
$ tree
.
├── MyTestSketch
│   └── MyTestSketch.ino
└── arduino15
    ├── arduino-cli.yaml
    └── inventory.yaml

今回はMyTestSketch/MyTestSketch.inoは使わないため、中身を空にしておきます。

MyTestSketch/main.cppを新規作成して実装します。以下はarduino-cliのGetting Startedのサンプルコード#include <Arduino.h>Serial関連を追加しました。

MyTestSketch/main.cpp

#include <Arduino.h>

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.println("Hello!");
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  Serial.println("World!");
  delay(1000);
}

エディタ上のエラーを消す

実装はこれで終了なのですが、このままだと私のNeoVim上ではヘッダーファイルや定義が見つからない、というエラーが出たままです。

これでは快適にコーディングできないため、C++のLanguage Serverであるclangdを導入して補完や定義へ移動等が効くようにします。NeoVimでcoc.nvimを用いてC++の開発環境を整える方法については以下の記事を参考にしてください。

参考: [Neovim/coc.nvim]clangd/clang-formatでC/C++の快適な開発環境を整える

clangdを使う準備ができたら、以下のようなcompile_flags.txtというファイルを作成しMyTestSketchディレクトリ内に配置します。

-I/path/to/.arduino15/packages/arduino/hardware/avr/1.8.3/cores/arduino
-I/path/to/.arduino15/packages/arduino/hardware/avr/1.8.3/variants/standard
-I/path/to/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/avr/include
-I/path/to/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/include
-DUBRRH
  • -Iでインクルードするヘッダーファイルの場所を指定しておくことで、補完や定義へ移動が効きます。
  • -DUBRRHがないとSerialundeclared identifierというエラーが出ました。

後述するArduino CLIのコマンドで必要なライブラリ等をインストールした後に確認すると、NeoVim上でのエラーも消えます。

コンパイル・アップロード

ここからはArduino CLIの公式ドキュメントにしたがって作業します。

ArduinoとPCをUSBケーブルでつなげたあと、以下のコマンドでArduinoが認識されているか確認します。

$ arduino-cli board list --config-file ./arduino15/arduino-cli.yaml
Port                             Type              Board Name  FQBN            Core
/dev/cu.Bluetooth-Incoming-Port  Serial Port       Unknown
/dev/cu.SoundcoreLiberty2-SPPDev Serial Port       Unknown
/dev/cu.usbmodem14201            Serial Port (USB) Arduino Uno arduino:avr:uno arduino:avr

続いて、プラットフォームをインストールします。これをしないとコンパイル時にplatform not installedというエラーになります。

$ arduino-cli core install arduino:avr --config-file ./arduino15/arduino-cli.yaml

ここまでできたらコンパイルします。

$ arduino-cli compile --fqbn arduino:avr:uno MyTestSketch --config-file ./arduino15/arduino-cli.yaml
Sketch uses 1992 bytes (6%) of program storage space. Maximum is 32256 bytes.
Global variables use 202 bytes (9%) of dynamic memory, leaving 1846 bytes for local variables. Maximum is 2048 bytes.

コンパイルが完了したらアップロードします。

$ arduino-cli upload -p /dev/cu.usbmodem14201 --fqbn arduino:avr:uno MyTestSketch --config-file ./arduino15/arduino-cli.yaml

すると、Arduino本体のLと書かれた部分が点減します。また、screenコマンドでシリアル接続すると、以下のように1秒おきに文字が出力されます。

$ screen /dev/cu.usbmodem14201 9600

Hello!
World!
Hello!
World!
Hello!
World!

おわりに

今回は簡単なC++のコードしか試していないため、もっと複雑な実装をし始めたら新たな障壁がでるかもしれません。頑張ってNeoVim/C++/arduino-cliで続けていきたいと思います。

なお、Arduino CLIではなくcmakeを使ってコンパイル・アップロードする方法もあるようです。こちらも試してみたいと思います。

Arduino CMake Toolchain

参考記事

https://qiita.com/filunK/items/49d92b04fca78e4ed5b0