Arduinoの開発環境は、一般的にArduino IDEを用います。
このIDEはGUIソフトなのですが、実はArduino CLIというCLIツールも提供されています。
CLI好きにとっては、とても嬉しいツールですね。
問題点
しかし、Arduinoの開発(C++)をNeoVimでする場合、Arduinoライブラリの参照エラーなどが発生してしまいます。
このサイトや、このサイトの通りにやってみたのですが、うまくいかず苦戦しました。
そこで、私がうまくいったやり方を記録しようと思います。
前提
- NeoVim導入済み
- Homebrew導入済み
- coc.nvim導入済み
C++の準備
まずは、C++のコンパイラ等を準備します。
# インストール
$ brew install llvm clangd
# インストール確認
$ clangd --version
Apple clangd version 13.1.6 (clang-1316.0.21.2.5)
Features: mac+xpc
ファイル保存時にオートフォーマットを適用したい場合は、以下を設定します。
(意図しないフォーマットになることがあるので、私は設定していないです)
$ nvim
:CocConfig
# 任意の場所に以下を挿入(カンマ区切りなどに注意する)
"coc.preferences.formatOnSaveFiletypes": [
"cpp"
]
Arduino CLIの準備
Arduino CLIをインストールします。
$ brew install arduino-cli
# インストール確認
$ arduino-cli version
arduino-cli Version: 0.23.0 Commit: 899dc91b Date: 2022-06-06T14:23:44Z
コーディング
Arduino CLIで新規スケッチを作成します。
# スケッチの作成
$ arduino-cli sketch new SampleProject
# 中身の確認
$ tree SampleProject
SampleProject/
└── SampleProject.ino
# c++ファイルで実装したいので、inoファイルは空にしておく
$ cd SampleProject
$ cat /dev/null > SampleProject.ino
次に、C++でArduino本体のLEDを点滅させるプログラムを作成します。
vim main.cpp
で作成。
#include <Arduino.h>
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
現時点では、警告文が大量に出ると思います。
そこで、同一ディレクトリにcompile_flags.txt
というファイルを作成し、必要なライブラリのパスを通してあげます。
-I/Users/ckpc/Library/Arduino15/packages/arduino/hardware/avr/1.8.5/cores/arduino
-I/Users/ckpc/Library/Arduino15/packages/arduino/hardware/avr/1.8.5/variants/standard
-I/Users/ckpc/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/avr/include
-I/Users/ckpc/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/include
-DUBRRH
上記は、私のPCでのパスですので、ご自身のPCでのパスを確認してから記載してください。
(特に、バージョン数などに注意)
しかし、この時点ではまだ警告文が発生すると思います。
後述のArduinoプラットフォームをインストールした後に、警告文が解消されます。
ちなみに、必要なライブラリを探す場合は(仮にServo.h)、ls -R $HOME/Library/Arduino15/packages/ | grep "Servo"
などで検索しています。
ちょっと面倒ですね。何かいい方法あったら教えてください。。
コンパイル・デプロイ
ようやくここで、ArduinoをPCに接続します。
接続後、以下のコマンドで接続確認します。
$ arduino-cli board list
Error initializing instance: Error loading hardware platform: loading platform release esp8266:esp8266@2.7.4: loading boards: skipping loading of boards esp8266:esp8266:espduino: malformed custom board options
Error detecting boards: Error getting board list: [listing ports from discovery builtin:mdns-discovery: command failed: mdns lookup error: write udp6 [::]:59580->[ff02::fb]:5353: sendto: no route to host]
シリアルポート Protocol タイプ Board Name FQBN Core
/dev/cu.BLTH serial Serial Port Unknown
/dev/cu.Bluetooth-Incoming-Port serial Serial Port Unknown
/dev/cu.usbmodem14401 serial Serial Port (USB) Arduino Uno arduino:avr:uno arduino:avr
なんかエラーが発生していますが、とりあえずスルーしておきましょう。
重要なのは、シリアルポートの/dev/cu.usbmodem14401
とFQBNのarduino:avr:uno
とcoreのarduino:avr
を記録することです。
この情報をもとに、必要なモジュールをインストールし、その後コンパイルします。
# モジュールインストール(前述のCoreの項目を指定する)
$ arduino-cli core install arduino:avr
# コンパイル(前述のFQBNの項目を指定する)
$ arduino-cli compile --fqbn arduino:avr:uno .
Error initializing instance: Error loading hardware platform: loading platform release esp8266:esp8266@2.7.4: loading boards: skipping loading of boards esp8266:esp8266:espduino: malformed custom board options
最大32256バイトのフラッシュメモリのうち、スケッチが924バイト(2%)を使っています。
最大2048バイトのRAMのうち、グローバル変数が9バイト(0%)を使っていて、ローカル変数で2039バイト使うことができます。
Used platform Version Path
arduino:avr 1.8.5
ここでも、なんかエラーが出でてますが、コンパイル自体は出来ているみたいなので、スルーします。
では、いよいよ、Arduinoにアップロードします。
# Arduinoにアップロードする(前述のシリアルポートとFQBNの項目を指定する)
$ arduino-cli upload -p /dev/cu.usbmodem14201 --fqbn arduino:avr:uno .
アップロードすると、Arduino本体のLEDがチカチカ点滅すると思います。
(また、main.cpp
ファイルをNeoVimで開いてみると、警告文が解消されていると思います)
もうちょっと便利に
コンパイルやアップロードの度に、長ったらしいコマンドを叩いていては、少々疲れます。
そこで、シェルで少しばかり便利にしていきます。
まず、main.cpp
とcompile_flags.txt
のテンプレートを作っておきます。
# テンプレートディレクトの作成
$ mkdir 00_tmp
# flagsの作成
$ vim 00_tmp/compile_flags.txt
-I/Users/ckpc/Library/Arduino15/packages/arduino/hardware/avr/1.8.5/cores/arduino
-I/Users/ckpc/Library/Arduino15/packages/arduino/hardware/avr/1.8.5/variants/standard
-I/Users/ckpc/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/avr/
-I/Users/ckpc/Library/Arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/incl
-DUBRRH
# main.cppの作成
$ vim 00_tmp/main.cpp
#include <Arduino.h>
void setup() {
}
void loop() {
}
次に、新しいスケッチを作成し、テンプレートで置き換えるシェルを作ります。
(引数で渡した名前で、スケッチを作成します)
$ vim new_sketch.sh
#!/bin/bash
arduino-cli sketch new $1
cp /dev/null $1/$1.ino
cp ./00_tmp/* ./$1
次に、コンパイル〜アップロードまでを行うシェルを作ります。
(引数で渡したスケッチ名をコンパイルし、アップロードまで行います)
$ vim compile_upload.sh
#!/bin/bash
# compile
arduino-cli compile --fqbn arduino:avr:uno $1
# upload
SERIAL=$(arduino-cli board list 2>/dev/null |grep usb |awk '{print $1}')
arduino-cli upload -p ${SERIAL} --fqbn arduino:avr:uno $1
これで、スケッチの作成からコンパイル・アップロードまでをシェルに任せることができます。
(chmod +x
で実行権限を与えるのを忘れずに)
例えば、こんな感じで使います。
# 最初の状態
$ tree .
.
├── 00_tmp
│ ├── compile_flags.txt
│ └── main.cpp
├── compile_upload.sh
└── new_sketch.sh
# 新しいスケッチを作成
$ ./new_sketch.sh 01_hoge
Sketch created in: /path/to/01_hoge
# 内容確認
$ tree .
.
├── 00_tmp
│ ├── compile_flags.txt
│ └── main.cpp
├── 01_hoge
│ ├── 01_hoge.ino
│ ├── compile_flags.txt
│ └── main.cpp
├── compile_upload.sh
└── new_sketch.sh
# main.cppを編集後、コンパイル・アップロードする
$ ./compile_upload.sh 01_hoge
Error initializing instance: Error loading hardware platform: loading platform release esp8266:esp8266@2.7.4: loading boards: skipping loading of boards esp8266:esp8266:espduino: malformed custom board options
最大32256バイトのフラッシュメモリのうち、スケッチが932バイト(2%)を使っています。
最大2048バイトのRAMのうち、グローバル変数が9バイト(0%)を使っていて、ローカル変数で2039バイ
使うことができます。
Used platform Version Path
arduino:avr 1.8.5 /path/to/Library/Arduino15/packages/arduino/hardware/avr/1.8.5
Error initializing instance: Error loading hardware platform: loading platform release esp8266:esp8266@2.7.4: loading boards: skipping loading of boards esp8266:esp8266:espduino: malformed custom board options
こんな感じで、arduino-cliコマンドを毎回叩かなくてもスケッチ〜アップロードまでできるようになりました。
(コンパイルが一発で成功する前提のシェルになってます。気になる方は、コンパイル後の終了コードでもってアップロードを行うかどうかを分岐すると良いと思います)
最後に
やはり、開発ツールを整えることは、開発そのものを楽しくしてくれます。
Vimmerにとっては、Vimで開発ができるというだけで、かなりのモチベーションになりますよね。
よき開発ライフを。
コメントを残す