profile-photo

電源同期クロックの試作

商用交流電源をクロックにした"狂わない"時計


このタイトルを見て、「懐かしい」と思う人は結構年配だ(^_^;
今更『時計』でも無さそうなのだが、時計はやはり電子おもちゃの1つの柱だと思う。
僕も古い人間だが…昔は商用電源を基準にした時計が沢山あった。
未だ、パソコンは無くて、精度の良い水晶発振子はとても高くてなかなか手が出ない頃だった。
ロジック回路はTTLのゲートやラッチが主流だった。商用交流電源(要はコンセント)は、電力会社が周波数を監視・管理しているので、かなり正確な周波数を得ることができる。
これを基準クロックとして分周回路を重ねて、LEDのデコーダ・ドライバを作り、時計を作った。
はがきより少し大きめの基板にTTL-ICをギッシリ。
それを3段程重ねて、7セグメントのLEDで時刻を表示。
消費電力も凄かったけど、発熱も凄くて小型の暖房器具になるくらいだった。
その後LSIや水晶発振子が小さく安くなって、コンセントに縛られる様な時計は人気が無くなってしまった。
今では『時計』なんて100円ショップでいくらでも売っている時代だ。
僕もカラー液晶シールドを手に入れて、最初にやってみたのが時計だった。
詳細はここ
これは時計シールドを作り、Arduino Unoの上に液晶シールドと合わせて3段積みだった。
しかし、この時計は狂う。時計たるモノやはり時刻を正確に刻んで欲しいと思い、これはそのままお蔵入りしてしまった。
やはり安物の時計モジュールを使ったのが悪かったのかも知れない。

正確な時刻を刻んで、狂わないコンパクトな時計を作ってみたくて、色々考えていた。
やはり、表示がネックになる。消費電力が少ないのはLCD(液晶)だが、バックライトが無いと見にくい。でもバックライトを点けると消費電力が一桁増えてしまう。
電池駆動の目標は10mA以下。できたら1mA以下にしたいと思っていた。
バックライト付液晶では、それだけで数10mAが必要になる。LEDのセル自体が10mA以上要求するからだ。
と、一時は諦めていた。

しかし、考えていたら1つの結論に達した。
「電池で動かせないで、どうせコンセントから電気を取るほどのものなら「電源同期」もありではないか。」
消費電力もAC電源を内蔵すれば、それ程気にしなくても良い。
時計ICとバックアップ用の電池程の大きさで、60Hz(名古屋なので)を整形して割り込みを掛ける回路が作れるか。
これがその試作の目標の1つだった。
AC100Vを直接触るので、感電やショートによる火災など不安要素はあるので、最初は壊れても良いように、トランジスタを使ったディスクリート回路で、トリガパルスを作ってみた。
これをいつも開発に使うArduino UNOに取り込んだ。
トリガパルスでマイコンに割り込みを掛けて、カウントする。
60Hzなので、60回割り込みを数えれば1秒になる。
これで時計が作れるわけだ。
実験が上手くいったので、実際の回路の設計を始めた。
半波整流回路は実験回路と同じだが、シュミットトリガ回路は小さくしたかったので、74HC14を使用。6ゲートもあるのに1つしか使わないのはちょっと勿体ないがディスクリート回路よりは小さくなるので我慢。
表示は省エネも考えてLCD(a店の99円液晶)とした。 最初は、この電源から直接トランスレスで全部の電源を取ろうととも思ったが、普通に作ると2〜30mA程度しか取れない。沢山取ろうとするとAC100Vからのカップリングコンデンサが大きくなってしまう。
結局、コンデンサーよりも小さい電源装置(5V/0.7A)が手元にあったので、直流電源はこちらに任せることにした。
次はCPUの選定。大したプログラムでは無いので当初はAttiny13で考えた。しかし液晶をケチったために、表示のプログラムが以外に大きくなった。どうやっても1Kbyte以下にならない。最少で1.1Kbyteにまで行ったのだが、時計であるからには時刻設定のプログラムなどが無くてはならない。そのためにはキーボードも必要になる。
最終的に、CPUは贅沢にもAttiny85を使うことになった(^_^;
最近Attiny85が高い。Attiny13なら@50円なのにAttiny85は@160円〜250円程もするのだ。特にSOPが高い。そこで今回は試作でもありDIPを使うことにした。
最初に実験したのはAttiny13だった。LCDの表示は簡易的にして無理矢理1Kbyteに収めていた。
同じAttinyだし、ピン数も同じ8Pinなので、Attiny85に差し替えれば動くと安易に考えていた。 ここで嵌まった。
半日ほど悩み続けて、13と85の仕様書を読んで分かった。実はAttiny13は外部割り込み”INT0”が6番(PB1)にあるのに、Attiny25/45/85は”INT0”は7番(PB2)に割り付けられているのだ。
それまで、13と85の違いはプログラムメモリーのサイズだけだと思っていたので、気がつかなかった。 確かにAtmelの仕様書は”Attiny13”と"Attiy25/45/85”とに分かれている。こんな所に違いがあるとは…
キーボードはアナログ1ポートで読み込めるいつもの"NANO-Key”を使った。

 

001

トリガ回路
コンデンサーで交流成分を取り出して、半波整流した後、ツェナーダイオードで5Vに抑えて、シュミットトリガ回路で整形する。
上が半波整流前の波形。ダイオードでプラス成分が切り取られている。
下がシュミットゲートを通った後。16ms毎にエッジが取り出された。

002

メイン基板(ハンダ面)
液晶を大物部品と干渉しないように取り付けるため、ハンダ面に持ってきた。これは結果的に失敗(考えすぎた)。
めもあって結局基板そのものはかなり大きくなってしまった。

003

側面から
液晶をコネクタで繋いだので、ここも長くなってしまった。
後から考えると、液晶は部品面に持ってきて、コンデンサや電源との配置を考えた方が良かった。

004

部品面
電源関連が左側に固まっていて、コンピュータ部分はAttiny85があるだけで閑散としている。
上のスイッチはバックライトのON/OFFスイッチ。

005

完成品の正面
当初の思いとは裏腹に結構大きな物になった。
NTPサーバと比較しているが、時刻は時に5秒程ずれる。
最初は心配したが、この誤差は累積せずに、また少なくなる。概ね日にプラスマイナス5秒程の誤差に収まっているようだ。

006

背面から
以前の装置はヒューズやスイッチは筐体の隅にあって、目立たなかったのに、全体が小さくなってきたので、ヒューズホルダが大きく目立つ。
上にあるユニットが5Vの電源(スイッチングレギュレータ)。
電源のスイッチングのイズを心配したが、今のところ大丈夫そうだ。

スケッチ(プログラム)について

Cの通常のプログラムは、「main関数」があって、起動するとこれが呼び出される形になっている。
Arduino IDEでは、ここを隠蔽して、setup()とloop()関数で構成するようになっている。 今回は、割り込み処理の関係で、敢えてmain関数を出してある。(結局はそうしなくても良かったのだが…)

main()関数

main()は、最初に各種の初期化処理をし、その後whileループで回り続ける。
このループの中では、1秒に1回タイムレジスタ(1秒単位)を参照して時・分・秒のレジスタ(変数)に値を計算して入れ、時刻の表示を行っている。

時刻設定ループ

また、ループ中ではキー入力を監視していて、”SELECT”キーが押されたら時刻設定モードになるようになっている。
時刻設定はMmain()の中にもう一つのwhileループを入れ子にしてあり、終了(“RIGTH"キー)が押されるまでループを続ける。
この設定ループの中では、”UP”キーまたは”DOWN”キーが押されるたびに分の桁を1つずつ進める(戻す)。
時刻設定ループは、「_delay_ms()関数」で、通常は0.5秒おきに設定を変更するが、5回続けて同じキーが押される(すなわち長押し)と、15msに待ち時間を変更する。
つまり、”UP””DOWN”を長押しすると、時刻が早く回り始めると言うわけだ。

割り込み処理

割り込みは、INT0の外部割り込みを使う。ここへ60Hzを整形した矩形波を入力し、カウントする。 60回数えたら1秒になるのでタイムレジスタを+1する。ただし、一日は86,400秒なので、この値を超えたらタイムレジスタは0にクリアする。
やっていることはただこれだけ。
ただ、今回1つソフトウェアで悩んだことは、割り込みとメインをつなぐグローバル変数だった。 上で書いたタイムレジスタだ
。 最初グローバル変数としてだけ定義したが、どうしても上手く動かなかった。
しばらく悩み、WEBで先輩方の処方を調べて、やっと分かった。この場合”volatile"宣言をしておいて、コンパイラに最適化をしないように指示する必要があったのだ。
C,C++(gcc)コンパイラは良くできていて、かなりしっかり最適化してくれる。下手にアセンブラで書くより余程上手いコードを作ってくれる。
これが災いして、グローバル変数までも最適化してしまうようだ。
この”volatile"宣言1つで悩みは解決した。

時刻合わせの方法

・商用交流電源
 今回使った、商用交流電源(50Hz/60Hz)を基準発信とする方法。
・クリスタル(水晶発振子)
 現在主流のクォーツ時計。精度の良いクリスタル(水晶発振子)を使う。
 しかし、クリスタルの発信は温度で変化するので、補正などが必要になる。
・JJY
 日本標準時刻(JST)の電波を受信する方法。
 電波時計などで使われている、福岡県の標準電波送信所からの40KHzの電波及び佐賀県からの60KHzを受信して表示する。
 これは日本標準時なので、正確ではあるが、常に受信しているわけにはいかないので、補完の時計が必要になる。
・NTPの利用
 世界中にあるNTP(Network Time Protocol)サーバに接続して、時刻を得る方法。
 こちらも時刻としては正確無比ではあるが、インターネット接続が必須になる。


参考までにハードウェア・ソフトウェアの情報を。ただしこれらは僕の覚えであり、正確に改版を反映していない可能性があります。この通り作って動かないからと、怒らないで欲しい。