Spresense SDK用にAdafruit NeoPixelライブラリを作成する

数年前に少し触っただけで放置していたSony SpresenseとNeoPixel。
久々に動かそうと思い立ち、Spresense SDKでNeoPixelを動かせないかと試してみました。

## Spresense SDKにはNeoPixelライブラリが無い
Arduino IDEを使う場合にはライブラリがあるんですけどねぇ。
私も購入した当初に以下のライブラリを使って光るだけ光らせて満足してました。

https://github.com/hideakitai/SpresenseNeoPixel

つい最近には以下のライブラリも公開されていました。
(Adafruit公式のAPIをOverrideしたような感じ？)

https://github.com/KotaMeiwa/nepils

NeoPixelを使うには基本的にこれらのライブラリを使うのが一番手っ取り早いんですが…
色々少し込み入ったことをしたいなぁと思うと、Arduino IDE環境だと個人的に少々やりづらく感じたというのと、まぁ勉強にもなるだろうと考えたのが今回の経緯です。

## Spresense SDK用のNeoPixelライブラリを作成してみる
[こちらの記事](https://qiita.com/ixy-shino/items/9c778243365cad50a443)を読むにSpresense/externalsに外部ライブラリとして置けるらしいので、せっかくだし今後使用するためにもライブラリっぽい感じに作ってみようと思います。
・
・
・
### そんなこんなで出来たのがこちら

https://github.com/whyes-develop/neopixel-for-spresense

基本的に上述のライブラリと[SpresenseのArduino互換ライブラリ](https://github.com/sonydevworld/spresense-arduino-compatible)を見てSpresense SDKに展開しただけなので、実装に関する詳しい解説は特にないです。

というよりろくに解説ができないから一旦スキップです…
先人様様です本当に…勉強します…ﾊｲ…
### 導入方法

Spresense SDKの環境構築とかは[公式ドキュメント](https://developer.sony.com/develop/spresense/docs/sdk_set_up_ide_ja.html)にお任せして飛ばします。

1. spresense/externals ディレクトリ上でNeoPixelライブラリをClone
  `git clone https://github.com/whyes-develop/neopixel-for-spresense.git`
2. spresense/sdk ディレクトリ上で以下のコマンドを実行し、NeoPixelライブラリを有効化
  `tools/mkdefconfig.py -d ../externals/neopixel-for-spresense neopixel`
  ※ もしくは `tools/config.py -m` で表示されるmenu config上で
     `Application Configuration->Spresense SDK->Externals->Adafruit Neopixel library`にチェックを入れる

### 使い方
#### サンプルコード
とりあえず5秒間白色点灯するだけのサンプルコードがこちら。
```c
#include <nuttx/config.h>

#include <arch/chip/pin.h>
#include <stdio.h>

#include "neopixel.h"

int main(int argc, FAR char *argv[])
{
#define N_PIXELS (12)

  neopixel_client_t *client = NULL;
  neopixel_color_t   color = {255, 255, 255};

  client = neopixel_inizialize(PIN_PWM0, N_PIXELS);

  neopixel_setall(client, &color);

  neopixel_show(client);

  sleep(5);

  neopixel_clear(client);
  neopixel_show(client);

  neopixel_finalize(client);

  return 0;
}
```
① `neopixel.h`をincludeします。
```c
#include "neopixel.h"
```
② neopixel_client_t の構造体ポインタ変数clientを用意します
```c
  neopixel_client_t *client = NULL;
```
➂ `neopixel_inizialize()`を実行してclientを初期化します
引数は順に GPIO PIN番号、NeoPixelのピクセル数です。
```c
#define N_PIXELS (12)
  client = neopixel_inizialize(PIN_PWM0, N_PIXELS);
```
④ `neopixel_setall()`を実行して全セルの色を設定します
今回は全てのセルに対して白色を設定しています。
```c
  neopixel_color_t   color = {255, 255, 255};
  neopixel_show(client);
```
　セルごとに色を設定したい場合はセル番号を指定できる`neopixel_set()`を使用します。
```c
int neopixel_set(neopixel_client_t *client,
                 uint32_t n,
                 neopixel_color_t *color);
```
⑤ `neopixel_show()`を実行してLEDを点灯します
```c
  neopixel_show(client);
```
⑥ `neopixel_clear()`を実行してセルに設定した色を初期化します
```c
  neopixel_clear(client);
```
⑦ 最後は`neopixel_finalize()`を実行してclientを解放します
```c
  neopixel_finalize(client);
```
#### 動かしてみる
上記のサンプルコードを実際に動かしてみます。
今回の試験環境はこちら。
![DSC_0267.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229241/ce884887-3bec-fbe3-24fb-d5109af9516c.jpeg)
- Spresenseメインボード
- Spresnese LTE拡張ボード(なんかあったからこれ使っただけ)
- NeoPixel Ring - 12連フルカラーシリアルLED

ジャンパーピンを無理やり捻じ曲げて接続した雑配線には目を瞑っていただいて…早速動かしていきます。

ビルドして、
![build.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229241/52efb472-70a5-df61-691a-5b48d672379a.jpeg)
実機に焼き、
![burn.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229241/118174ec-4d35-5219-e5a7-5902b20f7b49.jpeg)

コマンドを実行する…
![simple_light_exec.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229241/8102cb42-b637-dcb4-e90d-e31de1b38e64.jpeg)

動きました。 ｲｪｰｲ
![DSC_0270.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1229241/d9910102-86ad-8042-731d-aac3ffae264c.jpeg)

#### サンプル集
上記で動かしたサンプル (simple_light) も以下で公開しています(他のサンプルもでき次第随時追加予定)。

https://github.com/whyes-develop/neopixel-for-spresense-samples

本当はライブラリと一緒にしたかったんですが…ビルドコンフィグの勉強不足で実現できず…

## 最後に
というわけでSpresense SDKにNeoPixelライブラリを作成してみました。

正直先人のArduinoライブラリをほぼ~~パクって~~参考にしたので、先人のライブラリが無ければ到底作れませんでした…本当に感謝です。レジスタとかアセンブリとかの知識なんてほぼ無いので…
一部 `//なんかよく分からないけど動く` みたいな状態なので、理解はちゃんと深めていこうと思ってます。

私自身組み込みアプリエンジニアを5年くらいやってきたつもりですが、担当範囲が基本ミドルらへんだったので、ハード寄りの知識がほぼ無いことを痛感しました…勉強しないといけないですね。
今後は自分なりに勉強しつつこのライブラリも適宜リファクタしたり、それなりに機能拡張したりできればと思ってます。