Lua
FlashAir
SPI
MCP23S17

FlashAirでIOエキスパンダMCP23S17を制御してみた

More than 3 years have passed since last update.


FlashAir W-03のLuaスクリプト実行環境

 FlashAir W-03シリーズでは、SDカード上でLuaスクリプトを実行できます。Luaスクリプトでは、FlashAirのGPIO機能を使って、ソフトウェアSPI(fa.spi関数)によりSPIデバイスを制御することができます。

 前回、Airio RPとI2C接続したIOエキスパンダMCP23017を制御しましたが、今回は、FlashAirと直結したIOエキスパンダMCP23S17(SPIインターフェース)を制御してみます。

 Lua関数リファレンス


構成

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


  • FlashAir W-03 V3.00.01アップデート済みのもの

  • MCP23S17 (マルツオンライン

  • SDカードスロット

  • 3.3V定電圧レギュレータ(秋月電子通商

  • ブレッドボード

  • 動作確認用のLEDと抵抗

  • ACアダプタ(5V):手持ちのものを利用

更新した検証構成(2015/12/13追記)

flashair_mcp23S17_2.jpg

当初検証構成

flashair_mcp23S17.jpg


MCP23S17の接続

 今回、MCP23S17はアドレス設定ピンA0〜2を3本ともGNDに接続して0x20に設定しています。また、MCP23S17のGPIOの動作確認用にGPIOAとGPIOBの代表ピンにLEDを接続しています。


SDカードスロット

 SDカードスロットはなんでも構いませんが、FlashAirでソフトウェアSPI(fa.spi関数)を使う場合、SDカードの2番、7番、8番、9番ピンを引き出せる必要があります。

 当初検証構成では、秋月のDIP化モジュールのチップ抵抗を外して改造したものを利用していました。これは9番ピンが引き出されていませんので、自分でワイヤーを接続する必要があります。またFlashAirは3.3V駆動ですので、外部電源が今回のように5Vの場合は、3.3Vに変換する必要があります。秋月のDIP化モジュールには3.3V定電圧レギュレータが搭載されているので、これを利用しました。(手元に3.3VのACアダプタがなかったので外部電源が5Vになりました)

(以下2015/12/13追記)

 更新した検証構成では、SDカードスロットをカードソケットSD-N0940を使ってDIP化を自作しました。これはFlashAirとMCP23S17のSPI接続のワイヤー長を極力短くするためです。


FlashAirとMCP23S17の接続

 FlashAirとMCP23S17のSPI接続は、以下の表に示す対応通りに接続します。

FlashAir_MCP23S17_pinasign.png


CONFIGファイルの設定

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

IFMODE=1

LUA_RUN_SCRIPT=/mcp23S17sample.lua

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


Luaスクリプトファイル

 FlashAirのルートフォルダに以下のコードを記述したテキストファイル(mcp23S17sample.lua)をコピーします。

 このコードでは、MCP23S17のGPIOAとGPIOBの各8本のGPIOピンを交互に1秒ずつHIGHとLOWを切り替えています。GPIOAとGPIOBのGPIOピンにLEDを接続すれば、1秒ずつ交互に点滅するようになります。

 以下のコードではfa.spi("init", 645)と比較的低い周波数を指定しています。これは高い周波数だと動作しなかったためです。MCP23S17の仕様上では10MHzまでサポートされていますので、fa.spi("init", 1)でも理論的には動作するはずですが、写真にあるように今回の構成ではFlashAirとMCP23S17を直結するワイヤーの長さが長いため高い周波数では動作しなかったものと思われます。

(以下2015/12/13追記)

 更新した検証構成では、fa.spi("init", 1)でも動作することを確認しました。やはり高い周波数にするにはSPI接続部分のワイヤー長を極力短くする必要があるようです。


mcp23S17sample.lua

-- FlashAir AirioRP

-- I2C IO Expander MCP23017
function write_command(addr,data1, data2)
fa.spi("cs",0)
fa.spi("write",addr)
fa.spi("write",data1)
fa.spi("write",data2)
fa.spi("cs",1)
end

fa.spi("init", 1) --MCP23S17で動作確認済み
fa.spi("mode", 0) --MCP23S17で動作確認済み
sleep(500) --ちょっと待つ。待たないと次のGPIOAのOutput指定が失敗しているような感じ。検証が必要。
write_command(0x40, 0x00, 0x00) --GPIOAをOutputに指定
write_command(0x40, 0x01, 0x00) --GPIOBをOutputに指定
while(1) do
write_command(0x40, 0x12, 0xFF) --GPIOAをすべてHIGHに指定
sleep(1000)
write_command(0x40, 0x12, 0x00) --GPIOAをすべてLOWに指定
sleep(1000)
write_command(0x40, 0x13, 0xFF) --GPIOBをすべてHIGHに指定
sleep(1000)
write_command(0x40, 0x13, 0x00) --GPIOBをすべてLOWに指定
sleep(1000)
end



まとめ

 以上で、FlashAirからソフトウェアSPI(fa.spi関数)を使ってSPIデバイスであるMCP23S17のGPIOピンのHIGH/LOWを制御することができました。理論的にはI2C接続であるMCP23017よりも速く制御ができるはずです。

 これで、FlashAirに一気に16本のGPIOを増設することができて、応用の幅が大きく広がりますね。


参考資料

 MCP23S17データシート

 FlashAir Developers Lua関数リファレンス