2019年2月19日火曜日

MicroPythonでAE-AQM0802を使ってみる。

以前書いたESP-WROOM-02でLCD表示と概ね同じですが、I2Cの復習となっています。

当時だと全くと言って良いほど意味がわからなかった内容が少しは理解出来る程度に成長したかな?と言うのと、同じESP8266を使用しているNodeMCUボードでMicroPythonを使って動かしてみると言う点が違うところですかね。

使用するのは、I2C接続のAE-AQM0802です。
35mmx22mmと非常に小さく、表示出来るのは8文字(横5ドットx縦8ドット)2行と到ってシンプルですが必要十分な機能がコンパクトにまとまっています。
AE-AQM0802のピン配置
No. Pin Name Function
1 VDD 3.3V
2 RESET ハードウェアリセット
3 SCL シリアルクロック入力
4 SDA シリアルデータ入出力
5 GND グランド
動かすにあたって配線してみました。秋月電子通商さんの商品説明にデータシートがあるので、参考に配線してみましょう。
AE-AQM0802とNodeMCUの配線
SCLは、NodeMCUのD1(GPIO5)、SDAは、D2(GPIO4)に接続します。VDDGNDは説明の必要ないですよね? RESETには何も接続しなくても大丈夫なようですが、気になる方はプルアップ抵抗を繋げておくのも良いかと思います。
配線が完了すればコードを書くだけです。MicroPythonではインタラクティブモードがあるので1行づつ実行しながらAE-AQM0802の動作を確認してみたいと思います。
MicroPython v1.10-8-g8b7039d7d on 2019-01-26; ESP module with ESP8266
Type "help()" for more information.
>>>
シリアルコンソールでNodeMCUへアクセスすると、上のような表示でインタラクティブモードが起動しています。
>>>from machine import I2C, Pin
>>>
まず最初にI2C接続の準備としてmachineモジュールに含まれるI2CとPinの2つのクラスを読み込みます。
>>>i2c = I2C(scl=Pin(5), sda=Pin(4),freq=400000)
>>>
SCLをGPIO5(D1)、SDAをGPIO4(D2)、クロックを400kHzでI2Cの接続を確立します。I2C()は、Pin()により指定されたGPIOをSCL、SDAとして設定する事が出来ます。"freq"の値、400000(400k)Hzは、AE-AQM0802で使用されているLCDコントローラST7032でのSCLの最大クロック周波数となります。
"freq"の指定は省略可能です。
>>>i2c.scan()
[62]
>>>
I2Cオブジェクトが作成出来たら、スレーブアドレス(AE-AQM0802に割当てられたアドレス)を確認してみます。
"[62]"(0x3e)と表示。
データシートでは、"0x7c"と指定されていますが異なるようなので要注意です。
この辺りは、コントローラICデータシートに7-bitスレーブアドレスと記載されています。また、スレーブアドレスの指定で以下の様な表記があり、
0 1 1 1 1 1 0 R/W
R/Wは、は書き込み専用の0に割り当てられています。との表記が混乱の原因で、少なくともMicroPythonのI2Cクラス使用する上では、R/Wを外した7-bitのみの"0x3E"と捉えて支障ありません。

ここからは、ST7032の制御の話しとなります。

制御にあたって、下の表のように制御バイトとデータバイトの2バイトで構成するコマンドワードで指定する事になります。
コマンドワード
制御バイト データバイト
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
Co RS 0 0 0 0 0 0 D7 D6 D5 D4 D3 D2 D1 D0
  • 制御バイト
    単一、複数のコマンド送信方法、命令レジスタ(IR)、データレジスタ(DR)のレジスタ選択をCoとRSに定義して動作を指定します。
    bit Co RS
    0 単一コマンドワードを送信 命令レジスタ(IR)へ書込み
    1 複数のコマンドワードを送信 データレジスタ(DR)へ書込み
    • 命令レジスタ(IR)へ書込み
      0x00
      7 6 5 4 3 2 1 0
      0 0 0 0 0 0 0 0
      0x80
      7 6 5 4 3 2 1 0
      1 0 0 0 0 0 0 0
    • データレジスタ(DR)へ書込み
      0x40
      7 6 5 4 3 2 1 0
      0 1 0 0 0 0 0 0
      0xC0
      7 6 5 4 3 2 1 0
      1 1 0 0 0 0 0 0
  • データバイト
    こちらは、8ビット(1バイト)で定義された命令レジスタ(IR)へ書込む命令コード、もしくデータレジスタ(DR)へ書込む文字コードとなります。

    以降では、実際にAE-AQM0802を動作させながら説明していきたいと思います。
    ここでは、制御バイトは命令レジスタでは0x00、データレジスタでは0x40を使用します。
>>>i2c.writeto_mem(0x3e, 0x00, b'\x38')
>>>
最初に、I2Cで書込みに使用しているメソッドの説明です。
i2c.writeto_mem(addr, memaddr, buf, *, addrsize=8)
  • addr :スレーブアドレス(16進数)
  • memaddr :メモリアドレス / レジスタアドレス(16進数)
  • buf:バッファ / 書き込むbyte情報(バイト型のみ)
  • addrsize :アドレスサイズ(ESP8266では8bit固定で使用不可)
AE-AQM0802では、指定したレジスタアドレスが命令レジスタであれば続くデータバイトをデコードして命令を設定し、データレジスタであればレジスタに書き込まれた内容を自動的にDDRAM / CGRAM へ転送します。
以上より、ここで指定しているのは、addrへAE-AQM0802のスレーブアドレス(0x3e)、memaddrへは命令レジスタ(0x00)、bufのb'\x38'は16進の値をバイト型に変換しているもので、その命令の内容は、
8ビットバスモード / 2行表示モード / 通常フォント / 通常命令
のようになります。※詳しくは下記を参照
>>>i2c.writeto_mem(0x3e, 0x00, b'\x39')
>>>
8ビットバスモード / 2行表示モード / 通常フォント / 拡張命令
Function Set - 命令コード
D7 D6 D5 D4 D3 D2 D1 D0
0 0 1 DL N DH 0 IS
0 0 1 0 0 0 0 0 0x20
0 0 1 0 0 0 0 1 0x21
0 0 1 0 0 1 0 0 0x24
0 0 1 0 0 1 0 1 0x25
0 0 1 0 1 0 0 0 0x28
0 0 1 0 1 0 0 1 0x29
0 0 1 0 1 1 0 0 0x2C
0 0 1 0 1 1 0 1 0x2D
0 0 1 1 0 0 0 0 0x30 電源投入時の初期値
0 0 1 1 0 0 0 1 0x31
0 0 1 1 0 1 0 0 0x34
0 0 1 1 0 1 0 1 0x35
0 0 1 1 1 0 0 0 0x38
0 0 1 1 1 0 0 1 0x39
0 0 1 1 1 1 0 0 0x3C
0 0 1 1 1 1 0 1 0x3D
  • DL : インタフェースデータ長制御ビット
    バスモードを選択するための信号です。
    0 : 4ビットバスモード
    1 : 8ビットバスモード
    ※4ビットバスモードのときは、4ビットデータを2回転送する必要があります。
  • N : 表示行数制御ビット
    0 : 1行表示モード
    1 : 2行表示モード
  • DH : ダブルハイトフォントタイプ制御ビット
    DH = 0 : 通常フォント(5x8ドット)
    DH = 1 & N = 0 : ダブルハイトモード(5x16ドット)
    DH = 1 & N = 1 : 使用不可
    ※ダブルハイトモードではRAMアドレスは00H〜27Hしか使用できません。
  • IS : 通常/拡張命令選択
    0 : 通常命令
    1 : 拡張命令
>>>i2c.writeto_mem(0x3e, 0x00, b'\x14')
>>>
バイアスを1/5に設定 / フレーム周波数を183Hz
Bias selection/Internal OSC frequency adjust - 命令コード
D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 1 BS F2 F1 F0
0 0 0 1 0 0 0 0 0x10
0 0 0 1 0 0 0 1 0x11
0 0 0 1 0 0 1 0 0x12
0 0 0 1 0 0 1 1 0x13
0 0 0 1 0 1 0 0 0x14 電源投入時の初期値
0 0 0 1 0 1 0 1 0x15
0 0 0 1 0 1 1 0 0x16
0 0 0 1 0 1 1 1 0x17
0 0 0 1 1 0 0 0 0x18
0 0 0 1 1 0 0 1 0x19
0 0 0 1 1 0 1 0 0x1A
0 0 0 1 1 0 1 1 0x1B
0 0 0 1 1 1 0 0 0x1C
0 0 0 1 1 1 0 1 0x1D
0 0 0 1 1 1 1 0 0x1E
0 0 0 1 1 1 1 1 0x1F
  • BS : バイアス選択
    バスモードを選択するための信号です。
    0 : バイアスを1/5に設定
    1 : バイアスを1/4に設定
    ※外付けバイアス抵抗を使用すると(OPF1 = 1、OPF2 = 1)、BSは無効になります
  • F2, F1, F0 : 内部OSC周波数調整
    CLSをHIGH(電源)に接続すると、その命令はOSCとフレーム周波数を調整できます。よって、内部OSC周波数は"1,0,0"(183or192)に固定。
    Internal frequency adjust Frame frequency ( Hz )
    (2 line mode)
    F2 F1 F0 VDD = 3.0 V VDD = 5.0 V
    0 0 0 122 120
    0 0 1 131 133
    0 1 0 144 149
    0 1 1 161 167
    1 0 0 183 192
    1 0 1 221 227
    1 1 0 274 277
    1 1 1 347 347
>>>i2c.writeto_mem(0x3e, 0x00, b'\x73')
>>>
コントラスト設定の下位4ビットを設定。
Contrast set(low byte) - 命令コード
D7 D6 D5 D4 D3 D2 D1 D0
0 1 1 1 C3 C2 C1 C0
0 1 1 1 0 0 0 0 0x70 電源投入時の初期値
0 1 1 1 0 0 0 1 0x71
0 1 1 1 0 0 1 0 0x72
0 1 1 1 0 0 1 1 0x73
0 1 1 1 0 1 0 0 0x74
0 1 1 1 0 1 0 1 0x75
0 1 1 1 0 1 1 0 0x76
0 1 1 1 0 1 1 1 0x77
0 1 1 1 1 0 0 0 0x78
0 1 1 1 1 0 0 1 0x79
0 1 1 1 1 0 1 0 0x7A
0 1 1 1 1 0 1 1 0x7B
0 1 1 1 1 1 0 0 0x7C
0 1 1 1 1 1 0 1 0x7D
0 1 1 1 1 1 1 0 0x7E
0 1 1 1 1 1 1 1 0x7F
  • C3, C2, C1, C0 : コントラストセット(下位バイト)
    C5、C4、C3、C2、C1、C0は、内部フォロワを使用している場合にのみ設定できます(OPF1 = 0、OPF2 = 0)。それらはより正確にV0ジェネレータの入力基準電圧を調整することができます。詳細はLCDドライバ用電源電圧を参照してください。
>>>i2c.writeto_mem(0x3e, 0x00, b'\x56')
>>>
ICON表示をオフ / 昇圧回路をオン / コントラスト"100011 = 35"(上位+下位)
コントラストは、0〜63までの64段階なので中ほどの明るさに設定しています。
Power/ICON control/Contrast set(high byte) - 命令コード
D7 D6 D5 D4 D3 D2 D1 D0
0 1 0 1 Ion Bon C5 C4
0 1 0 1 0 0 0 0 0x50
0 1 0 1 0 0 0 1 0x51
0 1 0 1 0 0 1 0 0x52 電源投入時の初期値
0 1 0 1 0 0 1 1 0x53
0 1 0 1 0 1 0 0 0x54
0 1 0 1 0 1 0 1 0x55
0 1 0 1 0 1 1 0 0x56
0 1 0 1 0 1 1 1 0x57
0 1 0 1 1 0 0 0 0x58
0 1 0 1 1 0 0 1 0x59
0 1 0 1 1 0 1 0 0x5A
0 1 0 1 1 0 1 1 0x5B
0 1 0 1 1 1 0 0 0x5C
0 1 0 1 1 1 0 1 0x5D
0 1 0 1 1 1 1 0 0x5E
0 1 0 1 1 1 1 1 0x5F
  • Ion : ICON表示のオン/オフを設定します
    0 : ICON表示をオフ
    1 : ICON表示をオン
  • Bon : スイッチブースター回路
    内部フォロワが使用されている場合にのみ設定できます(OPF1=0、OPF2=0)。
    0 : 昇圧回路をオフ
    1 : 昇圧回路をオン
  • C5, C4 : コントラストセット(上位バイト)
    C5、C4、C3、C2、C1、C0は、内部フォロワを使用している場合にのみ設定できます(OPF1 = 0、OPF2 = 0)。それらはより正確にV0ジェネレータの入力基準電圧を調整することができます。詳細はLCDドライバ用電源電圧を参照してください。
>>>i2c.writeto_mem(0x3e, 0x00, b'\x6c')
>>>
スイッチフォロワ回路をオン / V0ジェネレータ増幅率を"1,0,0 = 2"に設定
Follower control - 命令コード
D7 D6 D5 D4 D3 D2 D1 D0
0 1 1 0 Fon Rab2 Rab1 Rab0
0 1 1 0 0 0 0 0 0x60
0 1 1 0 0 0 0 1 0x61
0 1 1 0 0 0 1 0 0x62 電源投入時の初期値
0 1 1 0 0 0 1 1 0x63
0 1 1 0 0 1 0 0 0x64
0 1 1 0 0 1 0 1 0x65
0 1 1 0 0 1 1 0 0x66
0 1 1 0 0 1 1 1 0x67
0 1 1 0 1 0 0 0 0x68
0 1 1 0 1 0 0 1 0x69
0 1 1 0 1 0 1 0 0x6A
0 1 1 0 1 0 1 1 0x6B
0 1 1 0 1 1 0 0 0x6C
0 1 1 0 1 1 0 1 0x6D
0 1 1 0 1 1 1 0 0x6E
0 1 1 0 1 1 1 1 0x6F
  • Fon : スイッチフォロワ回路
    内部フォロワが使用されている場合にのみ設定できます(OPF1=0、OPF2=0)。
    0 : 内部フォロワ回路をオフ
    1 : 内部フォロワ回路をオン
  • Rab2,Rab1,Rab0 : V0ジェネレータ増幅率
    内部フォロワが使用されている場合にのみ設定できます(OPF1=0、OPF2=0)。これらはV0ジェネレータの増幅率を調整することができます。
    V0ボルテージフォロア値計は以下の計算式で求められるようです。
    が、正直良く理解出来てないです。
    V0 = ( 1 + Rb / Ra ) x Vref
    While Vref = VDD ( α + 36/100 )
    VDD: 電源(ここでは3.3V?3.0V?)
    α: コントラスト(ここでは35)
    Rab2 Rab1 Rab0 1+Rb/Ra
    0 0 0 1
    0 0 1 1.25
    0 1 0 1.5
    0 1 1 1.8
    1 0 0 2
    1 0 1 2.5
    1 1 0 3
    1 1 1 3.75
    以上から、求められるはずなんですけどね?増幅率だから単位はdB?
>>>i2c.writeto_mem(0x3e, 0x00, b'\x38')
>>>
8ビットバスモード / 2行表示モード / 通常フォント / 通常命令
ここでは、通常命令に戻すためだけに使用されているようです。
>>>i2c.writeto_mem(0x3e, 0x00, b'\x0C')
>>>
表示オン / カーソル表示をオフ / カーソル点滅表示をオフ
Display ON/OFFDisplay ON/OFF - 命令コード
D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 1 D C B
0 0 0 0 1 0 0 0 0x08 電源投入時の初期値
0 1 0 0 1 0 0 1 0x09
0 1 0 0 1 0 1 0 0x0A
0 1 0 0 1 0 1 1 0x0B
0 1 0 0 1 1 0 0 0x0C
0 1 0 0 1 1 0 1 0x0D
0 1 0 0 1 1 1 0 0x0E
0 1 0 0 1 1 1 1 0x0F
  • D : 表示ON / OFF制御ビット
    0 : 表示は消えますが、表示データはDDRAMに残ります。
    1 : 全体表示がオンになります。
  • C : カーソルON / OFF制御ビット
    内部フォロワが使用されている場合にのみ設定できます(OPF1=0、OPF2=0)。
    0 : カーソルの表示は消えますが、I / Dレジスタのデータは保持されます。
    1 : カーソル表示がオンになります。
  • B : カーソル点滅ON / OFF制御ビット
    0 : カーソル点滅表示がオフになります。
    1 : カーソル点滅表示がオンになり、表示文字が交互に点滅表示されます。
8ビットバスモード / 2行表示モード / 通常フォント / 通常命令
ここでは、通常命令に戻すためだけに使用されているようです。
>>>i2c.writeto_mem(0x3e, 0x00, b'\x01')
>>>
表示の初期化
Clear Display  - 命令コード
D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 0 0 0 1 0x01
DDRAMアドレス全体に"20H"(スペースコード)を書き込み表示データをすべて消去し、AC(アドレスカウンタ)に "00H"を書き込んでDDRAMアドレスを設定します。カーソルを1行目の左端の初期位置へ移動します。入力モードをインクリメント(I/D = "1")します。
以上が初期化処理で、データバイトで命令コードを設定するサンプルとなります。

次にデータレジスタ(DR)への書き込み。。と行きたいところですが、初期化の項目に入っていないものの電源投入時に設定されている項目がもう一つあったので、そちらの情報だけ記載しておきます。
Entry Mode Set  - 命令コード
D7 D6 D5 D4 D3 D2 D1 D0
0 0 0 0 0 1 I/D S
0 0 0 0 0 1 0 0 0x04
0 0 0 0 0 1 0 1 0x05
0 0 0 0 0 1 1 0 0x06 電源投入時の初期値
0 0 0 0 0 1 1 1 0x07
  • I/D : DDRAMアドレスの増減(カーソルまたは点滅)
    0 :
    カーソル/点滅が左に移動し、DDRAMアドレスが1つ減少します。
    1 :
    カーソル/点滅が右に移動し、DDRAMアドレスが1つ増えます。
    ※CGRAMから読み書きする場合、DDRAMと同じように動作します。
  • 0 :
    または、DDRAMリード(CGRAMリード/ライト)動作の場合、表示全体のシフトは行われません。
    1 :
    更にDDRAM書き込み動作の場合、I/D値に従って表示全体のシフトが行われます(I/D = "1":左シフト、I/D = "0":右シフト)。

画面を見てみると、うっすらと黒い箱みたいなものが16個並んでいるのを確認出来るかと思います。これは表示が先ほどまでの設定が有効になっている事を示します。
では、いよいよ文字を表示を行ってみます。
>>>i2c.writeto_mem(0x3e, 0x40, b'\x41')
>>>
今までは、0x00の命令レジスタ(IR)に書き込みしてきましたが、ここでは文字コードを転送するのでデータレジスタ(DR)の0x40へ書込みします。
b'\41'は文字コードで、アルファベットの大文字"A"を指します。
画面への表示が確認出来たら、続けて文字を表示してみましょう。
>>>i2c.writeto_mem(0x3e, 0x40, b'\x62')
>>>
"A"の右横に"b"が表示されたと思います。
この自動的に右横に表示されたのは、電源投入時の初期設定"Entry Mode Set"で、左シフトが有効化のI/D=1となっているのでインクリメントされた結果です。

まだ、色々試していない点も多いのですが長文になってきたので、一旦終了します。
最後に、
>>>i2c.writeto_mem(0x3e, 0x00, b'\x01')
>>>for i in 'See you!':
...i2c.writeto_mem(0x3e, 0x40, i.encode())
...
...
...
>>>
です!

0 件のコメント:

コメントを投稿