google-site-verification: google3bd66dd162ef54c7.html

ソーラータイマースイッチの製作 基本検討

 以前、日の出・日の入り時刻をArduinoを使った計算で求めてみました。この計算には三角関数を何度も(約40回)使わないといけないので、計算時間が心配でした。しかしやってみると数ミリ秒で結果が出て来て処理速度には問題が無いことが判りました。それに計算誤差も最大で50秒くらいに収まっていて、日の出・日の入り時刻の予想に使うには問題無さそうなことが確認出来ました。

 つまりArduinoを使って日付と位置情報から日の出・日の入り時刻が計算出来る訳です。こうなると応用問題として、夜になると自動的にスイッチが入るタイマーを作ってみたくなります。

◆夜になったらスイッチを入れる方法
 ところで、夜になると自動的にスイッチを入れる方法として、タイマーを使うことを最初に考えると思います。でも日の出・日の入り時刻は季節によってかなり変わるので、年に数回以上タイマーの設定値を変える必要があります。これでは大変です。
 他の方法として明るさセンサーを使う手があります。つまり外が暗くなってきたら夜が始まったと判断する方法です。でもこの方法ではセンサーの設置や配線が必要になります。ということで、どちらの方法もちょっと難点があります。

◆ソーラータイマースイッチ
 その日の、日の出・日の入り時刻を自分で知ることが出来れば、上に書いたような問題が解決出来ます。実はこういう機能を持った製品は、ソーラータイマースイッチという名前で売られています。でもこれ、制御盤に取り付ける機器なので値段は高くて1万円以上します。

 だったらArduinoで作ってみよう、というのがこの記事の趣旨です。

▼回路図(実験用)
ソーラータイマーの回路図
 ArduinoにRTC(リアルタイムクロック)とキャラクタ液晶をI2Cで接続しています。どちらも電源電圧5Vで動くのでレベル変換無しでArduino UNOに接続できます。

 Timer Outの信号は相手に合わせたインターフェイスが必要になりますが、そこは後でどうにでもなるので、とりあえずこの状態でプログラムを作っていきます。

 以前の記事でI2Cキャラクタ液晶のライブラリをあれこれ選んでいましたが、実はこの回路を作るのが目的でした。

▼スケッチ
 まだ全部完成していませんが、基本的な機能は動くようになっています。ソーラータイマースイッチのスケッチはこちら(拡張子をinoに要変更)
 RTCのライブラリは以前使った経験があるRTC8564.hを使いました。実は最初はきむ茶工房さんのRTCライブラリを使いたくて、いろいろいじったのですが、割込みあたりの処理がうまく書けなかったので実績のあるものに戻しました。
 なお、もし実際に試される方は、ライブラリ、RTC8564.hを使う時の修正点をご覧ください。

▼動作中のメイン画面
メイン画面
 一行目に月日と時刻。二行目に日の出・日の入り時刻を表示します。つまり、この日の日の出は4時28分、日の入りは19時1分ということとです。なお、ボタン操作で西暦も確認できます。

▼時刻合わせ画面
時計時刻合わせ
 カーソルの位置の値を順番に修正していきます。こういう機能を作るのはかなり面倒ですが、以前作ったプログラムがほとんどそのまま使えたので助かりました。

▼経緯度確認画面
経緯度確認画面
 市販のソーラータイマースイッチでは設置場所を10種類くらいの地区から選ぶようになっていますが、このプログラムでは経緯度を直接指定する方式にしました。といってもこの画面は入っている値の確認用で、経緯度を変更したい時には再コンパイルが必要です。

◆プログラムのポイント
 以前作ったプログラムの寄せ集めで作ったので、新たに書いたのは20%くらいです。ポイントは以下の通りです。

 CPUは節電のために深いスリープに入れ、RTCから1秒間隔でピン割り込みを掛けて必要な処理を実行しています。プログラムの実行時間は約27msで残りの時間はスリープしています。ちなみに、スリープ中の消費電流は200μA程度になるはずです。(但しこれはCPU単独運転の場合の話で、UNOの状態では他の回路が電流を喰っているのでこんなに消費電流は減りません)
 
 現在のスケッチは日没から日の出までの期間に Pin10 にHIGHを出すようになっています。市販のソーラータイマースイッチの仕様を調べると、日の出・日の入り時刻の補正機能(各々±90分程度)と、固定時刻でON/OFFする機能を付けるのが普通のようなので、同等の機能を今後追加したいと思います。

◆まとめと今後の予定
 ソーラータイマースイッチとしての骨格の部分が完成したと思います。あとは使い易くするための機能の追加が残っていますが、このあたりはやり始めると切りが無いので、適当な所で切り上げるつもりです。複雑な処理をやりたい場合は専用のコードを書けば済む話です。

 ということで、時間が出来た時に少しずつプログラムを仕上げて行きたいと思います。

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.項のライブラリがそうなっていると思います。

 このくだりはちょっと余計だったかも知れません、また異論もあるでしょう。そもそもライブラリを一つも公開していない人間が偉そうなこと言うんじゃないよ、というお叱りを受けそうです。ただ、ずっと気になっていたので、この機会に文章にしてみました。
カレンダー
07 | 2017/08 | 09
- - 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コード