FlashAirとMCP23017で７セグメントLED（２桁）を制御してみた

#FlashAir DIP IOボードキット
　2015年12月初めに、秋月電子通商さんからFlashAir用ブレイクアウトボードである「FlashAir DIP IOボードキット」が発売になりました。このボードキットにはSPI-I2Cインタフェースブリッジ「SC18IS600IBS」が搭載されています。そこでさっそくI2C接続のIOエキスパンダMCP23017を制御してみました。この内容は、サークル「空と月」による同人誌「宵の空」（2015年12月発行、コミックマーケット89にて頒布）にてレビュー記事を書きました。
　まもなく秋葉原の三月兎さんで通販取扱も始まると思いますので、コミケに来られなかった方も、ぜひお手に取ってみてください。

![Sora_Lua_表紙s.png](https://qiita-image-store.s3.amazonaws.com/0/89137/a9edca11-5f50-3081-19ff-4bbe8c3f59b0.png)


　さて、今回は、「宵の空」のレビュー記事ではまだ十分に検証ができず記載できなかったFlashAirのLuaスクリプト関数のfa.spi関数を使って、FlashAir DIP IOボードキットとMCP23017を組み合わせて、２桁の７セグメントLED（2桁LED数字表示器LB-602VA2）を制御して、００〜９９でカウントアップしてみたいと思います。

#構成
　必要なものは以下のとおりです。

- FlashAir DIP IOボードキット （[秋月電子通商](http://akizukidenshi.com/catalog/g/gK-10007/)）
- FlashAir W-03 V3.00.01アップデート済みのもの
- MCP23017 （[秋月電子通商](http://akizukidenshi.com/catalog/g/gI-09486/)）
- 抵抗（10KΩ）２個（I2Cラインのプルアップ用）※ボードキットの裏面のジャンパーをショートさせることで不要になります。
- 抵抗（1MΩ）２個
- 2桁LED数字表示器LB-602VA2（ローム社）※たまたま自宅の道具箱で発見されたもの。
- ブレッドボード用マイクロＢメスＵＳＢコネクタＤＩＰ化キット（[秋月電子通商](http://akizukidenshi.com/catalog/g/gK-06656/)）
- ブレッドボード

![IMG_6706s.jpg](https://qiita-image-store.s3.amazonaws.com/0/89137/131a23a9-7e44-6df4-e813-3c25592483fe.jpeg)

　今回、MCP23017はアドレス設定ピンA0〜2を３本ともGNDに接続して0x20に設定しています。I2C接続の２本の線（SDA、SCL）は、10KΩ抵抗でプルアップしてありますが、FlashAir DIP IOボードキットの裏面のジャンパーをショートさせれば不要です。

#MCP23017とLB-602VA2の接続
　MCP23017のGPIOピンは8本2組の計16本あります。一方、2桁LED数字表示器LB-602VA2は、1桁あたり数字表示部７セグメントとドットの１セグメントの計8個のセグメント（LED）で構成されており、2桁で16本のGPIOで制御できますので、MCP23017でちょうど制御できます。
　MCP23017のGPIOは、GPIOA（GPA0〜GPA7）とGPIOB（GPB0〜GPB7）の２組に分かれているので、コードの書きやすさを考慮して、GPIOAに１桁目、GPIOBニ２桁目を接続します。また１桁目と２桁目の接続が揃うようにしておくとコードが簡略化できます。
　本来、LB-602VA2の各セグメントとMCP23017のGPIOピンの間に抵抗を挟むべきだと思いますが、今回は横着してLB-602VA2のアノードコモン（13番、14番ピン）側に抵抗を挟んでいます。

![FlashAir_7seg_pinasign.png](https://qiita-image-store.s3.amazonaws.com/0/89137/a45d7d28-7d61-55e9-c529-dbbf50326c0f.png)

#CONFIGファイルの設定
　FlashAirのSD_WLANフォルダ内のCONFIGファイルに、以下のオプションを追加します。IFMODEはFlashAirのGPIOモードをONにしています。LUA_RUN_SCRIPTはFlashAirの電源投入後すぐに指定のLuaスクリプトを起動するための設定です。
```IFMODE=1
LUA_RUN_SCRIPT=/mcp23017_7seg_sample.lua
```

　※SD_WLANフォルダとCONFIGファイルは不可視属性ファイルなので注意してください。

#Luaスクリプトファイル
　FlashAirのルートフォルダに以下のコードを記述したテキストファイル（mcp23017_7seg_sample.lua）をコピーします。
　このコードでは、2桁LED数字表示器LB-602VA2に００〜９９を１秒間隔でカウントアップしていき、９９の次は００に戻るようにしています。
　また今回たまたま自宅の道具箱で発見された2桁LED数字表示器LB-602VA2はアノードコモンタイプでしたので、接続したGPIOをLOWにすることでセグメントが点灯します。使用するLED数字表示器の仕様（アノードコモンか、カソードコモンか）で、GPIOのHIGHとLOWが逆になりますので注意してください。

```mcp23017_7seg_sample.lua
-- FlashAir DIP IO Board Kit
-- I2C IO Expander MCP23017 + 7 segments display LB-602VA2
-- Akiduki FlashAir DIP IO Board Kit
local spi_init = 1
local spi_mode = 3
-----------------   0     1     2     3     4     5     6     7     8     9
local LEDNUM = { 0x14, 0xD7, 0x98, 0x91, 0x53, 0x31, 0x30, 0x97, 0x10, 0x11 }

function write_i2c_command(addr,data1, data2)
	fa.spi("read") --この空readの必要性は注釈参照
	fa.spi("cs",0)
	fa.spi("write",0x00)
	fa.spi("write",0x02)
	fa.spi("write",addr)
	fa.spi("write",data1)
	fa.spi("write",data2)
	fa.spi("cs",1)
end

fa.spi("init", spi_init)
fa.spi("mode", spi_mode)
write_i2c_command(0x40, 0x00, 0x00)
write_i2c_command(0x40, 0x01, 0x00)

local idx1 = 0
local idx2 = 0
local cnt = 0
while(1) do
	idx1 = cnt % 10                --１桁目（1の位）
	idx2 = (cnt - (cnt % 10)) / 10 --２桁目（10の位）
	write_i2c_command(0x40, 0x12, LEDNUM[idx1+1]) 
	write_i2c_command(0x40, 0x13, LEDNUM[idx2+1]) 
	sleep(1000)
	cnt = cnt + 1
	if (cnt > 99) then
		cnt = 0
	end
	collectgarbage("collect")
end
```
[注釈]fa.spi("read")の空readの必要性について
　@Seg_faulさんの解析[「fa.spiの挙動(秋月 FlashAir DIP IOボードキットでfa.spiが動かない問題)」](http://gpsnmeajp.blogspot.jp/2015/12/faspi.html)に書かれている通り、秋月FlashAir DIP IOボードキットでは「CSが反映されないことがあるバグ(or仕様)」により、この空readを入れておかないと期待通りの動作になりません。

#まとめ
　以上で、FlashAirから秋月FlashAir DIP IOボードキットを使って、ソフトウェアSPIでI2CデバイスであるMCP23017のGPIOピンのHIGH/LOWを制御することで、2桁LED数字表示器LB-602VA2に数字表示をすることができました。これで、ちょっとしたレベル表示等に応用できますね。

#参考資料
　[FlashAir DIP IOボードキット](https://flashair-developers.com/ja/documents/resources/dipio/)
　[SC18IS600IBSデータシート](http://cache.nxp.com/documents/data_sheet/SC18IS600.pdf)
　[MCP23017データシート](http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf)
　[LB-602VA2データシート](http://rohmfs.rohm.com/jp/products/databook/datasheet/opto/led_display/numeric/lb-602ak2-j.pdf?_ga=1.265198854.843461739.1451748814)