明日は我が身の備忘録(あすびぼ)

自分向け備忘録です。頻繁に更新は難しいでしょうね

ArduinoUNO + 有機ELキャラクタディスプレイモジュール でアナログ値の表示

 前回I2Cで通信するモータドライバモジュールを動かしてみたが、今回は手持ちであった秋月電子のI2C有機ELキャラクタディスプレイにArduinoから表示してみる。

f:id:kirikoshokunin:20210329215711j:plain:w300
ArduinoUNO+I2C変換+有機ELキャラクタディスプレイ

有機ELキャラクタディスプレイモジュール

 今回使用するディスプレイは秋月電子で販売している、有機ELキャラクタディスプレイだ。有機EL(OLED)は液晶と異なり、文字の部分が発光するため背景と文字のコントラストが高いため視認性が良いので個人的に好きなディスプレイ。ただし、一般的に液晶よりも高価なので多用はできない。 また、キャラクタディスプレイとは文字を表示させる用途のディスプレイで、1バイトのデータで1文字を表示させることができる。今回のOLEDディスプレイは英数字とカタカナ、簡単な図形の表示ができる。

f:id:kirikoshokunin:20210329222400p:plain:w300
秋月電子有機ELキャラクタディスプレイ

秋月電子通商 トップページ - 電子部品・半導体 【通販・販売】 通販コード[P-08277]

  • 電源電圧 3.3[V]
  • 通信 I2C(3.3[V]レベル)
  • アドレス 0x3C or 0x3D (SA0ピンで選択)
  • 文字数 16文字x2行

I2Cのレベル変換

 ArduinoUNOのI2Cは5[V]レベルなので、3.3[V]レベルのI2Cとの通信はできない。そのため、レベル変換を行う必要がある。今回はレベル変換に秋月電子のI2Cバス用双方向電圧レベル変換モジュールを使用した。このモジュールはDIP8ピンサイズでモジュール内部にプルアップ抵抗があるので、ブレッドボードやユニバーサル基板で使用しやすいのでよく使用する。また、プルアップ抵抗が必要ないときはショートパッドを切断すればよい。

f:id:kirikoshokunin:20210329225248j:plain:w250
I2Cバス用双方向電圧レベル変換モジュール(PCA9306)
通販コード[M-05452]

 ArduinoUNOとレベル変換モジュール、OLEDディスプレイの配線

f:id:kirikoshokunin:20210329215415p:plain
ArduinoUNO+I2C変換+有機ELキャラクタディスプレイ

 ArduinoからOLEDディスプレイに文字表示プログラム

 まず、OLEDディスプレイとの通信にはコマンド通信とデータ通信の2種類がある。コマンド通信は、OLEDの設定に用いる。データ通信は文字データの送信やメモリデータの読み出し等に使う。今回は秋月電子の説明書のサンプルを参考に作成した。

OLEDディスプレイを初期化

文字を表示するためには初期化処理を行う必要がある。それを下に示す。

  delay(100);
  writeCommand(0x28);//RE=0 IS=0
  writeCommand(0x08); // DisplayをOFF
  writeCommand(0x01); // Displayのメモリ全消去
  delay(20);
  writeCommand(0x02); // カーソルをアドレス0x00に移動
  delay(2);
  writeCommand(0x0c); // DisplayをON
  delay(2);
  writeCommand(0x01); // Displayのメモリ全消去
  delay(20);

 コントラスト設定

 次にOLEDの文字の発光強さを設定する必要がある。初期値だと文字が見えにくい。

  contrast = 0xe0;
  writeCommand(0x2a);//RE=1
  writeCommand(0x79);//SD=1
  writeCommand(0x81);//コントラストセット
  writeCommand(contrast);//輝度設定 0~0xff
  writeCommand(0x78);//SD を0にもどす
  writeCommand(0x28); //2C=高文字 28=ノーマル

文字表示先頭位置を設定

 文字を表示するときには文字列の先頭位置を設定する必要がある。キャラクタディスプレイは多くが、表示できる文字数以上に文字列を格納できるので表示される箇所に該当するメモリのアドレスに正しく文字データを入力する必要がある。

  Wire.beginTransmission(0x3D);  //OLEDディスプレイのアドレス
  Wire.write(0x00);        //コマンド送信
  Wire.write(0x20);                  //先頭アドレスを指定 
  Wire.endTransmission();     //I2C通信を終了

 文字列を送信

文字列を送信するために次のような関数を作成した、これは文字列の先頭アドレスを引数としてその文字列の最終文字であるNULL文字が来るまで文字を送信し続けるというものだ。ただし、この関数は誤ってNULLがないデータのアドレスを渡したら永久ループに入るので、本来はカウント上限などで脱出方法を作っておくべきだろう。

void write_string(char* t_data)
{
  int i;
  Wire.beginTransmission(0x3D);
  Wire.write(0x40);     //データ送信
  for(i=0; *(t_data+i) != 0x00;i++){//NULL文字があるまで繰り返す
    Wire.write(*(t_data+i));
  }
  Wire.endTransmission();
  delay(1);
}

スケッチ全体

 上述したプログラムを組み合わせてAD0の電圧をOLEDディスプレイに出力するプログラムを記述した。stdio.hのsprintfを用いることで、容易に変数を文字列に変換することができる。ただし、stdioの多くは処理量が多いので多用しない方が良い。

実行した動画

 上のスケッチを実行した動画をしたに示す。リアルタイムでAD0の値がOLEDディスプレイに表示されていることがわかる。


ArduinoUNO+OLEDキャラクタディスプレイ