google-site-verification: google3bd66dd162ef54c7.html

ArduinoでI2Cキャラクタ液晶を使う(その3) 最終動作確認

 ArduinoからI2Cインターフェイスのキャラクタ液晶を使う話の最終回です。前回の記事で選んだI2Cキャラクタ液晶表示ライブラリの I2CLiquidCrystal (N. Mitsunagaさん) を使って実際に表示を行ってみます。なお、このライブラリにはいろいろなサンプルが入っているのでデモプログラムには事欠かないのですが、私が特に気にしている lcd.setCursor と lcd.print について自作のテストプログラムを動かしてみます。と言っても以前作ったものをちょっと手直ししただけのものです。

 プログラム自体の説明は後回しにして、表示結果は以下の写真の通りです。なお、接続回路図は、以前の記事に掲載したものと同じです。また、ライブラリのバージョンは I2CLiquidCrystal-1.5.zip を使いました。

▼実行結果
Arduino UNOの電源電圧
 CPUチップの温度と電源電圧を連続表示します。うまくいっているようです。

 なお、CPU温度の測定精度はかなり怪しくて大きなオフセットを伴っています。つまりこの表示の絶対精度はあてになりません。但し、分解能は高くて 0.1度あるので、CPUを指で触ると温度がどんどん上がることが判ります。

▼プログラム
/* CPU温度センサーと電源電圧の読み出し、表示デモ
初版 2014/7/19
改版 2017/06/11 I2C液晶用に修正 ラジオペンチ
http://radiopench.blog96.fc2.com/
*/
#include <I2CLiquidCrystal.h> // http://n.mtng.org/ele/arduino/i2c.html
#include <Wire.h>

I2CLiquidCrystal lcd(20, true); // コントラスト(0-63),液晶電源(true=5V, false=3.3V)

void setup() {
pinMode(13, OUTPUT);
lcd.begin(16, 2);
lcd.print("Starting...");
delay(1000);
Serial.begin(9600);
}

void loop() {
float temp, Vcc;
digitalWrite(13, HIGH);
temp = cpuTemp(); // CPU温度測定
Vcc = cpuVcc(); // 電源電圧測定
digitalWrite(13, LOW);

Serial.print("Temp= "); // シリアルに温度を出力
Serial.print(temp,1);
Serial.print(", Vcc= "); // シリアルにVccを出力
Serial.println(Vcc,2);

lcd.setCursor(0, 0); // 液晶に表示
lcd.print("Temp= ");
lcd.print(temp,1); // 温度、小数点以下1桁表示
lcd.print("c "); // 単位表示と後ろのゴミ消し
lcd.setCursor(0, 1);
lcd.print("Vcc = "); // Vcc
lcd.print(Vcc,2);
lcd.print("V "); // 単位表示と後ろのゴミ消し

delay(500);
}

// 流用する場合は以下を全てコピーする

float cpuTemp(){ // CPU温度測定関数
long sum=0;
adcSetup(0xC8); // Vref=1.1V, input=ch8
for(int n=0; n < 100; n++){
sum = sum + adc(); // adcの値を読んで積分
}
return (sum * 1.1/102.4)- 342.5; // 温度を計算して戻り値にする。-342.5は要調整
}

float cpuVcc(){ // 電源電圧(AVCC)測定関数
long sum=0;
adcSetup(0x4E); // Vref=AVcc, input=internal1.1V
for(int n=0; n < 10; n++){
sum = sum + adc(); // adcの値を読んで積分
}
return (1.1 * 10240.0)/ sum; // 電圧を計算して戻り値にする
}

void adcSetup(byte data){ // ADコンバーターの設定
ADMUX = data; // ADC Multiplexer Select Reg.
ADCSRA |= ( 1 << ADEN); // ADC イネーブル
ADCSRA |= 0x07; // AD変換クロック CK/128
delay(10); // 安定するまで待つ
}

unsigned int adc(){ // ADCの値を読む
unsigned int dL, dH;
ADCSRA |= ( 1 << ADSC); // AD変換開始
while(ADCSRA & ( 1 << ADSC) ){ // 変換完了待ち
}
dL = ADCL; // LSB側読み出し
dH = ADCH; // MSB側
return dL | (dH << 8); // 10ビットに合成した値を返す
}
 このプログラムはかなり前に書いた「外付け部品無しでArduinoの電源電圧を測定する」という記事に掲載したもので、インクルードするライブラリを入れ替えて、初期化の設定を修正しただけです。動作としては、CPUの電源電圧と温度を連続表示します。43行以降が測定ルーチンですが、このプログラムはCPUのレジスタを設定するだけで動いています。つまり外部の配線は何もしなくていいので、今回のように、ちょっとした動作確認をしたい時に使うと便利です。

 33行で温度を小数点以下1桁、37行で電圧を小数点以下2桁表示するように指定しています。こういうふうに表示フォーマットを指定出来るとプログラム作りが楽になります。

◆まとめ
 ということでうまく表示が出来るようになったので、I2Cインターフェイスのキャラクタ液晶を動かすライブラリの話は終わりです。I2Cインターフェースは少ないピン数で表示が出来るので便利になるはずです。

 あと、この後はこの液晶を使って日の出日の入りタイマーを作る予定です。そちらは進展があったら記事にする予定です。

ArduinoでI2Cキャラクタ液晶を使う(その2) ライブラリの選定

 ArduinoからI2Cインターフェイスのキャラクタ液晶を使う話の続きです。前回の記事で基本的な接続は確認出来たので、今回はライブラリを使って動かしてみます。実は、以前ライブラリの使用を試みたことがあるのですが、うまくいかなくて途中で断念しました。ライブラリを使わなくてもプログラムを頑張れば表示は出来ますが、いつもそんな面倒なことはやってられません。

▼回路図
AQM1602XA-RN-GBWとArduinoの接続図
 テストの前提条件は上の回路図で動くことです(I2Cバスは変換基板上でプルアップされています)。つまり、Arduino UNO に秋月のI2C接続キャラクタ液晶(AQM1602XA-RN-GBW)を接続して動かすことが目標です。たぶんこれ、現時点では一番多い使い方だと思います。なお、この回路では液晶の電源電圧とI2Cバスの信号レベルは共に5Vです。後の記事に出てきますが、この電圧条件をクリア出来ないライブラリがいくつかありました。

▼テストの様子
動作確認中
 I2Cのバスの信号を見ながらテストしました。

 ネットを検索してArduino で使えそうな I2C液晶のライブラリを探して、Arduino IDEに登録しました。ライブラリを登録すると、下の図のようにスケッチ例が出るようになるので、これを動かしてみれば正常に動くかどうか簡単に調べることが出来ます。なお、登録したライブラリが使えなかった場合は単にそのファイルを消すだけで済むはずで、後遺症は残らないと思います(たぶん)。

▼ライブラリに登録した様子
サンプルプログラム

 上を拡大したのが下の画面です。

▼今回登録したI2C液晶表示ライブラリ
登録したライブラリ
 今回、I2Cキャラクタ液晶用のライブラリとして、上記赤枠内の5種類のライブラリを登録しました。

 以下、この画面に出ている順にテスト結果をレポートしていきます。

1.I2CLiquidCrystal Noriaki Mitsunaga さん
 このライブラリでいきなりこの記事の結論が出てしまいました、このライブラリは使えます。このライブラリを使うと、lcd.setCursorとか、lcd.Print などパラレル液晶でおなじみのコマンドが使えます。それに何の修正も不要です。これこそ私が求めていたライブラリです。

 少しだけ説明を加えたいと思います。 このライブラリは初期化ルーチンでいろいろなメーカーのLCDが選べるようになっています。今回私が探していたのは上の回路図に書いたように秋月で売られているLCD用のライブラリですが、それはこのライブラリのデフォルトで指定されている Straberry Linux の定義がそのまま使えました。昔はストリナで売ってたけど今では秋月でも取り扱うようになったということなんでしょう。

 もう少し細かく説明すると、下記ルーチンで

// initialize the library
// uncomment next line if you are using a LCD from Straberry Linux
I2CLiquidCrystal lcd(20, (bool)true);
// | +--- set true if the power suply is 5V, false if it is 3.3V
// +-------- contrast (0-63)
 I2CLiquidCrystal lcd(20, (bool)true); となっているものを I2CLiquidCrystal lcd(20, (bool)false); とすれば電源電圧3.3V用の設定(Voltage Boosterが動く)となりますが、今回は5Vで使うのでこのままで大丈夫です。このあたりは作者の方のWebに詳しい説明があるのでそちらを見た方が判り易いです。

 なお、電源電圧指定の引数に論理値のキャスト(bool)が入っていますが、これは省略して下記のように書いてもかまわないと思います。 true という変数名は論理変数の真を表す予約語なのでキャストで明記する必要は無いと思うのですが、何か深い理由があるのかも知れません。
I2CLiquidCrystal lcd(20, true); 

2.LiquidCrystal_I2C fdebrabander さん@gitHub
 これ、gitHubに登録されていたものです。試してみたのですが全く動きませんでした。プログラムを見るとI2Cアドレスが0x27となっているので、全く別のメーカーの液晶用のライブラリのようです。なお、gitHub内の説明資料やプログラムの中も見たのですが液晶の型格が特定出来るような情報はありませんでした。名前だけで判断してはダメということですね。

3.skI2CLCDlib きむ茶工房さん
 きむ茶工房さんのwebには役に立つ情報がいっぱいあって、以前からお世話になっています。このライブラリでは液晶モジュールの電圧設定がデフォルトでは3Vになっているのでこれを下記のように修正して5Vに変更する必要があります。なおこのあたりは作者のWebに詳しく書かれています。
     // ICON OFF,コントラスト(0-63),VDD=3.3Vで使う
// LCD.Init(LCD_NOT_ICON,32,LCD_VDD3V) ;
LCD.Init(LCD_NOT_ICON,32,LCD_VDD5V) ;
 これでライブラリとしては正常に動くようになります。ただ残念なことに、文字表示の関数としてLCD.putc( )と LCD.puts( )くらいしか用意されていないようで、肝心のlcd.print( ) がありません。これではArduinoの文化で育った私は困ってしまいます(すみません)。たぶんPIC使いの方なら大丈夫なんでしょう。

 あと、きむ茶工房さんのサイトにこのキャラクタ液晶の昇圧回路について繰り返し注意が書かれています。これは自分も気にしていた点ですが、私と同じ見解が書かれていたので安心しました。

 それと、ライブラリの名前が skI2CLCDlib となっていて、先頭にsk という文字が入っているのは私の好きな作法です。このあたりの話は記事の後ろの方でまとめて触れたいと思います。

4.ST7032 オレ工房さん
 このライブラリはとても良く出来ていて必要な関数は全て揃っています。もちろん lcd.print もあります。スケッチ例もたくさん揃っていて親切な作りになっています。

 ただ残念なことに 昇圧回路が常にONになっていてライブラリからOFFにすることが出来ません。つまり液晶の電源電圧が3.3Vの場合しか使えません。Arduino UNOには3.3V電源を供給するピンがあるので、ここから液晶に電源を供給すればとりあえず動くとは思います。でも信号のレベルが合わないので I2Cバスのノイズマージンが確保出来ません。ということで、この使い方はお勧め出来ません。

 ということで私の結論は、このライブラリは使えない、ということになります。 あと、ライブラリの名称がドライバチップの名前のまま(ST7032)になっているのは、私としてはちょっと気になる点です。

5.wI2cLcdACN1602 エレキジャック、nakaoさん
 これ動きませんでした。よく見ると液晶のPNがACM1602となっていますが今回の液晶はAQM1602です。おまけにドライバのチップはST7066ということで全然別の製品用でした。これくらいは事前にちゃんと理解してから探せよ→自分。ということなんですが、すみません私が悪いです。

◆まとめ
 Arduinoで動かすI2Cキャラクタ液晶のライブラリは検索すれば簡単に見つかるだろう、と思っていたのですが。実際には簡単ではありませんでした。事実、今回は5種類試してそのまま使えたのは一つだけ(1.項の I2CLiquidCrystal)でした。昔、知識も無い状態で適当にネットで拾ったライブラリを入れてうまく動かなかったのはある意味当然の結果でした。

 あと、いまさら気付いたのですが、パラレルインターフェイスの液晶を使う場合のライブラリは LiquidCrystal.h を使いますが、このライブラリの完成度が素晴らしく高いので、他のライブラリを探す必要が全く無かったということなんですね。

◆ライブラリの名について
 この記事の中でちょっと触れていますが、ライブラリの名前について以前から気になっていることがあります。それは、ライブラリの名前は後で改良版を作る人のことを考えて付けて欲しい、ということです。デバイスの名前と同じライブラリがよく作られています(ex:デバイス名がABC123ならライブラリ名もABC123.h) 。でもそういうど真ん中の立派な名前を使われると、後で改良版を作る人はライブラリ名をどうするか困ってしまいます。(改変版を作る場合、オリジナルの作者の方の権利を侵さない注意は当然必要です。)

 もちろん最初の作者の方が、ずっとそのライブラリをメンテナンスしていただけるなら、ど真ん中の立派な名前を使っていただいてかまいません。でも現実を見ていると、そうはなっていないケースがたくさんあります。

 ライブラリの名前はもちろん判り易くないといけません。でもそれをそのまま使うのでは無く、ちょっと自分のイニシャルを追加して傷を付ける、というスタイルが良いのではないかと個人的には思います。今回の記事では、3.項と5.項のライブラリがそうなっていると思います。

 このくだりはちょっと余計だったかも知れません、また異論もあるでしょう。そもそもライブラリを一つも公開していない人間が偉そうなこと言うんじゃないよ、というお叱りを受けそうです。ただ、ずっと気になっていたので、この機会に文章にしてみました。

ArduinoでI2Cキャラクタ液晶を使う(その1) 基本動作確認

 I2Cインターフェイスのキャラクタ液晶のストックが増えてきたので、これをちゃんと使えるようにしたいと思います。なお、使う環境はArduino です。

▼I2Cキャラクタ液晶のストック
I2C液晶
 キャラクタ液晶は作った物に組み込んでしまうことが多いので、ある程度ストックを持っていないと不安です。ということで、秋月に行った時にちょこちょこと買っていたらこんなに増えてました。これ以外にパラレルのキャラクタ液晶のストックもいくつかあります。

 この液晶にちょっと数字を表示させるくらいならライブラリを使わないでも何とかなります。でも数値や文字などを整った書式で表示させようとすると、やはりライブラリの助けを借りた方が楽です。実は以前 I2C キャラクタ液晶用のライブラリを使おうとしたのですが、私の経験不足のためにうまくいきませんでした。

 いつまでもそんな状態では情けないので、今回 I2Cキャラクタ液晶をライブラリから動かすことに真面目に取り組むことにしました。最初のターゲットは次の写真のキャラクタ液晶です。これが動けば他は似たような物のはずです。

▼秋月のI2Cキャラクタ液晶(16文字×2行)
秋月のI2C液晶
 インターフェイスは一般的なST7032i です。変換基板を使うとVdd,GND,SCA,SCLの4ピンを接続するだけで動きます。

◆I2Cバスの疎通確認
 キャラクタ液晶として動かす前に、I2Cバスの疎通を自作のI2Cアドレススキャナープログラムで確認しておきました。
I2Cアドレススキャン
 I2Cアドレスの0x3E にデバイスがあるのでインターフェイスは大丈夫そうです。

◆基本動作確認
 次に、基本的な動作の確認のためにライブラリを使わないで動かしてみます。そのために秋月のpdfの取説(AQM1602XA-GBW)に書かれているスケッチを下記のように少しアレンジして使いました。なおArduino のボードは UNO を使い配線は取説に記載された通りで、電源電圧は5Vで動かしました。
/*
I2Cキャラクタ液晶(ST7032)の動作テスト
電源電圧=5.0V, SCL=A5, SDA=A4
これは秋月のAQM1602XA-RN-GBWの取説に掲載のArduino用のプログラムを
アレンジしたものです。
2017/06/05 ラジオペンチ http://radiopench.blog96.fc2.com/
*/

#include <Wire.h>
#define LCD_ADRS 0x3E

char moji[] = "AQM1602XA-RN-GBW";

void setup() {
Wire.begin();
init_LCD(); // ST7032初期化
}

void loop() {
for (int i = 0; i < 16; i++) {
writeData(moji[i]); // 文字列表示
}
writeCommand(0x40 + 0x80); // 2行目先頭
for (int i = 0; i < 16; i++) {
writeData(i + 0xb1);
}
for (;;) { // 無限ループで
writeCommand(0x0C); // 表示ON
delay(1000);
writeCommand(0x08); // 表示OFF
delay(1000);
}
}

void writeData(byte t_data) { //データ書き込み
Wire.beginTransmission(LCD_ADRS);
Wire.write(0x40);
Wire.write(t_data);
Wire.endTransmission();
delay(1);
}

void writeCommand(byte t_command) { //コマンド書き込み
Wire.beginTransmission(LCD_ADRS);
Wire.write(0x00);
Wire.write(t_command);
Wire.endTransmission();
delay(10);
}

void init_LCD() { // ST7032i初期化
delay(100);
writeCommand(0x38);
delay(20);
writeCommand(0x39);
delay(20);
writeCommand(0x14); // Internal OSC freq.
delay(20);
writeCommand(0x73); // Contrast set(上位と合わせて0x23)
delay(20);
// writeCommand(0x56); // Power/ION/Contrast control(Bon ON,3.3V用)
writeCommand(0x52); // Power/ION/Contrast control(Bon OFF,5V用)
delay(20);
writeCommand(0x6C); // Follower control
delay(20);
writeCommand(0x38); // Function set
delay(20);
writeCommand(0x01); // Clear Display
delay(20);
writeCommand(0x0C); // Display ON/OFF control
delay(20);
}
27~31行目は追加した部分で、ここで表示を点滅させています。init_LCD()でモジュールの初期化を行っています。

▼画面表示
秋月のデモプログラム
 上のような画面の点滅を繰り返します。

◆トラブルと対策
 ここで問題が起きたのは、61行目の、writeCommand(0x56); の部分です。オリジナルのプログラムでは61行目はそのまま(コメントアウト無し)で、62行目はありません。この状態で動かすとコントラストが強すぎて黒い■表示になって文字が読めませんでした。但し、この状態でもコントラストの値をうんと下げる(0x0Aくらい)と文字が読めるようになりました。

 どうも61行目は電源電圧が3.3Vの場合の設定のようです。ということで、61行目をコメントアウトし、62行目で writeCommand(0x52); としてBonビットを0にしてbooster circuit をOFFにしました。これで電源電圧が5Vでも正常に表示されるようになります。なお、このあたりのプログラムのコメントは私が追加したものです。

 ところで電源電圧5VでBonがONのままでもコントラストの設定をうんと下げる(例えば0x0A)と表示が見えるようになるので、この状態で使うことが出来るかも知れません。でも、電源電圧5Vで Booster circuit を動かすと液晶の駆動電圧(V0ピン)が8Vくらいまで上昇してしまうので最悪は壊れるかも知れません。ちなみにV0の絶対最大定格はmax.7Vです。ということであまり変な使い方はしない方がいいと思います。

 こんなところで基本的な動作は大丈夫そうなので、いよいよライブラリを使ってみます。長くなったので続きは次の記事で、
カレンダー
05 | 2017/06 | 07
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード