グラフィック液晶をいじってみた

5年ほど前にジャンクで手に入れたグラフィック液晶を思い立っていじってみました。このパーツななぜかHardOffのジャンクコーナーに315円でありました。一緒にあったFTDIのチップのEEPROM中に立川のP社系の名前があったので、そこが整理したものかもしれません。実装されてるICに9505の刻印があるので1995年頃の製品と思われます。

後日追記：ネットで見つけたのですが、2003年くらいに秋葉原の鈴商で取り扱いのあったG2436(240x64)と同系の製品のようです。

この液晶にはHD66204が2個とHD66205が1個使われています。これ以外に部品が実装されていないパターンが二つあります。接続端子は下に15Pinがあり、左に2列の20Pinがあります。20Pinの方は未実装のパターンからつながっているようなので、使えないようです。基板面にはS-10544Aとシルクプリントがありますが、メーカー名などは入っていません。

いろいろ調べたところスタンレーのGMF12064ASLYとおもわれます。90年代後半の製品のようです。この液晶はVRAMが無く、空きパターンにはコントローラーのSED1330FとメモリのSRM2064M(2KByte)が実装されている製品もあったようです。これらは元々エプソンのチップで、ひょっとするとOEMでエプソンに提供していたのかもしれません。今検索するとSED1330FはS-MOS Systemsのデーターシートが見つかります。

![STANLEY-LCD.png](https://qiita-image-store.s3.amazonaws.com/0/104066/b325f32c-d3e2-43a2-f15a-6fbcc3b18bb9.png)


SED1330Fは内部に8BitくらいのCPUとDMAが入っていてLCDコントローラー専用の処理が入ったチップだったと想像できます。

最近では、ほとんどのグラフィック液晶がコントローラーを搭載していて、このモジュールのように素の状態の製品はほとんど見かけません。

以前調べたときにはHD66204とHD66205のデーターシートは見つからなかったのですが、今回調べたら出てきました。またスタンレーのデーターシートも完全な物は見つかってないのですが、また調べていたらGMF12064ASLYのスペックシートは見つかり、15ピンの仕様は判明しました。

|Pin No.|Symbol|Effective Sinal level|Function|
|:--|:--|:--|:--|
|1|FLM|H/L|Scan start signal|
|2|NC|-|No connection|
|3|CL1|H L|Display data latch signal|
|4|CL2|H L|Diaplay data receive signal|
|5|D.OFF|L|Display OFF signal|
|6|D0|H/L|Display data 0 H:ON L:OFF|
|7|D0|H/L|Display data 1 H:ON L:OFF|
|8|D0|H/L|Display data 2 H:ON L:OFF|
|9|D0|H/L|Display data 3 H:ON L:OFF|
|10|VDD|-|Power supplay for logic(+5V)|
|11|VSS|-|GND for logic(0V)|
|12|Vo|-|Contrast adjustment|
|13|VEE|-|Power supply for LCD drive(-17V)|
|14|A|-|Power supply for LED backright(+12V)|
|15|K|-|Power supply for LED backright(0V)|

データーシートは時間をあけて探すと出てきたりする事がよくあります。

HD66204は横のラインの操作を担当して最大80ピクセルの処理が可能です。HD66205は縦の操作をおこないます。

HD66204/HD66205は日立のチップですがHD44104というチップを使った似たようなLCDがあるようなので、HD44104は後継のチップなのかもしれません。

とりあえずArduinoでいじってみる事にします。

当初VEEを入力せずに試していたところ、何となく表示は出るのですが、動きがおかしい状態でした。

最近のLCDデバイスではVEEは内部でDC DCコンバーターで作っていたりしますが、このモジュールは古いので外部で作る必要があります。ジャンクルーターから剥がしたMC34063で作ってみました。Voltage Inverting ConverterのR2が12KでR1が1Kで-16Vくらいで作りました。

![写真（2018-04-22 18.47）.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/bd0b63d4-f4c2-7505-b68a-556bd38004ad.jpeg)

MC34063は結構メジャーなチップで、秋月の昇圧型DCDCコンバータ・キットでも使われていたようです。元々はモトローラのチップだったみたいですが、今はいろいろなメーカがセカンドソースを作っています。

MC34063のドキュメントのAN920/Dの36ページの回路図の出力のコンデンサーの極性が間違えていてあやうく飛ばすところでした。

![スクリーンショット（2018-04-22 19.05.44）.png](https://qiita-image-store.s3.amazonaws.com/0/104066/0c131875-8ad4-1399-32f2-354ba8369fc3.png)

MC34063のオリジナルはモトローラでセカンドソースがいろいろあるようで、今回使った物はADDtekの物でした。シガーソケットのUSB充電器でよく使われているようで、ジャンクで入手したモジュールにもUTCのMC34063が入っていました。

これをつないで以下を実行したところやっと動きました。

```c
// GMF12064ASLY test program

#define FLM  5
#define CL1  6
#define CL2  7
#define D0   8
#define D1   9
#define D2   10
#define D3   11

void setup() {
  pinMode(FLM, OUTPUT);
  pinMode(CL1, OUTPUT);
  pinMode(CL2, OUTPUT);
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);

  digitalWrite(FLM, LOW);
  digitalWrite(CL1, LOW);
  digitalWrite(CL2, LOW);

  digitalWrite(D0, LOW);
  digitalWrite(D1, LOW);
  digitalWrite(D2, LOW);
  digitalWrite(D3, LOW);
}

void loop(){
  int x, y;
  digitalWrite(CL1, HIGH);
  digitalWrite(FLM, HIGH);
  for(y = 0; y < 64; ++y) {

    digitalWrite(CL1, LOW);
    // set test patern data      
    if(y % 2 == 0) {
      digitalWrite(D0, HIGH);
      digitalWrite(D1, LOW);
      digitalWrite(D2, LOW);
      digitalWrite(D3, LOW);
    } 
    else {
      digitalWrite(D0, HIGH);
      digitalWrite(D1, LOW);
      digitalWrite(D2, HIGH);
      digitalWrite(D3, LOW);
    }

    for (x = 0; x < 32; ++x) {
      digitalWrite(CL2, HIGH);
      digitalWrite(CL2, LOW);
      if(x == 31) {
        digitalWrite(CL1, HIGH);
      }
    }
    if(y == 0)
      digitalWrite(FLM, LOW);
  }
}
```

![写真（2018-04-22 18.16）.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/fb78202f-c1e3-94ab-03a7-ca05f9308b98.jpeg)

表示領域が128x64なので、128÷4で32回のループと64回のループで一画面表示できます。

ArduinoのopenGLCDというライブラリがありますが、これはコントローラの入っているモジュールがターゲットで、このモジュールのような素のデバイスはサポートされてないでようです。

シリアルでデーター受け取って表示するようにしてみました。

```c
// GMF12064ASLY display program by seirial data

#define FLM  5
#define CL1  6
#define CL2  7
#define D0   8
#define D1   9
#define D2   10
#define D3   11

int count = 0;
unsigned char vram[128*8];

void setup() {
  int i;

  Serial.begin(19200);
 
  pinMode(FLM, OUTPUT);
  pinMode(CL1, OUTPUT);
  pinMode(CL2, OUTPUT);
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);

  digitalWrite(FLM, LOW);
  digitalWrite(CL1, LOW);
  digitalWrite(CL2, LOW);

  PORTB = 0;

  for (i = 0; i < sizeof(vram); ++i)
    vram[i] = 0x0;
}

void loop(){
  int x, y;
  //  delayMicroseconds(100);
  while(Serial.available() > 0) {
    uint8_t c = Serial.read();
    vram[count] = c;
    ++count;
    if (count == sizeof(vram))
      count = 0;
  }
  digitalWrite(CL1, HIGH);
  digitalWrite(FLM, HIGH);
  for(y = 0; y < 64; ++y) {

    digitalWrite(CL1, LOW);


    for (x = 0; x < 32; ++x) {
      if (x % 2)
        PORTB = vram[y * 16 + x / 2] & 0xf;
      else
        PORTB = vram[y * 16 + x / 2] >> 4;

      digitalWrite(CL2, HIGH);
      digitalWrite(CL2, LOW);
      if(x == 31) {
        digitalWrite(CL1, HIGH);
      }
    }
    if(y == 0)
      digitalWrite(FLM, LOW);
  }
}
```

128x64なので8192ビットで1024バイトです。スタートとストップビットの2ビットを加えると10240ビットで、19200ボーで転送すると0.53秒です。

![写真（2019-03-27 09.45）.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/5d6d332e-0e1b-617f-ce75-660641de1117.jpeg)

mrubyのスクリプトはこんな感じです。

```ruby
def copylcd(c, sp)
  for n in 1..64 do
    rgba = c.getpix(0, n - 1, 128)
    for i in 1..16 do
      pat = 0
      for k in 1..8 do
        if rgba[1 + (i - 1) * 4 * 8 + (k - 1) * 4] == 0xff
          pat |= 1 << (8 - k)
        end
      end
      bytestr = ""
      bytestr.setbyte(0, pat)
      sp.write bytestr
    end
  end
end

sp = SerialPort.new("/dev/ttyU0", 19200, 8, 1, 0)

sleep 4

c = Cairo.new(128,64)

while 1 do

c.set_source_rgb(1, 1, 1)
c.set_line_width(1)
c.rectangle(0.5, 0.5, 127, 62)
c.stroke();

c.move_to(60, 58)
c.set_source_rgb(1, 1, 1)
c.font_create("/root/fonts/6x13.pcf")
c.set_font_size(13)
c.show_text("mruby cairo")
c.stroke();

copylcd(c, sp)
```

ATMEGA328はRAMが2Kで1フレーム1Kと作業領域が必要なので、ダブルバッファにすることはできないです。またATMEGA168などではメモリが足りないので動かせません。

上のコードだと16MHzのATMEGA328で1秒に50回書き換えてました。もう少しすくなくても良さそうです。

と思ったのですが、Timer2を使って実行するとうまく動きませんでした。

ユニバーサル基板で作ってみました。消費電流は70mAくらいのようです。古いものなので消費電力大きいし、少し発振しているようです。

![写真（2019-03-29 18.56）.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/6bda7a2b-0912-f80b-1dbc-79006989255e.jpeg)

昔はコントロール用の専用チップが必要でしたが、汎用マイコンが高性能になって、置き換えが可能になりましたとさ。

後日追記：G2436をH8(16Bit)とCPLDとメモリで駆動してる方がいました。私の方法では240x64のG2436はメモリが足りず処理できませんが、ワンチップで駆動できてるのは、ちょっと良いように思います。