google-site-verification: google3bd66dd162ef54c7.html

キャラクタ液晶とスイッチでパラメーター設定する関数 (Arduino)

 日の出日の入り時刻を計算で求めることが出来たので、ソーラータイマースイッチを作っているところです。ソーラータイマースイッチとは、日の出日の入り時刻に連動して動作するタイマーです。このタイマーは、例えば日の入り時刻の10分前にON、などと動作条件を細かく設定出来ると使い勝手が良くなります。

 このようなパラメーター設定を、Arduinoを使い、キャラクタ液晶と限られた数のスイッチだけで行うのは結構面倒なプログラムを書かないといけません。

 今回、ソーラータイマー用に液晶画面を使って数値を入力する関数を作りましたが、これ、けっこう汎用的に使えそうです。ということで、自分用のメモも兼ねてデモプログラムとして公開します。

▼プログラムを動かすための回路
回路図
 液晶はI2Cの16文字、2行(AQM1602)。スイッチは dec.(-)、inc.(+)、Enterの三つを使います。

◆液晶とボタン3つで値を設定するデモプログラム
/* キャラクタ液晶と押しボタンを使って数値を入力するデモ
* 液晶:AQM1602A
* 2017/7/13 ラジオペンチ http://radiopench.blog96.fc2.com/
*/

#include <I2CLiquidCrystal.h> // N. MitsunagaさんのI2C液晶ライブラリ http://n.mtng.org/ele/arduino/i2c.html

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

int DecB = 8; // - (Dec) ボタンのピン指定
int IncB = 9; // +(Inc)ボタンのピン指定
int EntB = 10; // Enterボタンのピン指定

int Data1 = 0; // テスト用データー
int Data2 = 6;
void setup() {
pinMode(IncB, INPUT_PULLUP); // + (Increment)ボタン
pinMode(EntB, INPUT_PULLUP); // Enterボタン
pinMode(DecB, INPUT_PULLUP); // - (Decrement)ボタン
lcd.begin(16, 2); // 16文字2行のI2C液晶を使用
}

void loop() {
lcd.clear();lcd.print("Input sNN +-20"); // 2桁の正負の値の入力(符号付き表示)
lcd.setCursor(0, 1); lcd.print("Data1 sNN");
Data1 = lcdInput(Data1, 8, 1, -20, 20); // Data1を±20の範囲で入力(値は上下限で飽和)
lcd.clear();
lcd.print("Data1 = "); lcd.print(Data1); // 確認のために表示
delay(2000);

lcd.clear();lcd.print("Input NN 1-12"); // 2桁の整数入力(符号無し表示)
lcd.setCursor(0, 1); lcd.print("month NN");
Data2 = lcdInput(Data2, 7, 1, 1, 12); // Data2を1~12の範囲で入力(値はサーキュレート)
lcd.clear();
lcd.print("month = "); lcd.print(Data2); // 確認のために表示
delay(2000);
}

int lcdInput(int d, int x, int y, int minV, int maxV) { // 液晶表示と値の入力関数
// +-ボタンで値を変更、Enterボタンで確定
// d=初期値、x, y=液晶座標、 minV,maxV=下限上限、戻り値=入力決定値
// 下限値(minV)が負なら符号付き表示(sNN) 正なら符号無し表示(NN)を行う
// minVが正なら値をサーキュレート、minVが負なら値は上下限でストップ

lcdDisp(d, x, y, minV); // 値を表示
while (digitalRead(EntB) == LOW) { // もしEntBが押されていたら離されるまで待つ
delay(30);
}
while (digitalRead(EntB) == HIGH) { // EntBが押されていなければ以下の処理を繰り返す
if (digitalRead(IncB) == LOW) { // +ボタンが押されていたら
delay(30);
d++; // dをインクリメント
if (d > maxV ) { // 上限を超えていたら
if (minV < 0) { // minVがマイナスの場合は
d = maxV; // 上限で抑える
} else { // そうでなければ
d = minV; // 値を下限に変更(サーキュレート)
}
}
lcdDisp(d, x, y, minV); // 指定フォーマットで表示
while (digitalRead(IncB) == LOW) { // +ボタンが離されるまで待つ
}
delay(30);
}

if (digitalRead(DecB) == LOW) { // -ボタンが押されていたら
delay(30);
d--; // dをデクリメント
if (d < minV ) { // 下限を下回っていたら
if ( minV < 0) { // minVがマイナスの場合は
d = minV; // 下限で抑える
} else { // そうでなければ
d = maxV; // 値を上限に変更(サーキュレート)
}
}
lcdDisp(d, x, y, minV); // 指定フォーマットで表示
while (digitalRead(DecB) == LOW) { // -ボタンが離されるまで待つ
}
delay(30);
}
}
delay(30);
lcd.noCursor(); // 入力が終わったのでカーソルを消す
return d;
}

void lcdDisp(int d, int x, int y, int minV) { // 指定位置に2桁の値を表示する関数
// minVが正ならNN形式、負ならsNN形式
if (minV < 0) { // 負の値がある場合
lcd.setCursor(x - 2, y); // 2文字左にカーソルを移動して
if (d >= 0) { // 値が正なら
lcd.print("+"); // +を表示
} else { // それ以外(つまり負)なら
lcd.print("-"); // -を表示
d = abs(d);
}
}
lcd.setCursor(x - 1, y); // 1文字左から
if (d < 10) { // 値が10以下なら
lcd.print("0"); // 0を埋めて
}
lcd.print(d); // 値を表示
lcd.setCursor(x, y); // 1桁目にカーソル移動
lcd.cursor(); // カーソル表示
}

 このプログラムは2桁の数値の入力を行うデモになっています。カーソル(アンダーバー)が出ている位置の値(2桁)を変更します。値は inc. (+)ボタンで増加、dec. (-)ボタンで減少し、Enter ボタンで入力決定して次の処理へ進みます。

▼デモプログラムの表示
液晶の表示

 lcdInput( )関数を適当な引数を付けて呼び出すと、設定した値が関数の戻り値として帰ってきます。細かい動作はコメントに書いておいたので、興味のある方はご覧ください。なお、このプログラムは順番にゴリゴリと書いただけで、たぶん誰が描いても同じようなものになると思います。ということで、勝手に改変して使って頂いてかまいません。

◆参考
 現在作りかけのソーラータイマースイッチに使う関数のテスト用のスケッチは以下の通りです。これは上の関数を中心に、もう少し複雑な機能を入れたものです(同じ回路図で動きます)。なお、まだテスト中なのでおかしな所があるかも知れませんが、何かの参考になれば幸いです。
 ソーラータイマースイッチ設定機能テストプログラム、20170713SolarTimerSetTest.txt (拡張子をinoに要変更)
関連記事

コメントの投稿

管理者にだけ表示を許可する

文字化け?

プログラムを拝見させて貰おうと思いぽちっとしたのですが、

コメントが文字化けです。コードの設定が必要ですか?

 話変わりますが、AVR初めました。AT90S2313。

実に面白いです。Arduinoにもインラインアセンブラ使えるんですね。私はCはあんまり得意ではないのですが、参考にさせていただきます。暑い日が続きますがご健康でありますように。

re:文字化け?

老技師さん、こんにちは。今、この記事に液晶の写真を追加したところです。

文字化けの件ですが、プログラムのファイルはShift_JISでエンコードしています。お使いの処理系によっては文字化けしてしまうことがあるかも知れませんが、すみませんうまくやってください。

ちなみにArduino IDEで作る .inoのファイルのエンコードはUTF-8になっていますが、そのままwebに上げるとほとんどのブラウザで文字化けするので、Shift_JISに変換してアップロードしています。

AT90S2313ですか、いいですね。私もピン数の少ないものを使ってみたいですが、なかなかきっかけが掴めません。

参考になります

こんばんは。毎日暑い日が続きます。夜中でもエアコンを止めると室温が30度超えるので寝苦しいです。

プログラムタイマのスケッチありがとうございます。
まだ、ざっと見ただけなので何も理解できていませんが
補正値は重要ですね。この部分は、ラジオペンチさんの気圧ロガーのスケッチの補正値を参考にさせて頂きました。
またまた、いろいろなテクニックが見れそうなのでちゃんと見るのが楽しみです。

自分なりに工夫したのは電池駆動の場合、液晶画面の文字の濃さが電圧によって変わってしまうので、電池出圧をAD変換で読み取って、コントラスト調整をしています。

私のスケッチは本当に稚拙で小学生が考えるようなプログラムの組み方をしています。
ただ自分で考えつくことは単純なので、だいたいどうにかなってしまうから、arduinoプログラムって面白いのかな。

re:参考になります

hiroさん、おはようございます。暑いですね!

そうやってプログラムを流用して使っていただけると励みになります。アイディアをすぐ試すことが出来るのが楽しいですよね。

なお、ソーラータイマースイッチのプログラムはプログラムは現在デバッグ中です。ごちゃごちゃのスパゲッティプログラムになっていて恥ずかしいのですが、完成したら記事で紹介予定です。
カレンダー
06 | 2017/07 | 08
- - - - - - 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 31 - - - - -
プロフィール

ラジオペンチ

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

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