LoginSignup
6
4

More than 5 years have passed since last update.

FlashAirでD/AコンバータMCP4922を制御してみた

Last updated at Posted at 2016-01-01

あけましておめでとうございます。今年もよろしくお願いします。
新年早々の電子工作初めは、FlashAirでD/Aコンバータを制御してみました。

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

 FlashAir W-03シリーズでは、SDカード上でLuaスクリプトを実行できます。Luaスクリプトでは、FlashAirのGPIO機能を使って、ソフトウェアSPIによりSPIデバイスを制御することができます。
 これまで、IOエキスパンダMCP23017IOエキスパンダMCP23S17を制御してみましたが、今回は、FlashAirでD/AコンバータMCP4922を制御してみます。

構成

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

IMG_6653s.jpg

SDカードスロット

 SDカードスロットはなんでも構いませんが、今回はSDカードの1番、2番、7番、8番ピンを引き出せる必要があります。

FlashAirとMCP4922の接続

 FlashAirとMCP4922の接続は、以下の表に示す通りに接続します。

FlashAir_MCP4922_pinasign copy.png

CONFIGファイルの設定

 FlashAirのSD_WLANフォルダ内のCONFIGファイルに、以下のオプションを追加します。IFMODEはFlashAirのGPIOモードをONにしています。LUA_RUN_SCRIPTはFlashAirの電源投入後すぐに指定のLuaスクリプトを起動するための設定です。
IFMODE=1
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と同じフォルダに配置してください。

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関数リファレンス

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4