FlashAirでグラフィック液晶AQM1248Aを制御してみた

先日、秋葉原の秋月電子さん店頭で、なんとなく目に入って買ってみた超小型グラフィックＬＣＤピッチ変換キットAE-AQM1248（SPI接続の超小型グラフィック液晶AQM1248A搭載）を、FlashAirで制御してみました。

#FlashAir W-03のLuaスクリプト実行環境
　FlashAir W-03シリーズでは、SDカード上でLuaスクリプトを実行できます。Luaスクリプトでは、FlashAirのGPIO機能を使って、ソフトウェアSPIによりSPIデバイスを制御することができます。
　これまで、[D/AコンバータMCP4922](http://qiita.com/ayasehiro/items/1b03a24b463b67f31c32)や[IOエキスパンダMCP23S17](http://qiita.com/ayasehiro/items/778d15bb4ee1c2a218c8)を制御してみましたが、今回は、FlashAirで超小型グラフィック液晶AQM1248Aを制御してみます。

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

- FlashAir W-03 V3.00.01アップデート済みのもの
- 超小型グラフィックＬＣＤピッチ変換キットAE-AQM1248（[秋月電子通商](http://akizukidenshi.com/catalog/g/gK-07007/)）
- SDカードスロット（[カードソケットSD-N0940](http://www.aitendo.com/product/1194)をDIP化）
- 3.3V定電圧レギュレータ（[秋月電子通商](http://akizukidenshi.com/catalog/g/gI-00538/)）
- ブレッドボード
- ACアダプタ（5V）:手持ちのものを利用

![IMG_9328s.jpg](https://qiita-image-store.s3.amazonaws.com/0/89137/0e5e9c75-17ce-011f-9380-d1f97c4aeb8f.jpeg)

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

###FlashAirとAE-AQM1248の接続
　FlashAirとAE-AQM1248の接続は、以下の表に示す通りに接続します。

![FlashAir_AQM1248_pinasign.png](https://qiita-image-store.s3.amazonaws.com/0/89137/4b7c29dd-b5c8-3caa-68ac-7a1dec05cec5.png)

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

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

#Luaスクリプトファイル
　FlashAirのルートフォルダに以下のコードを記述したテキストファイル（GLCDsample.lua）をコピーします。
　このコードでは、まずはグラフィック液晶がどの程度の速度で書き換えられるのかを試すため、全面にビットパターンを描いて、消すことを繰り返します。このコードを作成するために、以下のサイトを参考にさせていただきました。

[しなぷすのハード製作記 - Arduino用ヘッダシールドの製作(3)](http://www3.big.or.jp/~schaft/hardware/HeaderShield/page003.html)

　今回試したAQM1248AはSPI接続対応ではありますが、コマンド送信とデータ送信の区別をするためにRS端子のHIGH/LOWを制御する必要があります。そのため、FlashAirのLuaスクリプトで提供されているfa.spi関数は使わず、[D/AコンバータMCP4922](http://qiita.com/ayasehiro/items/1b03a24b463b67f31c32)と同様にfa.pio関数を使って制御しています。fa.pio関数はそのままでは使いづらいので、@Seg_Faulさんが公開しているライブラリ[FlashAirのPIOをArduino風に扱う](https://sites.google.com/site/gpsnmeajp/electricmemo/flashairnopiowoarduino-fengni-xiu)を利用しています。pioduino.luaをダウンロードして、GLCDsample.luaと同じフォルダに配置してください。


```GLCDsample.lua
-- FlashAir
-- AQM1248A 128x48 Graphic LCD
require("pioduino")
DA_SCK  = 1  --0x02 0000 0010 --> SD-pin 7
DA_SDI  = 0  --0x01 0000 0001 --> SD-pin 2
DA_CS   = 2  --0x04 0000 0100 --> SD-pin 8
DA_RS   = 4  --0x10 0001 0000 --> SD-pin 1

function delay(value)
	sleep(value)
end

function SPISend(value)
	digitalWrite(DA_SDI, value)
	digitalWrite(DA_SCK, HIGH)
	digitalWrite(DA_SCK, LOW)
end

function LcdCommand(value)
	--コマンドデータの出力
	digitalWrite(DA_RS, LOW)
	digitalWrite(DA_CS, LOW)
	--8bitデータ出力
	for i=7, 0, -1 do
		if (bit32.band(bit32.rshift(value, i), 0x01) == 1) then
			SPISend(HIGH)
		else
			SPISend(LOW)
		end
	end
	digitalWrite(DA_CS,HIGH)
end

function LcdData(value)
	--コマンドデータの出力
	digitalWrite(DA_RS, HIGH)
	digitalWrite(DA_CS, LOW)
	--8bitデータ出力
	for i=7, 0, -1 do
		if (bit32.band(bit32.rshift(value, i), 0x01) == 1) then
			SPISend(HIGH)
		else
			SPISend(LOW)
		end
	end
	digitalWrite(DA_CS,HIGH)
end

function LCDInit()
 	LcdCommand(0xae) --Display = OFF
	LcdCommand(0xa0) --ADC = nomal
	LcdCommand(0xc8) --Common output = revers
	LcdCommand(0xa3) --LCD bias set = 1/7
	
	LcdCommand(0x2c) --power control 1 = 0N
	delay(2);
	LcdCommand(0x2e) --power control 2 = 0N
	delay(2);
	LcdCommand(0x2f) --power control 3 = 0N
	
	LcdCommand(0x23) --Vo voltage resistor ration set
	LcdCommand(0x81) --Electronic volume mode set
	LcdCommand(0x1c) --Electronic volume value set
	LcdCommand(0xa4) --Display all point = normal
	LcdCommand(0x40) --Display start line = 0
	LcdCommand(0xa6) --Display nomal/revers = normal
	LcdCommand(0xaf) --Display = ON
end

pinMode(DA_SCK, OUTPUT)
pinMode(DA_SDI, OUTPUT)
pinMode(DA_CS,  OUTPUT)
pinMode(DA_RS,  OUTPUT)
digitalWrite(DA_SCK,LOW)
delay(1000)
LCDInit()
while(1) do
	for page = 0, 5 do
		LcdCommand(0xb0+page); -- 1011 XXXX : XXXX = page address
    	LcdCommand(0x10);      -- 0001 0000 : Column address set upper bit = 0000
    	LcdCommand(0x00);      -- 0000 0000 : Column address set lower bit = 0000
		for x = 0, 127 do
			LcdData(0)
		end
	end
	delay(1000)
	for page = 0, 5 do
		LcdCommand(0xb0+page);
    	LcdCommand(0x10);
    	LcdCommand(0x00);
		for x = 0, 127 do
			LcdData(x)
		end
	end
	delay(1000)
	collectgarbage("collect")
end
```

#まとめ
　以上で、FlashAirからfa.pio関数を使って超小型グラフィック液晶AQM1248Aの描画を制御することができました。ちょっと書き換え速度が遅いのですけど。これを使って、鉄道模型のポイント制御装置で、ポイント開通方向の表示などしても面白いかなと思っています。

#参考資料
　[しなぷすのハード製作記 - Arduino用ヘッダシールドの製作(3)](http://www3.big.or.jp/~schaft/hardware/HeaderShield/page003.html)
　[AQM1248Aデータシート](hhttp://akizukidenshi.com/download/ds/xiamen/AQM1248.pdf)
　[FlashAirのPIOをArduino風に扱う](https://sites.google.com/site/gpsnmeajp/electricmemo/flashairnopiowoarduino-fengni-xiu)
　[FlashAir Developers Lua関数リファレンス](https://flashair-developers.com/ja/documents/api/lua/reference/)