コマンドラインでArduino開発 : vim + platformio

![arduino_platformio.png](https://qiita-image-store.s3.amazonaws.com/0/77816/0d0e330b-8517-c9dc-6339-940e22505bca.png)
## はじめに

[前回](http://qiita.com/caad1229/items/ab41a9a5f5862d0275d0)`ino`を使ったコマンドラインからのビルドとアップロードだったが、今回は`platformio`を使った方法をメモ。

## Platformioについて

`ino`と同じく`platformio`もarduinoの公式ページで[紹介](http://playground.arduino.cc/Learning/CommandLine)されている。現在自分はこちらをメインに使わせてもらっている。

`platformio`がすごいのは、IDEが必要ないということだ。`ino`は別途IDEが必要だったが`platformio`は必要ない。パッケージとして自動でダウンロードしてくれるのだ。さらにすごいのは様々な組み込みボードをサポートしている。
有名どころはばっちり抑えているようで、STM32 Nucleoなど最近のボードもサポートされている。(http://platformio.org/#!/boards)

`ino`同様、`python`で書かれており、大きな依存はないので簡単にインストールできる。IDEの導入がない分`ino`よりも楽だと思う。

- ubuntu 14.04
- Mac OSX Yosemite（10.10.3）

## `platformio`の導入

### udevの設定 (Ubuntuのみ)

※ シリアル機能を使わない場合はこの項目はスキップしてください

`platformio`はシリアルモニター機能もある。しかしubuntuの場合、権限の関係上`udev`ルールにファイルを追加しておく必要がある。(http://docs.platformio.org/en/latest/platforms/atmelavr.html)

> Linux Users: Don’t forget to install “udev” rules file 99-platformio-udev.rules (an instruction is located in the file).

[`udev`ルールファイル](https://github.com/platformio/platformio/blob/develop/scripts/99-platformio-udev.rules)のみでもいいが、いろいろなボードのサンプルプロジェクトもあるので`github`から本体をダウンロードしておく。

```sh
# platformioプロジェクトをDL
$ git clone https://github.com/platformio/platformio.git
```

プロジェクトの中にある`99-platformio-udev.rules`をコピー

```sh
# udevルールファイルを自身のルールフォルダにコピーする
$ sudo cp ./platformio/script/99-platformio-udev.rules /etc/udev/rules.d/
```

### `platformio`のインストール

`virtualenv`の仮想環境下でインストールする。(`virtualenv`環境構築は[こちら](http://qiita.com/caad1229/items/325ca5c8ad198b0ebce7)にメモしてあるので興味があればみてください。)

```sh
# virtualenv作成
$ mkvirtualenv --no-site-package platformio
(platformio)$ pip install platformio
(platformio)$ pip install --egg scons   # makeに変わるビルドツール。これも必要みたい。
```

## ビルドしてアップロードしてみる

### ボード名を調べる

初期化オプションでボードを指定(`--board=<ボード名>`)すると色々設定してくれる。自分のボード名がわからなければ一覧を表示できるし、[サイト](http://docs.platformio.org/en/latest/platforms/atmelavr.html#boards)でも調べることができる。

```sh
(platformio) $ platformio boards
    Platform: atmelavr
    ---------------------------------------------------------------------------
    Type                  MCU            Frequency  Flash   RAM    Name
    ---------------------------------------------------------------------------
    flora8                atmega32u4     8Mhz      28Kb    2Kb    Adafruit Flora
    protrinket3ftdi       atmega328p     16Mhz     28Kb    2Kb    Adafruit Pro Trinket 3V/12MHz (FTDI)
    protrinket3           atmega328p     12Mhz     28Kb    2Kb    Adafruit Pro Trinket 3V/12MHz (USB)
        # 以下省略
```

`grep`して絞ってもいいし、追加オプションでも絞れる。自分は`uno`なのでこちらを検索してみる。

```sh
(platformio) $ platformio boards | grep uno
    uno                   atmega328p     16Mhz     31Kb    2Kb    Arduino Uno
```

別の例として、[nano](http://www.arduino.cc/en/Main/ArduinoBoardNano)。

```sh
(platformio) $ platformio boards | grep nano
    nanoatmega168         atmega168      16Mhz     14Kb    1Kb    Arduino Nano ATmega168
    nanoatmega328         atmega328p     16Mhz     30Kb    2Kb    Arduino Nano ATmega328
```

検索で出てきた`type`項目をボードオプションで指定すればいい。

### プロジェクトを作る : `platformio init`

プロジェクトの作成は簡単だ。`platformio init --board=<ボード名>`で、空のサブフォルダとプロジェクトファイル(`platformio.ini`)が生成される。`platformio.ini`のフォーマットは [INI file](http://en.wikipedia.org/wiki/INI_file)で、様々なオプションがあり細かい設定ができる。(http://docs.platformio.org/en/latest/projectconf.html)


プロジェクト用の空フォルダを作成

```sh
(platformio) $ mkdir uno; cd ./uno
```

arduinoプロジェクトの作成 (今回は一般的なunoボードで生成)

```sh
(platformio) $ platformio init --board=uno
    # 自動アップロードを有効にするかどうかの質問。
    # あとで`platformio.ini`ファイルを編集して変更することもできる
    Would you like to enable firmware auto-uploading when project is successfully built using `platformio run` command?
    Dont forget that you can upload firmware manually using `platformio run --target upload` command. [y/N]: y

    # プロジェクトディレクトリを変更できるよって案内
    The current working directory /home/hoge/uno will be used for the new project.
    You can specify another project directory via
    `platformio init -d %PATH_TO_THE_PROJECT_DIR%` command.

    # コンフィファイルを作る場所は`/home/hoge/uno`だけどいい？って質問。
    # 迷わず`y`
    The next files/directories will be created in /home/hoge/uno
    platformio.ini - Project Configuration File. |-> PLEASE EDIT ME <-|
    src - Put your source code here
    lib - Put here project specific or 3-rd party libraries
    Do you want to continue? [y/N]: y

    # 成功
    Project has been successfully initialized!
    Useful commands:
    `platformio run` - process/build project from the current directory
    `platformio run --target upload` or `platformio run -t upload` - upload firmware to embedded board
    `platformio run --target clean` - clean project (remove compiled files)
```

### シリアルポート名を調べる : `platformio serialports list`

ビルドしたファームウェアはシリアルポート経由でアップロードされる。デフォルトは`/dev/ttyUSB0`となっているためArudinoを接続した場合、ポート名が違うためそのままだとアップデートに失敗する。そこでシリアルポート名を調べて`platformio.ini`に指定しておく必要がある。調べ方はいろいろあるが、`platformio`コマンドを使って調べてみる。

`platformio serialports list`コマンドでシリアル情報の一覧が表示される。`Description`項目からArduinoポートかどうかはわかるはずだ。大抵Ubuntuの場合は`/dev/ttyACM0`、Macの場合は`tty.usbserial-*`。

```sh
(platformio)$ platformio serialports list
    :   # 省略
    /dev/ttyACM0
    ----------
    Hardware ID: USB VID:PID=1a86:7523
    Description: QinHeng Electronics USB2.0-Serial
```

Arduinoのシリアルポート名を`platformio.ini`に追記する。オプション名は[upload_port](http://docs.platformio.org/en/latest/projectconf.html#upload-port)。

```bash
(platformio)$ echo -e "\nupload_port = /dev/ttyACM0" >> platformio.ini
```


### ソース書く

お決まりのLED点滅とシリアル表示。ソースは`./src`に入れる。

```bash

(platformio)$ vim ./src/sketch.ino
    #define LED_PIN 13
    void setup() {
        pinMode(LED_PIN, OUTPUT);
        Serial.begin(9600);
    }
    void loop() {
        Serial.println("Hello Arduino");
        digitalWrite(LED_PIN, HIGH); delay(100);
        digitalWrite(LED_PIN, LOW);  delay(900);
    }

```
### ビルドしてみる : `platformio run`

もしビルドターゲットのプラットフォームパッケージがなければダウンロードをするメッセージが表示されるので`y`を入力して取得する。ダウンロード先は`~/.platformio/packages`。

```bash

(platformio)$ platformio run
    If you like PlatformIO, please:
    - follow us on Twitter to stay up-to-date on the latest project news > https://twitter.com/PlatformIO_Org
    - give us a star on GitHub > https://github.com/platformio/platformio
    Thanks a lot!

    [Wed May  6 13:06:53 2015] Processing autogen_uno (targets: upload, platform: atmelavr, board: uno, framework: arduino)
    ---------------------------------------------------------------------------------------------------------
    The platform 'atmelavr' has not been installed yet. Would you like to install it now? [y/N]: y

    Installing toolchain-atmelavr package:
    Downloading  [####################################]  100%
    Unpacking  [####################################]  100%
    Installing tool-avrdude package:
    Downloading  [####################################]  100%
    Unpacking  [####################################]  100%
    Installing framework-arduinoavr package:
    Downloading  [####################################]  100%
    Unpacking  [####################################]  100%
    Installing tool-micronucleus package:
    Downloading  [####################################]  100%
    Unpacking  [####################################]  100%
    The platform 'atmelavr' has been successfully installed!
```
Downloadが終わるとそのままビルドしてアップロードされる。本体を見るとLEDが点滅しているはず。

```sh
        : # 省略
    Reading | ################################################## | 100% 0.13s

    avrdude: verifying ...
    avrdude: 998 bytes of flash verified

    avrdude: safemode: lfuse reads as 0
    avrdude: safemode: hfuse reads as 0
    avrdude: safemode: efuse reads as 0
    avrdude: safemode: Fuses OK (H:00, E:00, L:00)

    avrdude done.  Thank you.

    =================================== [SUCCESS] Took 64.38 seconds ===================================
```

### シリアルモニターを使ってみる : `platformio serialports monitor`

`platformio`は標準で[シリアルモニター機能](http://docs.platformio.org/en/latest/userguide/cmd_serialports.html)も備えている。別の`minicom`や`picocom`などインストールする必要はないが、ここらへんは好みが分かれるところだと思う。

```sh
(platformio)$ platformio serialports monitor -p /dev/ttyACM0 -b 9600
    # monitor開始
    # 終了するにはCtrl + ]
    --- Miniterm on /dev/ttyACM0: 9600,8,N,1 ---
    --- Quit: Ctrl+]  |  Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
    Hello Arduino
    Hello Arduino
    Hello Arduino
    Hello Arduino
```

## その他の機能

パッケージのアップロード、本体のアップグレードもコマンドから簡単にできる。

- `platformio upgrade` : `platformio`のアップデート

```sh
(platformio)$ platformio upgrade
    You're up-to-date!
    PlatformIO 1.4.0 is currently the newest version available.
```

- `platformio update` : パッケージのアップデート

```sh
(platformio)$ platformio update
    Platform atmelavr
    --------
    Updating toolchain-atmelavr package:
    Versions: Current=2, Latest=2 	 [Up-to-date]
    Updating tool-avrdude package:
    Versions: Current=3, Latest=3 	 [Up-to-date]
    Updating framework-arduinoavr package:
    Versions: Current=16, Latest=16 	 [Up-to-date]
    Updating tool-micronucleus package:
    Versions: Current=1, Latest=1 	 [Up-to-date]
```

その他、外部ライブラリが簡単にインストールできたり様々な機能がある。詳しくは[公式ドキュメント](http://docs.platformio.org/en/latest/index.html)を是非一読してほしい。

## まとめ

すぐに遊ぶための基本コマンドをまとめた。

|command|Description|
|---|---|
|`platformio boards`|ボード一覧表示|
|`platformio init --board=<ボード名>`|プロジェクト作成|
|`platformio run`|ビルド(設定により自動アップロード)|
|`platformio run --target=upload`|ビルドとアップロード|
|`platformio run --target=clean`|クリーン|
|`platformio serialports list`|シリアルポート一覧表示|
|`platformio serialports monitor -p <デバイス> -b <ボーレート>`|シリアルモニタ|

## おしまい

今後は外部ライブラリの取り込みや、他プラットフォームのボードを試してみたい。何にせよ簡単に様々な組み込みボードを一つのコマンドラインで開発できるのは嬉しい限りである。

- [Arduino IDE v1.6.4 (2015/05/07)](http://blog.arduino.cc/2015/05/07/arduino-ide-1-6-4-released/)でコマンドラインからのライブラリーインストールなどサポートしたようだ。それでもコマンドラインからの開発をメインにする場合、`ino`や`platformio`のほうが使いやすいと思う。