2013年08月08日追記:従来「グラフィックLCDシールド」と呼んでいたシールドを、「122X32モノクログラフィックLCDシールド」と改称させていただきました。これは、現在他の解像度のグラフィックLCDシールドを開発する計画をしているからです。本文中は従来どおり「グラフィックLCDシールド」との表記になっていますが、「122X32モノクログラフィックLCDシールド」とお読み替えください。また、このシールドの改良版がスイッチサイエンスで発売中です。発売されている製品の詳細については、製品ユーザサポートページをご覧ください。
350円の格安グラフィックLCDモジュールのS12232ZAが動作するようになったのはいいのですが、そのままではArduinoのI/Oピンを13本も使ってしまいます。I/Oピンが元々20ピンしかないArduino Unoの場合、大半のI/OピンはLCDの制御に使ってしまいます。そこで、制御用のマイコンチップを載せ、Arduinoとはシリアル通信をすることで、0番ピン(RX)と1番ピン(TX)の2ピン(もしくはソフトウェアシリアルを使う場合は、任意の2ピン)しか使用しないグラフィックLCDシールドを製作しました。グラフィック描画用のMGLCDライブラリというライブラリもあるので、このシールドを使うと、Arduinoで簡単にグラフィック表示ができるようになります。
Arduinoの余っている2ピンを使用することで簡単にLCDの制御ができるので、プロトタイピングの時間を大幅に削減することができると思います。また、LCD制御用のソフトはシールド側に載っているので、Arduinoのフラッシュメモリを節約できます。
図1がグラフィックLCDシールドの構成図です。
LCDとしては、122×32ピクセルのモノクロLCD、S12232ZAを採用しています。このLCDにはバックライトはありません。
LCDの制御用、およびシリアル通信制御用として、ワンチップマイコンATmega328P(Arduino Unoに内蔵しているのと同一のマイコン)を載せています。このマイコンが、Arduinoからシリアル通信で送られてくる描画コマンドを解釈し、LCDを描画制御することで、RXとTXの2つの信号線のみでのグラフィック描画を実現しています。
ATmega328Pには、16MHzの水晶振動子が付いており、Arduino Unoと同じ、16MHzで動作します。
ATmega328Pには、LCDの他にも4つのプッシュスイッチ(タクトスイッチ)と1つのLEDが繋がっています。プッシュスイッチの状態の取得や、LEDの制御も、シリアルインターフェース経由で行いますので、ArduinoのI/Oピンを消費しません。
S12232ZAは、コントラスト調整に負電圧が必要ですが、その負電圧発生回路も、シールドに内蔵しています。
INT/EXTの切り替えスイッチは、Arduinoとハードウェアシリアルで通信するか(INT)、ソフトウェアシリアル(EXT)で通信するかを選択するスイッチです。
Arduino側がハードウェアシリアルで描画コマンドを出す場合は、I/Oピンが0番ピン(RX)と1番ピン(TX)に決まっています。その場合はSW5をINT側に切り替えます。そうすると、ATmega 328Pのシリアル通信のピン(TXとRX)が、Arduinoの0番ピンと1番ピンに接続されます。
Arduino側がソフトウェアシリアルで描画コマンドを出す場合は、スケッチ次第で、ソフトウェアシリアルに対応している任意のI/Oピンにシリアル信号を割当てられます。その場合はSW5をEXT側に切り替えます。そうすると、ATmega328PのRXとTXの信号線がCN2に接続されます。ブレッドボード用のジャンパ線で、CN2とソフトウェアシリアルの信号線を、下の写真のように接続します。(写真の例では、Arduinoの2番ピンをRX、3番ピンをTXとしている)
現在はArduino UnoとArduino MEGA 2560にしか対応していませんが、レベル変換回路を追加すれば、3.3V系のマイコン(Arduino DueやGR-SAKURAなど)に接続することができます。またUSBシリアルインターフェースを使えばパソコンのUSB端子から制御することもできます。他のマイコンやパソコンに対応したライブラリも順次開発する予定です。
シールドに内蔵しているATmega328Pには、Arduino Unoのブートローダーを書き込んであります。Arduino IDEとUSBシリアルインターフェースを使うことで、簡単にファームウェアをアップデートできます。
回路図やライブラリなどの詳細な情報は後で紹介するとして、まず、グラフィックLCDシールドの使い方をご紹介します。(回路図を先に見たい方は、こちらをクリックしてください。)
下の2枚の写真のように、シールドの裏側にはArduinoに接続するピンヘッダがあり、シールドの表側には同じ位置にピンソケットがあります。
ほとんどのピンは、ただ単に裏側のピンヘッダを表側のピンソケットに中継しているだけです。しかし、SW5をINT側に切り替えるとArduinoの0番ピンと1番ピンがシールド内蔵のマイコンと接続され、シリアル接続のLCDとして動作します。
なお、0番ピンと1番ピンに内部接続するという意味で、INT(0,1)とシルク表示したかったのですが、基板設計の時にあわてていたのか、INT(1,2)になってしまっています。(^^; 恐ろしいことに、他にも色々間違いが見つかって、基板を作り直す羽目になったのですが、その話は後ほど…。
ただ単にLCDに文字を表示したいだけなら、特別なライブラリを使わずに、このシールドを1行20文字、4行のターミナルとして利用できます。(グラフィック表示の方法は後に述べます)
例として、1から10までの文字を1秒間隔で表示するスケッチを以下に示します。
void setup()
{
Serial.begin(1200);
delay(5000);
for(int i=1; i<=10; i++) {
Serial.println(i);
delay(1000);
}
}
void loop()
{
}
この例を見ると分かるように、Arduino IDEのシリアルモニタやハイパーターミナル、Tera Termなどを使って、パソコンのシリアルポート経由で1200bpsで文字を表示するのと全く同じスケッチになります。このように、このシールドは、1200bpsのターミナルとしても働きます。1200bpsと、通信速度が遅めに設定してあるのは、フロー制御なしでも文字を取りこぼさないようにとの配慮です。
スケッチをArduinoに書き込む場合は、いったんSW5をEXTに切り替えてからスケッチを書き込み、5秒以内(delay(5000)の実行している間)にSW5をINTに切り替えます。Arduinoは、スケッチの書き込みに0番ピンと1番ピンを使いますので、いったんグラフィックLCDシールドを0番ピンと1番ピンから切り離さないとスケッチの書き込みができません。そのために、スケッチ書き込み時だけSW5をEXTに切り替える必要があります。
上記のスケッチを書き込み、LCDに1~10の数字を表示する手順を動画で紹介します。
Arduinoの0番ピンと1番ピンを、LCD制御以外の事に使いたいなら、ソフトウェアシリアルを使えば、他のピンでLCD制御をできます。次の例は2番ピンをRX、3番ピンをTXとする場合のスケッチです。(これはArduino Unoの例です。Arduino Mega 2560では、2番ピンはRXとして使えないので、10番ピンなど、RXに対応したピンをお使いください。)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX:2番ピン TX:3番ピン
void setup()
{
mySerial.begin(1200);
//delay(5000);
for(int i=1; i<=10; i++) {
mySerial.println(i);
delay(1000);
}
}
void loop()
{
}
このスケッチを書き込む前に、まずSW5をEXT側に切り替えて、ソフトウェアシリアルを使うモードにします。そうすると、ArduinoとグラフィックLCDシールドの信号線は切り離され、CN2のピンソケットにシリアル信号線を繋ぐ形となります。
本当は、CN2から外部に接続するという意味で、EXT(CN2)というシルク表示にしたかったのですが、あわてんぼうの私は、何を血迷ったかEXT(CH2)と意味不明の事を書いています。(^^;
次にCN2のピンソケットを、ソフトウェアシリアルで使う2本のピンと、ブレッドボード用のジャンパ線で繋ぎます。
スケッチの方で、2番ピンをRX、3番ピンをTXと指定しているため、CN2のto RXと書いてある方のピンを2番ピンに、to TXと書いてある方のピンを3番ピンに接続します。
この状態でArduinoにスケッチを書き込むと、数字を表示し始めます。スケッチの書き込みに使う0番ピンと1番ピンを外して使っているので、スケッチの書き込みの際にSW5を切り替えるという面倒な事はありません。よって、スイッチの切り替えの時間を稼ぐためのdelay(5000);
をmySerial.begin(1200);
の次の行から削除しています。
他のピンでソフトウェアシリアルを使いたい場合は、スケッチのSoftwareSerial mySerial(2, 3); // RX:2番ピン TX:3番ピン
の行を、自分の使いたいピンに合わせて書き直します。また、CN2に繋ぐピンも、スケッチに合わせて変えてください。
たとえ4行とはいえ、LCDの表示がArduinoのすぐそばで行えるのはありがたいです。Arduino IDEは、ブレークポイントとかトレース実行などのデバッグ機能を持たないため、いわゆるprintfデバッグをする事が多くなるのですが、表示結果がパソコンの画面に出ると、Arduinoとパソコンの画面の間を、視線が行ったり来たりするために、疲れてしまいます。そんな時は、このシールドを使うとデバッグが楽になります。
また、低消費電力にできているので、簡単に電池駆動できるのも便利です。
グラフィックLCDシールドの簡単な応用例として、ArduinoのanalogRead関数で読み込んだA/D変換結果を、LCDに表示する方法を紹介します。A/D変換器に入力する電圧源として、今回は半固定抵抗(あるいは可変抵抗)の分圧回路を使うことにします。
電源電圧の5Vを、半固定抵抗で0~5Vの範囲の任意の電圧に分圧して、A0端子に入力します。そのために、図2のように、1番端子をGNDに、2番端子をA0ピンに、3番端子を5Vにつなぎます。抵抗値は、5kΩでも、20kΩでも、50kΩでも良かったのですが、キリのいい10kΩを使いました。
今回は写真撮影する際にシールドと半固定抵抗が同一フレームに収まりやすいという理由から、次の写真のような半固定抵抗を使いました。しかし、Arduinoに接続するには、簡単な基板加工が必要です。また、抵抗値を変えるのに、ドライバーを使う必要があります。皆さんが自分で実験する場合は、こちらで売られているような、可変抵抗を使えば、基板やドライバーは不要で、実験がし易いでしょう。
上の写真の状態では半固定抵抗の端子がピンソケットに刺さりませんから、次の写真のように加工しました。
この半固定抵抗を、グラフィックLCDシールドのピンソケットに差し込んで、5V、GND、A0の各線に接続します。
このように接続すれば、半固定抵抗を左に回しきれば0V、右に回しきれば5Vの電圧がA0に印加されます。Arduino UnoのA/D変換器は、5Vがフルスケールの10ビットA/D変換器なので、半固定抵抗を左に回しきれば0、右に回しきれば1023を出力します。この様子をグラフィックLCDシールドで観察してみましょう。
今回はRXが7番ピン、TXが8番ピンのソフトウェアシリアルでArduinoとグラフィックLCDシールドを接続することにします。下の写真のようにジャンパ線を配線します。(これはArduino Unoの例です。Arduino Mega 2560では、7番ピンはRXとして使えないので、10番ピンなど、RXに対応したピンをお使いください。)
そしてSW5をEXT側に切り替えて、次のスケッチをArduino Unoに書き込みます。
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8); // RX:7番ピン TX:8番ピン
void setup()
{
// ソフトウェアシリアルの初期化
mySerial.begin(1200);
}
void loop()
{
// A/D変換値(0~1023)の取得
int val=analogRead(A0);
// バーグラフの表示
for(int i=0; i<=15; i++) {
if(i<(val*15+512)/1024) {
mySerial.print('*');
} else {
mySerial.print(' ');
}
}
// A/D変換値の表示
mySerial.println(analogRead(A0));
}
そうすると、次のビデオのようにA/D変換値を簡易バーグラフと数字で表示します。
次のページでは、グラフィック表示用ライブラリの使い方について説明します。