ArduinoでLCDモジュールの使い方(AQM0802)

AQM0802とは

AQM0802は、I2C接続の小型液晶モジュールと呼ばれるものになる。
8文字×2行の文字を表示することが出来る。
基本的に秋月電子で購入できる、ピッチ変換キットを使うことが多い。

秋月電子商品ページより


ブレッドボードに簡単に挿して使えるようになるので、非常に便利。

I2C通信

AQM0802はI2C通信というもので、Arduinoとデータの通信を行う。
I2C通信はフィリップス社が開発したシリアル通信である。
Arduinoでは様々なセンサがこの通信規格を使ってデータのやりとりを行うことが出来る。

AQM0802を使う

AQM0802モジュールのはんだ付け

秋月で購入したキットにはんだ付けを行っていく。


基板上のPUと書かれた部分をはんだ付けすると、基板内で10kΩのプルアップ抵抗を内蔵してくれる。
今回ははんだ付けせずに、ブレッドボード上でプルアップ抵抗をつけることにする。

ブレッドボードでの回路作成

AQM0802を使うには3.3Vの動作電圧で使うようにと秋月電子の商品ページには記載されている。
いろいろネットで調べてみるとAQM0802本体は5.5Vの電圧まで耐えることができるらしい。
だが、このブログでは3.3Vの動作電圧を守って動かしてみようと思う。
そのために必要になるのがレベル変換モジュールになる。



このモジュールを使えば、5Vの電圧を安全に3.3Vに変換してくれる。
双方向なので、3.3Vを5Vに変換することもできる。
3.3Vの動作電圧のモジュールを扱うなら何個か持っておくと非常に便利。




こんな感じにブレッドボードに回路を組んでみた。
レベル変換モジュールはArduinoから5Vと3.3Vの電源を取っている。
Arduinoはピンから出力される電圧は5Vである。これをレベル変換モジュールで3.3Vに変換してAQM0802につなげている。
I2C通信はSCLとSDAという二つのピンにつなげる必要がある。Arduino nanoではA5がSCL、A4がSDAピンとして使える。
そして、AQM0802には3.3Vのプルアップ抵抗をブレッドボードで組んでおいた。


AQM0802のArduinoプログラム

#include <Wire.h>

void setup() {
  Wire.begin();
  lcdInit();
  lcdDisp1("Hello");

}

void loop() {
  // put your main code here, to run repeatedly:

}

//  ------------------------------------------------------------
//  LCD(AQM0802)関係
//  ------------------------------------------------------------
#define LCDA 0x3E           // LCD address
#define CONTRAST 0x20         // for AQM0802@3.3V

//  ----------------------------------------
//  LCDにコマンド送信
//  ----------------------------------------
void lcdCmd(byte cmd) {
  Wire.beginTransmission(LCDA);
  Wire.write((byte)0x00);       // コマンド指定
  Wire.write(cmd);          // コマンド出力
  Wire.endTransmission();       // ストップ

  if( (cmd==0x01) || (cmd==0x02) ) {
    delay(2);             // 2ms待ち
  }
  else {
    delayMicroseconds(30);      // 30us待ち
  }
}

//  ----------------------------------------
//  LCDにデータ送信
//  ----------------------------------------
void lcdData(byte dat) {
  Wire.beginTransmission(LCDA);   // これから...
  Wire.write(0x40);         // データ送るよ
  Wire.write(dat);          // データ
  Wire.endTransmission();       // おしまい
  delayMicroseconds(30);
}

void lcdPut(int x, int y, byte dat){
  lcdLocate( x, y );
  lcdData(dat);
}

void lcdReg(int a, char *str){
  byte H, L;
  byte adr;
  byte dat;
  char *buf;
  
  buf = str;
  if(a == 1){
    adr = 0x40;
  }else if(a == 2){
    adr = 0x48;
  }else if(a == 3){
    adr = 0x50;
  }else if(a == 4){
    adr = 0x58;
  }else if(a == 5){
    adr = 0x60;
  }else if(a == 6){
    adr = 0x68;
  }else if(a == 7){
    adr = 0x70;
  }else if(a == 8){
    adr = 0x78;
  }else {
    adr = 0x40;
  }
  Wire.write(adr);
  Wire.beginTransmission(LCDA);
  for(int i = 0; i < 8; i++){
    H = *buf - '0';
    buf++;
    if(H > 9){
      H = H + '0' - 'a' + 10;
    }
    L = *buf - '0';
    buf++;
    if(L > 9){
      L = L + '0' - 'a' + 10;
    }
    H = H << 4;
    dat = H + L;
    
    Wire.write(dat);
  }
  Wire.endTransmission();
}

//  ----------------------------------------
//  表示位置の指定
//  ----------------------------------------
void lcdLocate(byte col, byte row) {
  byte add = 0x80 + col;        // 1行目+x座標
  if( row>0 ) add += 0x40;      // 2行目に変更
  lcdCmd(add);
}

//  ----------------------------------------
//  初期化
//  ----------------------------------------
void lcdInit() {
  //I2c.begin();            // begin I2C master
  delay(10);
  lcdCmd(0x38);           // 8bit 2line Normal mode
  lcdCmd(0x39);           // 8bit 2line Extend mode
  lcdCmd(0x14);           // OSC 183Hz BIAS 1/5

  // コントラスト設定
  lcdCmd((byte)(0x70 + (CONTRAST & 0x0F))); //下位 4bit
  lcdCmd((byte)(0x5c + (CONTRAST >> 4)));   //上位 2bit
  lcdCmd((byte)0x6b);         // Follwer for 3.3V
  delay(1);

  lcdCmd((byte)0x38);         // Set Normal mode
  lcdCmd((byte)0x0C);         // Display On
  lcdCmd((byte)0x01);         // Clear Display
  delay(1);
}

//  ----------------------------------------
//  全消去関数
//  ----------------------------------------
void lcdClear() {
  lcdCmd(0x01);           // 初期化コマンド出力
  delay(2);
}

//  ----------------------------------------
//  文字列表示関数
//  ----------------------------------------
void lcdPrint( char* cp ) {
  while(*cp!=0x00) {
    lcdData(*cp);
    cp++;
  }
}

//  ----------------------------------------
//  LCDの1行目表示
//  ----------------------------------------
void lcdDisp1( char* cp ) {
  lcdLocate( 0, 0 );
  lcdDisp8( cp );
}

//  ----------------------------------------
//  LCDの2行目表示
//  ----------------------------------------
void lcdDisp2( char* cp ) {
  lcdLocate( 0, 1 );
  lcdDisp8( cp );
}

//  ----------------------------------------
//  8文字表示(普通は使わない)
//  ----------------------------------------
void lcdDisp8( char* cp ) {
  int i;
  for( i=0; i<8; i++ ) {
    if( *cp==0x00 ) break;      // 文字列が終わった
    lcdData( *cp );
    cp++;
  }
  for( ; i<8; i++) {
    lcdData( 0x20 );        // 残りを空白で埋める
    cp++;
  }
}

データシートを読みながら実際にこんなプログラムを組めたら一流のプログラマーなのだが、僕はそこまで頭がよくない。
基本的にコピペで何とかやっている。
今回は、専門学校時代にいただいたソースコードからAQM0802の部分を切り出して使っている。

Arduinoのヘッダファイルにある「Wire.h」というものを使っている。
これはI2C用のライブラリらしい。
ArduinoでI2C通信を行うときは、このライブラリを使えるようにしておく。

Arduinoに書き込みしてみた結果がこのようになる。







コメント

このブログの人気の投稿

STM32CubeIDEに日本語化プラグインを導入する

STM32F401でLチカをする(LED点灯)

STM32F401-Nucleoでシリアル通信をやってみる