MicroPython で NeoPixel をピカらせる

# プロローグ

この記事は [IoTLT Advent Calendar 2017](https://qiita.com/advent-calendar/2017/iotlt) の12月16日の記事です（JSTで間に合いませんでしたが、UTCでなんとか間に合っているはず・・・）。

さて、私は広島で「IoTLT広島」というのを開催させていただいております。2〜3ヶ月に1回程度の割合で2016年6月にスタートして、2017年12月9日に [Vol.7](https://iotlt.connpass.com/event/71795/) を開催することができました。そんな、 IoTLT広島Vol.7 ですが、下記のまとめにあるように、なんとあの本家 IoTLT でも有名な[ギャル電さん](https://twitter.com/galden999)が登場！！当然のごとく、会場は LED 全開でマジ卍な開催となりました。

-> [まとめはこちら](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwijjoy3xY_YAhUBw5QKHe5OCtMQFggoMAA&url=https%3A%2F%2Ftogetter.com%2Fli%2F1179848%3Fpage%3D3&usg=AOvVaw3vr2LFLMpfmLN_ZvR5XW3V)

そう、ギャル電さんといえば、LED ！！！その夜に行われた GEEKNIGHT広島 も合わせて、当日は広島エンジニア界隈でもっとも LED が光った日になりました。

# 本題

ということで、私もそんな影響を受けて早速 LED テープを購入して使ってみましたのでその報告をさせていただきます。

# 用意するもの

- NeoPixel MiniテープLED 1m/60LED
- ESP-WROOM-02

今回、とりあえず手元にあったESP-WROOM-02を使うことにしました。

# 方針

Arduino IDE での作成事例は日本語の記事が非常にたくさん溢れていたので、今回は [MicroPython](http://docs.micropython.org/en/latest/esp8266/index.html) でやってみようと思います。

# MicroPython のセットアップ

まず、ESP-WROOM-02 に MicroPython をセットアップする必要があります。

*その前に、お手元の端末で python3 と pip3 が動くようにしておく必要がありますが、Python3 のセットアップはこの記事では省略します。*

### esptool.py のインストール

``` command
> pip3 install esptool
```

pip3 install の最後で /bin に書き込めないというエラーになる人は、下記のようなオプションをつけてみてください。

``` command
> pip3 install --install-option="--prefix=/usr/local" esptool
```

### ESP-WROOM-02 の接続

USB で ESP-WROOM-02 を接続して、ポートを確認します。ポートは Mac の場合下記のような感じです。

``` command
> ls /dev/tty.usb*
/dev/tty.usbserial-xxxxxx
```

以下、この記事ではポートを「/dev/tty.usbserial-xxxxxx」として進めていきますので適宜ご自分の環境に置き換えてください。Windowsの場合は「COM3」とかそういう感じです。

### esptool.py の動作確認
```
> esptool.py --port=/dev/tty.usbserial-xxxxxx --baud 115200 flash_id
```

正常にセットアップできてれば下記のような表示がされるはずです。

```
esptool.py v2.2
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Uploading stub...
Running stub...
Stub running...
Manufacturer: a1
Device: 4016
Detected flash size: 4MB
Hard resetting...
```

### ファームウェアのダウンロード

ファームウェアを MicroPython のページからダウンロードします。一番上の Latest で特に問題はないと思います。

http://micropython.org/download#esp8266

``` command
> wget http://micropython.org/resources/firmware/esp8266-20171101-v1.9.3.bin
```


### ファームウェアの書き込み

``` command
> esptool.py --port=/dev/tty.usbserial-xxxxxx erase_flash
esptool.py v2.2
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 21.7s
Hard resetting...
```

``` command
> esptool.py --port=/dev/tty.usbserial-xxxxxx --baud 115200 write_flash --flash_size=4MB 0 esp8266-20171101-v1.9.3.bin
esptool.py v2.2
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash params set to 0x0040
Compressed 600888 bytes to 392073...
Wrote 600888 bytes (392073 compressed) at 0x00000000 in 34.9 seconds (effective 137.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting...
```

### REPLの動作確認
上記まで成功すると、REPL という Python のインタプリタのようなものが動くようになります。Mac の場合の確認方法は以下の通りです。

``` command
> sudo cu -s 115200 -l /dev/tty.usbserial-xxxxxx
Connected.
>>>
```
Connected. と表示された後、>>> が表示されます。反応がない感じであれば、Return か Ctrl+C を入力してください。>>> の後ろに入力した、適当なPythonの処理命令が動くようになります。

``` command
>>> print('IoT!!!!!!')
IoT!!!!!!
```

cu を終了する場合は ~. （チルダ + ピリオド) を入力します。Disconnected. と表示されます。

``` command 
>>> ~.

Disconnected.
```

# Python によるプログラム作成

さて、ここまでくればほぼ完了です。Python のプログラムを1つ作成します。と言っても、GitHubで拾ったサンプルを貼り付けただけです。

https://github.com/lvidarte/esp8266/blob/master/examples/neopixels/src/python/main.py


``` main.py
from machine import Pin
from neopixel import NeoPixel
import time


def demo(pin, n):
    np = NeoPixel(Pin(pin), n)

    # cycle
    for i in range(4 * n):
        for j in range(n):
            np[j] = (0, 0, 0)
        np[i % n] = (255, 255, 255)
        np.write()
        time.sleep_ms(25)

    # bounce
    for i in range(4 * n):
        for j in range(n):
            np[j] = (0, 0, 128)
        if (i // n) % 2 == 0:
            np[i % n] = (0, 0, 0)
        else:
            np[n - 1 - (i % n)] = (0, 0, 0)
        np.write()
        time.sleep_ms(60)

    # fade in/out
    for i in range(0, 4 * 256, 8):
        for j in range(n):
            if (i // 256) % 2 == 0:
                val = i & 0xff
            else:
                val = 255 - (i & 0xff)
            np[j] = (val, 0, 0)
        np.write()

    # clear
    for i in range(n):
        np[i] = (0, 0, 0)
    np.write()
```

# ampy のセットアップ

Python から ESP-WROOM-02 へのファイル転送をやりやすくするために　ampy というツールをセットアップしておきます。

``` command
pip3 install adafruit-ampy
```

# ファイルの書き込み

``` command
ampy -p /dev/tty.usbserial-xxxxxx put main.py
```

# NeoPixel LEDテープの接続

5V、GND、4番ピンを使います。
![g1.png](https://qiita-image-store.s3.amazonaws.com/0/125488/5e52c89f-f855-a43d-61f2-54d8e4d37663.png)



# 実行確認
REPL に接続して下記を実行すると、LEDがゴージャスに光るはずです！

``` command
>>> demo(4,8)
```

4 はコントロールの線を接続したピン番号、8 は光らせるLEDの個数です。

PCから外しても自動的に光るようにするには main.py の一番後ろに　demo(4,8) を記載します。

``` main.py
    # clear
    for i in range(n):
        np[i] = (0, 0, 0)
    np.write()

demo(4,8)
```

# Let's 電飾
これであなたもLEDクイーン！服に取り付けたりして街に出かけましょう！
![g2.png](https://qiita-image-store.s3.amazonaws.com/0/125488/f3eb3f75-d73e-568e-0cd1-e5df89b90adf.png)


# MicroPython の利点

さて、MicroPython ですが、一番の利点は Python のコードがかけること。特に HTTP 周りの処理や、APIのリクエストを使うなら、Arduino IDE を使うより圧倒的に楽です。例えば、Firebase につなぐ例は下記の通り。

やー、Python って素晴らしいですね！

``` firebase.py
        res = http_request(
            'https://your-firebase-project.firebaseio.com/your-database-name/your-key-name.json',
            'POST',
            data,
            'application/json')

```

# IoTLT Advent Calendar 2017
次の記事は @gishi_yama さんです！