google-site-verification: google3bd66dd162ef54c7.html

ソーラータイマースイッチの製作 ケースに入れて完成

 Arduinoで作るソーラータイマースイッチの話の最終回です。ソフトは完成しているので今回はハードを完成形に持って行きます。

 これまで Arduino UNO とブレッドボードで動かしていた回路を、CPUの単独動作にします。さらにケースに入れて使い易くします。ハード製作には回路図が必要なので完成型の回路図に書き直します。具体的には、Arduino UNO の状態からCPUのATmega328P単独動作の状態の回路図に書き直します。

▼回路図 (クリックで別窓に拡大図)
ソーラータイマースイッチ

 電源は5VのUSB充電器から取ることとし、USBーAケーブルを直出しにすることにしました。

 後でプログラムの書き換えが出来るように、6ピンのICSPコネクタを付けておきました。

 Timer Outの出力(回路図の右下)はとりあえずパワーFET(Q1)のバッファを入れて5V出力でLEDを点灯出来るようにしておきました。なお、LEDまでの配線が長くなりそうで、発振が怖いので、ゲートに抵抗(R2)を入れておきました。また、点灯テスト用にマニュアル点灯スイッチを追加しています。

 基板はおなじみの秋月のC基板(片面100ミル)を使い、ケースは秋月のABS樹脂ケース(P-07423)を使いました。

▼完成品の外観
ソーラータイマースイッチ完成
 いい感じに仕上がりました。スイッチはケースの上蓋を開けて操作します。実は、蓋を開けないで操作出来るようにしたかったのですが、細工が面倒だったのでやめました。左側に出ている黒い線は電源ケーブルで、先に付いているUSB-Aコネクタから電源(5V)を供給します。

▼内部基板
基板に液晶を乗せた状態
 スイッチの機能を手書きで記入していますが、左から、Reset、Dec.、Inc.、Enterです。右端のスライドスイッチは出力の強制ONです。

▼液晶を取り外した状態
基板
 左上の3ピンコネクタが出力(Timer Out)です。中央上の青い小さな基板は、液晶の取り付け位置を上にシフトさせるために付けた物で、強度を確保するため両面スルホール基板を使っています。右上はパワーFETで、足を変則的に曲げて液晶との干渉を防いでいます。
 記事を書いていて気付きましたが、この写真は電源のパスコン(C1,C2)が付いていませんでした。液晶やRTCの中にパスコンが入っているので、入れなくてもまあ大丈夫です。

▼裏面
裏面、配線が丸見え
 透明ケースなので配線が丸見えです。基板はプラビスで固定しています。

◆まとめ
 とりあえずソーラータイマースイッチが完成しました。市販のソーラータイマースイッチは1万円以上しますが、その1/10くらいの値段で作ることが出来ました。とは言っても、市販品は計装部品として必要な各種のマージンを確保しているので単純な比較は出来ません。ただ、機能としては遜色無い物が出来たと思います。

 今後このタイマーを使って、テレビボードのLEDダウンライトの自動点灯をやってみる予定です。

 ところで今回28ピンのICソケットを切らしていたのでCPUを直付けしました。ICSPコネクタがあるのでCPUを引っこ抜かなくてもプログラムの書き換えが出来るはずだったのですが、、、なぜかUSBシリアルケーブルがうまく動きません。チップはPL2303を使った物です。
 ちなみに以前もおかしくなったことがあり、対策のためにドライバの入れ替えをやったのですが、またしても動かなくなりました。最近 Windows10 の大きなアップデートがあったったので、たぶんその影響だと思います。

 やれやれ、また対策を調べないといけません。たぶんパチ物のUSBシリアルチップを使っている報いが来ているんでしょう。こういう非生産的なことに何度も時間を使うのは馬鹿らしくなってきたので、正規品を一つ持っていた方が良さそうです。あと、28ピンのICソケットも補充しないといけません。暑いけど久しぶりに秋月に行ってみようかなと思います。

【追記】
 書き忘れていましたが、回路の消費電流は0.2mAで、1秒に一回の表示更新時には約20msの間消費電流は16mAまで増えます。平均としては消費電流は0.5mAということになりますが、USBのACアダプタを電源に使うなら問題にならない消費電流だと思います。

ソーラータイマースイッチの製作 ソフトほぼ完成

 この間からArduinoで動かすソーラータイマースイッチを作っているのですが、そのソフトがほぼ完成しました。

 とは言ってもまずは回路図から、

▼回路図
ソーラータイムスイッチ回路図

 前回の記事とほとんど同じですが、スイッチが一つ増えています。このプログラムは沢山のパラメーターの設定が必要になるので、操作を効率的に行うために、Dec.(-)、Inc.(+)、Enterの3ボタン方式にしました。なお、以下の資料ではボタンを(Dec)、(Inc)、(Enter)と括弧付きで表現します。

  タイマーの出力の Timer Out にはインターフェイス回路の追加が必要ですが、それは相手が決まってから考えればいいので、今は状態表示用のLEDだけ接続しておきます。

▼実験用ボード
デバッグ中のソーラータイマースイッチ
 まだArduinu UNOとブレッドボードで動かしています。

◆機能
 ところで、ソーラータイムスイッチは計装機器として多くのメーカーから販売されています。調べてみると夜はON、朝になるとOFFになるのが基本動作になっていました。でも流石にこれだけでは単純すぎるのでしょう、どのメーカーも固定時間タイマーを組み合わせることが出来るようになっていました。以下は動作モードの説明図で、大崎電機の資料から抜粋したものですが、他メーカもほとんど同じす。

▼市販のソーラータイムスイッチの動作モード(大崎電機の資料から抜粋)
ソーラータイマースイッチの動作モード

 少し説明すると、日没/日の出時刻は設置場所や季節によって変わります。ソーラータイマーはそういう変化を反映した時刻で動作します。ただ設置環境によっては「朝明るくなるのが遅い」などの個別の違いがあります。そういう違いを補正するために、「早め」、「遅め」の調整が1分単位で出来るようになっています。

 固定タイマーは時計に連動したタイマーで、設定時刻にON/OFFの操作を行うものです。これは例えば、日没で自動的にONとした照明を夜明けまで点灯させ続けるのは無駄なので、24時になったら消す、という動作にしたい時に使います。他にもいろいろな理由が考えられると思いますが、ともかく固定ONとOFFのタイマーを各々、有効/無効に設定することで、上の表のような各種の動作パターンを選択出来るようになっています。

◆プログラム
 Arduinoで動かしますが、せっかくなので市販のソーラータイマーと同等の機能を実現することにとにしました。

 プログラムは700行以上あって長いので、下記リンクに置いておきます。なお、同じような機能の関数が複数あったりして汚いソースになっていますがご容赦を。
 ソーラータイムスイッチのプログラム_20170721SolarTimeSwich (Shift_JISでエンコードしています。拡張子をinoに要変更)
 プログラムはピン割り込みを使って省エネで動くようになっていますが、そのあたりの話は割愛し、この記事では操作方法につき説明することにします。

 操作は大きく以下の二つのグループに分かれています。
1.起動時のボタン操作による動作条件の設定
  (指定ボタンを押した状態でリセットボタンを押す。その状態で先にリセットボタンを離す)
2.動作中のボタン操作による状態表示

 以下、この順に機能を解説します。

1.起動時のボタン操作による設定

1-1  時計の時間合わせ (Dec)と(Inc)を押しながらリセット
▼開始メッセージ
時計合わせ開始
 時計合わせモードに入ったことを表示。ボタンを離すと次の画面へ進みます。

▼時計の時刻合わせ
時計合わせ中
 カーソルの位置の値をInc/Decボタンで設定し、Enterで確定します。確定するとカーソルは次の位置に移動。分の値を決定(Enterを押)したタイミングで、00秒として時刻合わせが行われます。なお、カーソルは逆方向へは動きません。間違いに気付いた時はリセットで最初から入力。

1-2 ソーラータイマーのオフセット設定 (Dec)を押しながらリセット
▼開始メッセージ
ソーラータイマー

▼オフセット値の設定(日没補正)
ソーラータイマー
 日没でONにする時刻の補正量を設定します。遅くしたい場合は+、早くしたい場合は-の合値を入れます。設定は分単位で行い、±99分まで設定可能です。

▼オフセット値の設定(日の出補正)
ソーラータイマー
 日の出でOFFにする時刻の補正。設定方法は上記と同じ。

1-3 固定タイマーの設定 (Inc)を押しながらリセット
▼開始メッセージ
Fixタイマー設定

▼固定OFFタイマーの設定画面
Fixタイマー 時刻設定
 USE/NO USEの選択と、動作時刻を設定します。この画面は、23時10分にOFFを設定しています。

 市販のソーラータイマースイッチは、固定時間タイマーは夜間(日没から日の出まで)しか設定出来ないようになっているようですが、このタイマーではそのような制限は無く、昼間の時刻も設定出来ます。

▼固定ONタイマーの設定画面
Fixタイマー
 この画面では、固定ONタイマーは不使用(NO USE)に設定しています。

1-4 経緯度の表示 (Enter)を押しながらリセット
▼経緯度の表示
経緯度表示
 設定されている経度、緯度を表示します。この座標を使って日の出、日の入り時刻を計算しています。この画面から抜けるにはリセットします。なお、座標の値の設定機能は無いので値を変更したい場合は再コンパイルが必要です。デフォルトの値は東京(日本地図原点)です。

2.動作中のボタン操作で表示
2-1 何も操作しない場合 ボタン操作無し
▼情報表示(ノーマル)
通常表示
 何もスイッチを操作しないとこの画面が表示されます。

 上段に現在の 月/日、時:分:秒を表示。下段にその日の日の出/日の入り時刻を表示します。右上の黒丸はタイマーがONの時に表示されます。

2-2 ソーラータイマーのオフセット表示 (Dec)を押す
▼ソーラータイマーの設定状態確認
ソーラータイマー
 右端にソーラータイマーが動作するオフセット値を±の値で表示します。なお、値は分単位。表示している時刻は当日の日の入り/日の出時刻です。操作を統一するため、ソーラータイマーの設定と状態確認は(Dec)を使うようにしています。

 ボタンを離すと通常表示に戻ります。なお、ボタン押しの検出は1秒間隔で行っているので、短時間押した場合は表示が変わらない場合があります。ボタンは少し長めに押す必要があります。以下同様です。

2-3 固定時間タイマーの表示 (Inc)を押す
▼固定時刻タイマーの設定状態確認
Fixタイマー
 Incボタンを押すと、固定時刻タイマーの設定状態を表示します。なお、操作を統一するため、固定タイマーの設定と状態確認は(Inc)を使うようにしています。

 この例では、23:00にタイマーをOFFし、ON時刻の指定が無いのでONはしません。日の出にソーラータイマーからOFF指示が出ますが、元々OFFだったので状態変化は無しという動作になります。

2-4 西暦の表示 (Enter)を押す
▼年表示の情報表示
通常表示
 左上の 月/日を表示していた位置に西暦を表示します。(2017/)

◆まとめ
 予想外に長いプログラムになってしまいましたが、たぶん市販されているソーラータイマースイッチと同等の機能を作り込むことが出来たと思います。そのまま使っていただいてもいいし、流用できる部分があれば、そこだけつまみ食いしていただいてもかまいません。

 市販のソーラータイマースイッチでは設置場所を、日本を10のブロックに分けて設定するようになっています。この方法は判り易いですが、同じブロック内でも日の出時刻は数分くらい違うので精度はあまり良くありません。
 このソーラータムスイッチは設置場所の経緯度をピンポイントで指定出来るので、市販の物より精度良く日の出日の入り時刻を予想出来ると思います。また、日本本土から遠く離れた島でも安心して使えるはずです。

 この先の予定としては、このソーラータイムスイッチを使って、夜になったらテレビボードのLEDダウンライトを点灯させる仕掛けを作ってみたいと思います。実は7年前に、暗くなるとLEDを点灯する回路(太陽電池の電圧検出方式)というのを作りましたが、この発展型ということになります。昔はトランジスタのシュミットトリガ回路がちゃんと動いただけで喜んでいたのですが、7年経つとマイコンが使えるようになりました。自分で言うのもなんですが、我ながら進歩したと思います。

キャラクタ液晶とスイッチでパラメーター設定する関数 (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に要変更)
カレンダー
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コード