ArduinoでグラフィックLCDを動かす(AQM1248A編)(14)

このページをスマートフォンなどでご覧になる場合は、画面を横長にする方が読みやすくなる事があります。
目次へ  前のページへ (9) (10) (11) (12) (13) (14) (15) (16) (17) 次のページへ
2016年05月23日 公開。

5-4.ヘッダファイルのインクルード

MGLCDライブラリを使ってスケッチを作る場合に必要なヘッダファイルの、インクルード方法について説明します。

5-4-1.ハードウェアSPI接続の場合

ハードウェアSPI接続の場合は、MGLCD.h、MGLCD_SPI.hおよびSPI.hのインクルードが必要になります。スケッチの先頭で、リスト28の様に、これらのファイルをインクルードしてください。

リスト28、MGLCDライブラリを用いる場合に必要になるヘッダファイルのインクルード部分(ハードウェアSPI接続)COPY
#include <MGLCD.h>
#include <MGLCD_SPI.h>
#include <SPI.h>

5-4-2.ソフトウェアSPI接続の場合

ソフトウェアSPI接続の場合は、インクルードする必要のあるヘッダファイルはMGLCD.hのみです。スケッチの先頭で、リスト29の様に、MGLCD.hをインクルードしてください。

リスト29、MGLCDライブラリを用いる場合に必要になるヘッダファイルのインクルード部分(ハードウェアSPI接続)COPY
#include <MGLCD.h>

5-5.オブジェクト変数の宣言

MGLCDライブラリを用いてAQM1248Aを制御するには、そのためのオブジェクト変数を宣言する必要があります。

これは、キャラクタLCDモジュール用のLiquidCrystalライブラリを使用する際に、LiquidCrystal型のオブジェクト変数(通常はlcdという変数名にする)を、リスト30の様に宣言するのと同じです。

リスト30、(参考)LiquidCrystalライブラリを利用する場合のLiquidCrystal型のオブジェクト変数の宣言の例COPY
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

オブジェクト変数の宣言の仕方は、ハードウェアSPI接続の場合とソフトウェアSPI接続の場合で異なります。

5-5-1.ハードウェアSPI接続の場合

ハードウェアSPI接続の場合は、リスト31の様に、オブジェクト変数を宣言します。

リスト31、オブジェクト変数の宣言(ハードウェアSPI接続)COPY
#define CS_PIN 10
#define DI_PIN  9
#define MAX_FREQ (1000*1000L)

MGLCD_AQM1248A_SPI MGLCD(MGLCD_SpiPin2(CS_PIN, DI_PIN), MAX_FREQ);

MGLCD_AQM1248A_SPIというのが、オブジェクト変数の型(クラス)です。

その後のMGLCDが変数名で、その後に、括弧付きで2つの引数が続きます。

1つ目の引数の、MGLCD_SpiPin2(CS_PIN, DI_PIN)がピン接続を指定しています。

MGLCD_SpiPin2というのは、ピン接続の指定に必要なオブジェクトの型(クラス)ですが、単にこういう表記をすると理解してくださっても構いません。

MGLCD_SpiPin2の2つの引数のCS_PINとDI_PINは、それぞれ/CS信号とRS信号をArduinoのどのピンに接続するかを表しています。

リスト31の場合は

#define CS_PIN 10
#define DI_PIN  9

で、CS_PINとDI_PINを、それぞれ10と9に宣言していますので、この場合は/CS信号を10番ピン、RS信号を9番ピンに接続する事を表しています。(前のページに掲載した図12、図32、図35、図38、および図6のいずれの配線図でも、/CS信号は10番ピン、RS信号は9番ピンに接続してる事に注意)

もし/CS信号とRS信号を別のピンにつなぎたければ、CS_PINとDI_PINの2つの定数の値を書き換えればいい事になります。

MGLCDの2つ目の引数のMAX_FREQは、SPIバスのクロック周波数を表しています。

リスト31では

#define MAX_FREQ (1000*1000L)

と、MAX_FREQを100万(1000×1000)に設定していますので、この場合、SPIバスのクロック周波数を1MHzに設定している事になります。(1MHzは100万Hz)

もちろん

#define MAX_FREQ 1000000L

と、MAX_FREQに直接1000000Lを指定しても構いませんが、0が連続して続くと桁数を間違う恐れがあるので、(1000*1000L)と表記する方が、間違いが少ない表記法だと言えるでしょう。

注:数字の後ろにLが付くのは、long型の定数を表しています。8ビットのArduinoの場合、Lを付けずに(1000*1000)とすると、1000*1000の計算結果(100万)がint型の範囲(-32768~32767)を超えてしまうために、正しくスケッチが動作しません。LまたはUL(unsigned long型定数)を掛け算の少なくとも一方の数に指定する必要があります。32ビットのArduinoの場合はこの様な問題は発生しませんが、8ビットArduinoとのスケッチの互換性を考えるなら、やはりUまたはULを付けるべきです。

なお、SPIバスのクロック周波数は、どの様な周波数にでも設定できるわけではありません。

8ビットのArduinoの場合は、SPIクロック周波数をCPUのクロック周波数の2N分の1(Nは1以上の整数)にしか設定できません。例えばArduino UnoのCPUクロック周波数は16MHzなので、設定できるSPIクロック周波数は8MHz、4MHz、2MHz、…となります。

また32ビットのArduinoの場合は、SPIクロック周波数をCPUクロック周波数のN+1分の1(Nは1以上の整数)にしか設定できません。例えばArduino M0のCPUクロック周波数は48MHzなので、設定できるSPIクロック周波数は24MHz、16MHz、12MHz、…となります。

MAX_FREQに、Arduinoが設定不能なSPIクロック周波数を指定すると、MAX_FREQを超えない範囲で最も高い、設定可能なSPIクロック周波数に設定されます。例えばArduino UnoでMAX_FREQを(5000*1000L)(5MHz)にすると、SPIクロック周波数は4MHzに設定されます。

なお、リスト31では#defineで定数の定義を行ったために、オブジェクト変数の宣言が4行になりましたが、#defineを使わずにリスト32の様に1行に書くこともできます。この場合、スケッチは短くなりますが、若干可読性が低下します(スケッチの意味が理解しにくくなります)。

リスト32、リスト31のオブジェクト変数の宣言を1行に書き直した例COPY
MGLCD_AQM1248A_SPI MGLCD(MGLCD_SpiPin2(10, 9), (1000*1000L));

5-5-2.ソフトウェアSPI接続の場合

ソフトウェアSPI接続の場合は、リスト33の様に、オブジェクト変数を宣言します。

リスト33、オブジェクト変数の宣言(ソフトウェアSPI接続)COPY
#define SCK_PIN  13
#define MOSI_PIN 11
#define CS_PIN   10
#define DI_PIN    9
#define WAIT      0

MGLCD_AQM1248A_SoftwareSPI MGLCD(MGLCD_SpiPin4(SCK_PIN, MOSI_PIN, CS_PIN, DI_PIN),WAIT);

MGLCD_AQM1248A_SoftwareSPIというのが、オブジェクト変数の型(クラス)です。

その後のMGLCDが変数名で、その後に、括弧付きで2つの引数が続きます。

1つ目の引数の、MGLCD_SpiPin4(SCK_PIN, MOSI_PIN, CS_PIN, DI_PIN)が、ピン接続を指定しています。

MGLCD_SpiPin4というのは、ピン接続の指定に必要なオブジェクトの型(クラス)ですが、単にこういう表記をすると理解してくださっても構いません。

MGLCD_SpiPin4の4つの引数SCK_PIN、MOSI_PIN、CS_PIN、およびDI_PINは、それぞれSCK信号(SCLK信号)、MOSI信号(SDI信号)、/CS信号、RS信号を、Arduinoのどのピンに接続するかを表しています。

リスト33の場合は

#define SCK_PIN  13
#define MOSI_PIN 11
#define CS_PIN   10
#define DI_PIN    9

で、SCK_PIN、MOSI_PIN、CS_PIN、およびDI_PINを、それぞれ13、11、10、9と宣言していますから、SCLK信号を13番ピン、SDI信号を11番ピン、/CS信号を10番ピン、RS信号を9番ピンに、それぞれ接続する事を表しています。(前のページに掲載した図13、図33、図36、図39、および図7のいずれの配線図でも、SCLK信号は13番ピン、SDI信号は11番ピン、/CS信号は10番ピン、RS信号をは9番ピンに接続している事に注意)

使用するArduinoのピンを変更したい場合は、これらの定数宣言を変更すればいい事になります。

MGLCDの2つ目の引数のWAITは、アクセス速度の調整に使うウェイト値で、通常は0を指定します。

例えばAQM1248AとArduinoの間に使用するレベル変換回路の動作が遅いなど、何らかの事情でアクセス速度を遅くしたい場合は、WAITの値を1以上に設定します。その場合は、

#define WAIT      0

の部分を書き換えてください。

注:同じArduinoでスケッチを使用する場合に限り、ウェイト値が大きいほどアクセスが遅くなる事が保証されます。Arduinoの種類が変わると、同じウェイト値でもウェイトのかかり方に差が出ますので、例えばArduino UnoでWAIT=1にした場合より、Arduino DueでWAIT=2にした場合の方が速いといった事は起こり得ます。複数の機種で同じスケッチを使う事を想定する場合は、十分なウェイト値を設定したり、ハードウェアSPI接続に変更するなどの配慮が必要です。

リスト33は、#defineによる定数宣言を使わずに書くと、リスト34の様に1行に書き直せます。ただしこの場合は、若干可読性が低下します。

リスト34、リスト33のオブジェクト変数の宣言を1行に書き直した例COPY
MGLCD_AQM1248A_SoftwareSPI MGLCD(MGLCD_SpiPin4(13, 11, 10, 9), 0);

5-5-3.変数名について

リスト31およびリスト33では、

MGLCD_AQM1248A_SPI MGLCD(MGLCD_SpiPin2(CS_PIN, DI_PIN), MAX_FREQ);

あるいは

MGLCD_AQM1248A_SoftwareSPI MGLCD(MGLCD_SpiPin4(SCK_PIN, MOSI_PIN, CS_PIN, DI_PIN),WAIT);

と、MGLCDという変数名のオブジェクト変数を宣言しました。

この宣言により、MGLCDという変数を使って、例えば

MGLCD.print("Hello, World!");

と、AQM1248Aにアクセスする事ができます。

print関数LiquidCrystalライブラリの場合と同様に、引数の内容を画面に表示しますから、この例では画面に"Hello, World!"の文字列を表示する事になります。

変数名は必ずしもMGLCDにしなければならない訳ではありません。例えば変数名をhogeにしたい場合は、

MGLCD_AQM1248A_SPI hoge(MGLCD_SpiPin2(CS_PIN, DI_PIN), MAX_FREQ);

あるいは

MGLCD_AQM1248A_SoftwareSPI hoge(MGLCD_SpiPin4(SCK_PIN, MOSI_PIN, CS_PIN, DI_PIN),WAIT);

と宣言してください。

この場合、画面に"Hello, World!"を表示したいなら、

hoge.print("Hello, World!");

とします。

これ以降の説明では、便宜上、MGLCDの変数名でオブジェクト変数の宣言を行ったものとして説明します。

広告

5-6.AQM1248Aの初期化方法

画面に何かを表示する前に、AQM1248Aを初期化する必要があります。初期化はリスト35の様にすれば行えます。

リスト35、AQM1248Aの初期化COPY
MGLCD.Reset();

注:ハードウェアSPI接続の場合も、ソフトウェアSPI接続の場合も、初期化方法は同じです。Reset関数の呼び出しに限らず、ヘッダファイルのインクルードとオブジェクト変数の宣言の部分を除いては、ハードウェアSPI接でも、ソフトウェアSPI接続でも、スケッチは共通です。

Reset関数による初期化は、表示を始める前に1度だけ実行すればいいので、通常はsetup関数内で行います。

122X32モノクログラフィックLCDシールドなどとの互換性を考える場合は、リスト36の様にします。

リスト36、他のLCDモジュールとのスケッチの互換性を考慮した初期化方法COPY
while(MGLCD.Reset());

注:Reset関数には返り値があり、初期化に成功すると0、失敗すると負の値を返します。122X32モノクログラフィックLCDシールドなどでは初期化に失敗する事はありますが、AQM1248Aの場合は必ず初期化に成功しますので、Reset関数は必ず0を返します。AQM1248Aの場合は、リスト35を実行するのとリスト36を実行するのは、実質的には同じ意味になりますが、122X32モノクログラフィックLCDシールドの場合は、リスト35では正常に初期化できない事があります。

5-7.スケッチのテンプレート

ヘッダファイルのインクルード、オブジェクト変数の宣言、AQM1248Aの初期化と順に説明してきましたが、これらはいずれもAQM1248AをMGLCDライブラリで用いる際には必要な記述事項になります。そこで、これらをすべてまとめて、テンプレートにしました。

5-7-1.ハードウェアSPI接続の場合

ハードウェアSPI接続の場合は、リスト37のテンプレートをお使いください。

リスト37、MGLCDライブラリを使用するスケッチのテンプレート(ハードウェアSPI接続)COPY
// ヘッダファイルのインクルード
#include <MGLCD.h>
#include <MGLCD_SPI.h>
#include <SPI.h>

// ピン割り当てとSPIクロック周波数の宣言
#define CS_PIN 10
#define DI_PIN  9
#define MAX_FREQ (1000*1000L)

// オブジェクト変数の宣言
MGLCD_AQM1248A_SPI MGLCD(MGLCD_SpiPin2(CS_PIN, DI_PIN), MAX_FREQ);

void setup() {
  // AQM1248Aの初期化
  MGLCD.Reset();

}

void loop() {

}

5-7-2.ソフトウェアSPI接続の場合

ソフトウェアSPI接続の場合は、リスト38のテンプレートをお使いください。

リスト38、MGLCDライブラリを使用するスケッチのテンプレート(ウェアSPI接続)COPY
// ヘッダファイルのインクルード
#include <MGLCD.h>

// ピン割り当てとウェイト値の宣言
#define SCK_PIN  13
#define MOSI_PIN 11
#define CS_PIN   10
#define DI_PIN    9
#define WAIT      0

// オブジェクト変数の宣言
MGLCD_AQM1248A_SoftwareSPI MGLCD(MGLCD_SpiPin4(SCK_PIN, MOSI_PIN, CS_PIN, DI_PIN),WAIT);

void setup() {
  // AQM1248Aの初期化
  MGLCD.Reset();

}

void loop() {

}

リスト37にせよ、リスト38にせよ、

  MGLCD.Reset();

の次の行に

  MGLCD.print("Hello, World!");

を追加すると、前のページで紹介した"Hello, World!"を表示するスケッチになります。(リスト26およびリスト27)

次のページでは、MGLCDライブラリのテキスト表示関数について説明します。

目次へ  前のページへ (9) (10) (11) (12) (13) (14) (15) (16) (17) 次のページへ

このページで使われている用語の解説

関連ページ

関連製品

122X32モノクログラフィックLCDシールド 商品名 122X32モノクログラフィックLCDシールド
税抜き小売価格 3333円
販売店 スイッチサイエンス
サポートページ
GLCD学習シールドキット 商品名 GLCD学習シールドキット
税抜き小売価格 1410円
販売店 スイッチサイエンス
サポートページ
PCBgogoのバナー
Arduino 電子工作
このサイトの記事が本になりました
ISBN:978-4-7775-1941-5
工学社の書籍の内容の紹介ページ
本のカバーの写真か書名をクリックすると、Amazonの書籍購入ページに移動します。
電子工作で学ぶ論理回路入門
このサイトの中の人が書いた本です。
ISBN:978-4-7775-2280-4
工学社の書籍の内容の紹介ページ
この本の紹介記事
本のカバーの写真か書名をクリックすると、Amazonの書籍購入ページに移動します。