あけましておめでとうございます。今年もよろしくお願いします。
新年早々の電子工作初めは、FlashAirでD/Aコンバータを制御してみました。
#FlashAir W-03のLuaスクリプト実行環境
FlashAir W-03シリーズでは、SDカード上でLuaスクリプトを実行できます。Luaスクリプトでは、FlashAirのGPIO機能を使って、ソフトウェアSPIによりSPIデバイスを制御することができます。
これまで、IOエキスパンダMCP23017やIOエキスパンダMCP23S17を制御してみましたが、今回は、FlashAirでD/AコンバータMCP4922を制御してみます。
#構成
必要なものは以下のとおりです。
- FlashAir W-03 V3.00.01アップデート済みのもの
- MCP4922 (秋月電子通商)
- SDカードスロット(カードソケットSD-N0940をDIP化)
- 3.3V定電圧レギュレータ(秋月電子通商)
- ブレッドボード
- 動作確認用のLEDと抵抗
- ACアダプタ(5V):手持ちのものを利用
###SDカードスロット
SDカードスロットはなんでも構いませんが、今回はSDカードの1番、2番、7番、8番ピンを引き出せる必要があります。
###FlashAirとMCP4922の接続
FlashAirとMCP4922の接続は、以下の表に示す通りに接続します。
#CONFIGファイルの設定
FlashAirのSD_WLANフォルダ内のCONFIGファイルに、以下のオプションを追加します。IFMODEはFlashAirのGPIOモードをONにしています。LUA_RUN_SCRIPTはFlashAirの電源投入後すぐに指定のLuaスクリプトを起動するための設定です。
LUA_RUN_SCRIPT=/mcp4922sample.lua
※SD_WLANフォルダとCONFIGファイルは不可視属性ファイルなので注意してください。
#Luaスクリプトファイル
FlashAirのルートフォルダに以下のコードを記述したテキストファイル(mcp4922sample.lua)をコピーします。
このコードでは、MCP4922のVOUTAとVOUTBの出力を徐々に上げていくようにしています。接続されたLEDは、交互に徐々に明るくなります。
今回試したMCP4922はSPI接続対応ではありますが、単純に接続するだけではなく、制御するためにはLDACピンのHIGH/LOWを制御する必要があります。SPIで16ビットのデータを送信した後、LDACピンをLOWにすることで、VREFAまたはVREFBにかかっている電圧に基づき書き込んだ値(0〜4096)に応じてVOUTAまたはVOUTBの出力値が変化します。
MCP4922に送信する16ビットのデータは以下のようになっています。
15ビット:VOUTA/VOUTBの選択(0:VOUTA、1:VOUTB)
14ビット:VREF入力のバッファ制御有無(0:なし、1:あり)
13ビット:出力ゲインの選択(0:VREFA/Bの2倍、1:VREFA/Bの1倍)
12ビット:シャットダウン制御有無(0:アナログ出力あり、1:アナログ出力なし)
11〜0ビット:出力値の指定(4096段階:0x000[0]〜0xFFF[4095])
また、本当はFlashAirのSPI用のLuaスクリプト関数であるfa.spi関数を使って制御したかったのですが、うまくいかず、とりあえず今回はfa.pio関数を使って制御しています。fa.pio関数はそのままでは使いづらいので、@Seg_Faulさんが公開しているライブラリFlashAirのPIOをArduino風に扱うを利用しています。pioduino.luaをダウンロードして、mcp4922sample.luaと同じフォルダに配置してください。
-- FlashAirでD/AコンバータMCP4922を制御する
require("pioduino")
MCP4922_OUTA = 0
MCP4922_OUTB = 1
DA_SDI = 0 --0x01 SD-pin 2
DA_SCK = 1 --0x02 SD-pin 7
DA_CS = 2 --0x04 SD-pin 8
--DA_SDO = 3 --0x08 SD-pin 9 --未使用
DA_LDAC = 4 --0x10 SD-pin 1
function MCP4922DataSend(value)
digitalWrite(DA_SDI, value)
digitalWrite(DA_SCK, HIGH)
digitalWrite(DA_SCK, LOW)
end
function MCP4922CommandSend(outab, value)
--コマンドデータの出力
digitalWrite(DA_LDAC,HIGH) --LDACピンをHIGHに
digitalWrite(DA_CS,LOW) --CSピンをLOWに
--出力ピン(VOUTA/VOUTB)を指定
if (outab == 0) then
MCP4922DataSend(LOW) --VOUTA
else
MCP4922DataSend(HIGH) --VOUTB
end
MCP4922DataSend(LOW) --VREFバッファ制御なし
MCP4922DataSend(HIGH) --出力ゲインは1倍
MCP4922DataSend(HIGH) --アナログ出力あり
--12ビット分のデータを出力
for i=11, 0, -1 do
if (bit32.band(bit32.rshift(value, i), 0x01) == 1) then
MCP4922DataSend(HIGH)
else
MCP4922DataSend(LOW)
end
end
digitalWrite(DA_CS,HIGH) --CSピンをHIGHに
digitalWrite(DA_LDAC,LOW) --LDACピンをLOWに
end
pinMode(DA_SCK, OUTPUT)
pinMode(DA_SDI, OUTPUT)
pinMode(DA_CS, OUTPUT)
pinMode(DA_LDAC,OUTPUT)
digitalWrite(DA_SCK,LOW)
delay(1000) --ここでちょっと待たないと上手く動かない。
while(1) do
MCP4922CommandSend(MCP4922_OUTB, 0)
for cnt = 0, 4000, 100 do
MCP4922CommandSend(MCP4922_OUTA, cnt)
delay(100)
end
MCP4922CommandSend(MCP4922_OUTA, 0)
for cnt = 0, 4000, 100 do
MCP4922CommandSend(MCP4922_OUTB, cnt)
delay(100)
end
collectgarbage("collect") --定期的にお掃除
end
#まとめ
以上で、FlashAirからfa.pio関数を使ってD/AコンバータMCP4922を制御することができました。
これで、FlashAirにアナログ出力を増設することができました。さらに応用の幅が大きく広がりますね。
#参考資料
DAコンバータ MCP4922(SPI)を利用しD/A変換を行う
MCP4922データシート
FlashAirのPIOをArduino風に扱う
FlashAir Developers Lua関数リファレンス