Arduino を CLI で開発する #PlatformIOが素晴らしい

コマンドラインから Arduino をいじりたい。いくつか試して結局 PlatformIO に落ち着いた。


# インストール (macOS)

Homebrew でインストールしたのは動かなかったので pip でインストールした。

```shell-session
$ ~/Documents/Arduino
$ pyenv install 2.7.15
$ pyenv virtualenv 2.7.15 platformio
$ pyenv local platformio
$ pip install platformio
```

# 使い方

#### ボード定義を調べる

```shell-session
$ platformio boards
(snip)
$ platformio boards esp32

Platform: espressif32
-----------------------------------------------------------------------------------
ID                    MCU            Frequency  Flash   RAM    Name
-----------------------------------------------------------------------------------
featheresp32          ESP32          240MHz    1.25MB  288KB  Adafruit ESP32 Feather
espea32               ESP32          240MHz    1.25MB  288KB  April Brother ESPea32
esp32doit-devkit-v1   ESP32          240MHz    1.25MB  288KB  DOIT ESP32 DEVKIT V1
pocket_32             ESP32          240MHz    1.25MB  288KB  Dongsen Tech Pocket 32
(snip)
```

#### Hello world

```shell-session
$ mkdir test-pfi
$ cd test-pfi
$ platformio init --board esp32doit-devkit-v1
```

プロジェクトのひな形ができるので、src/main.ino にコードを書く。

```cpp:src/main.ino
void setup()
{
	Serial.begin(115200);
	Serial.println("hello platformio!");
}

void loop()
{
	Serial.println("hello");
	delay(1000);
}
```



```shell-session
$ platformio run  # ビルド
$ platformio run -t upload  # 書き込み
$ platformio serialports monitor -b 115200  # シリアルモニタ
```

シリアルポートを指定しなくても動いた。それっぽいデバイスファイルを推測して使っているのかな。
`platformio.ini` に `monitor_speed = 115200` を書いておけば serialports の `-b 115200` が不要になる。

```ini:platformio.ini
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
monitor_speed = 115200
```

#### ライブラリのインストール (platformio.ini)
`platformio.ini` に依存するライブラリを書いておくと `platformio run` でビルドする際に自動でダウンロードしてくれる。

```ini:platformio.ini
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
lib_deps =
  Wire
  Adafruit Unified Sensor@>=1.0.2
  Adafruit AM2320 sensor library@>=1.1.1
monitor_speed = 115200
```

`@` の後ろでバージョンを指定できる。[マニュアル](http://docs.platformio.org/en/latest/userguide/lib/cmd_install.html#cmd-lib-install) から抜粋

- `0.1.2`: バージョンを固定
- `^0.1.2`: メジャーバージョンを固定。`0.x.y` を使う
- `~0.1.2`: メジャー&マイナーバージョンを固定。 `0.1.y` を使う
- `>0.1.2`: 0.1.2 より大きいバージョンを使う。`>=`, `<`, `<=` も同様
- `>0.1.0,!=0.2.0,<0.3.0`:  `0.1.0` より大きく、ただし `0.2.0` ではない、`0.3.0` より小さいバージョンのものを使う

#### ライブラリのインストール (手動)

いちいち ini ファイルに書かなくても、ちょっと試すとかは lib install でインストールできる。

```shell-session
$ platformio lib search AM2320
Found 3 libraries:

(snip)
Adafruit AM2320 sensor library
==============================
#ID: 2456
Arduino library for AM2320 I2C Temp & Humidity Sensors

(snip)

$ platformio lib install 2456  # 番号を指定する
$ platformio lib install 'Adafruit Unified Sensor'  # 名前でも指定できる。依存ライブラリは自力で解決する必要がある
```

main.ino はこうなった。

```cpp:src/main.ino
#include <Adafruit_Sensor.h>
#include <Adafruit_AM2320.h>

Adafruit_AM2320 am2320 = Adafruit_AM2320();

void setup()
{
	Serial.begin(115200);

	am2320.begin();
}

void loop()
{
	delay(2000);
	Serial.print("Temp: ");
	Serial.print(am2320.readTemperature());
	Serial.print("Hum: ");
	Serial.println(am2320.readHumidity());
}
```

```shell-session
$ platformio run
$ platformio run -t upload && platformio serialports monitor

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11584
entry 0x40078a60
Temp: 27.30Hum: 41.50
Temp: 27.90Hum: 41.50
Temp: 27.80Hum: 41.50
...
```


~~`#include <Arduino.h>` が必要で Arduino IDE のプロジェクトをそのままビルドするとかはできないけど~~ ファイル名を `.ino` にすればそのままでよかった。

シリアルポートも勝手に推測して設定してくれるし、Arduino IDE みたく別途 ESP32 用の定義ファイルを追加するとかも必要ない。素晴らしい。


# 試したけどダメだったツール

手元の環境は macOS 10.13 + Arduino IDE 1.8.4

#### ino

動かなかった。
開発も止まっているようで、

#### Arduino-Makefile

Arduino UNO だとさくっと動くっぽい。ただ、ESP32 だとビルドが通らない。パスを指定したり何やかんやと準備が必要っぽい。面倒くさくなってやめた。

#### arduino(1)

Arduino 公式のコマンドラインツール。[マニュアル](https://github.com/arduino/Arduino/blob/master/build/shared/manpage.adoc)
macOS の場合 `/Applications/Arduino.app/Contents/MacOS/Arduino` がそれになる。

コマンド実行毎に Arduino IDE 起動相当の処理をするようで、とても時間がかかる。ちょっと無いなーと。


## 余談

macOS デフォルトの make(1) が GNU Make になってて驚いた。

```
% which make
/usr/bin/make
% make -v
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-apple-darwin11.3.0
```