レトロでハードな物語

レトロなゲーム機・マイコン・中古デバイスなどをArduinoやAVRで再活用する方法を模索しています。

以前に作ったタイマーを省エネ化する

2020年11月25日 | 電子工作

前回のコイン電池で動くデバイスで、不要な回路の電力カットとスリープモードを使って省エネにすることを学習したので、過去に作ったこちらのデバイスも省エネ化してみることにしました。



ハンダごてやグルーガンが温まるまでの約4分を計るタイマーです。ATtiny13Aを使っています。Arduinoの開発環境だとdelay()やtone()などでATtiny13Aに1つしかない8ビットタイマーを使ってしまうので、このときのスケッチはdelay()とforループだけで時間を計測するいいかげんな作りになっています。
そのうえ省エネ対策は一切行っていなかったので、電池を入れっぱなしにしておくと、いつのまにか電池切れになります。そこで後から電源スイッチを付けたのですが、それでもスイッチを切り忘れて電池切れになったことがありました。いつも使用しながらもう少しまともな物にしたいと思っていたので、この機会に改良することにしました。

時間の計測には前回と同様にウォッチドッグを使います。タイマーにブザーは必要なので、圧電ブザーを鳴らすためのtone()は使わなければなりません。そのため8ビットタイマーが使えないので他に選択肢はありません。
※実はウォッチドッグではなく8ビットタイマーを利用して、tone()を使うときだけタイマー割り込みを使わないようにしてテストしてみたのですが、最初はちゃんと動作していても使用しているうちにタイマー割り込みが動かないこともあったりして安定動作しなかったのであきらめました。自前で圧電ブザーを制御するという方法もありますが、アセンブラで書かないとATtiny13Aの少ないフラッシュメモリを圧迫しそうですし。

ウォッチドッグタイマーは4分の計測だけでなく、一定時間操作しないときにスリープモードに移行するためのタイマーとしても利用します。これも前回と同じ使い方です。これらの機能を利用して新たに書き直したスケッチがこちらです。

ATtiny13TimerSleep.ino

スケッチはMicroCoreでコンパイルします。bitDuino13でコンパイルするとバイナリサイズが大きくなってフラッシュメモリに収まりません。
でもMicorCoreにはひとつ問題があって、whileループの中でLEDの点滅を行うと出力ピンの設定がリセット(?)されてLEDが光らなくなってしまう現象が発生しました。LEDの点滅の直前に出力ピンの設定を行うとこの問題を回避できたので、上記のスケッチでは107行と145行にピンの設定を記述しています。(145行の記述はwhileループの直前ではなく、中で行わないとだめでした。なぜ??)どちらもウォッチドッグのレジスタを操作した後の処理なので、なにか関係あるのかもしれません。試しにbitDuino13で似たような処理をさせてテストしても問題なかったので、これはMicorCoreの問題なんでしょうね。

ところでピンの入出力設定ですが、今回はレジスタに直接書き込んで設定してみました。たいした効果はありませんが、Arduinoライブラリを使ったときより4バイトのフラッシュメモリを節約できます。複数のdigitalWrite()もひとまとめにしてレジスタ書き込みを試してみたのですが、こちらはメモリ使用量に変化がなかったので元に戻しました。Arduinoは優秀ですね。

MicorCoreのボード設定は以下のようにしました。



この設定値がヒューズビットに書き込まれるように、最初にブートローダーの書き込みも行っておきます。

動作クロックは600kHzにしてみました。このスピードでもちゃんと動作します。データシートによるとアイドル状態の消費電流は21〜22μAくらいで、AD変換とタイマ/カウンタ回路に電力を与えているときのアイドル状態では0.2mAくらいです。前回と同様にアナログ入力やコンパレータなども電力カットしているので、LEDを点灯させなければ消費電流は結構少ないはずです。ちなみにLEDには100Ωの抵抗を付けているので、1ピンに最大30mAで3つ点灯すると90mAになります。

ウォッチドッグは前回と同じに1秒ごとに割り込みを発生させていますが、3Vのボタン電池動作では60回の割り込みに1分11〜12秒ほどかかりました。1.2秒弱くらいの割り込み間隔になります。用途的にきっちり4分でなくてもいいのですが、なるべく誤差が少なくなるように51回の割り込みで1分としました。

4分のタイマー時間を計測していないときもウォッチドッグ割り込みは行われていて、約30秒経過したときにスリープモードに移るようにしています。スリープモードは最も消費電力の少ないモードにしていて、スリープ中はウォッチドッグ割り込みも禁止しました。データシートによると、このときの消費電流は0.13〜0.14μA(動作温度25℃のとき)くらいです。
スリープモードに移るときに、ブザーを1回鳴らして知らせるようにしました。

スリープからの復帰は、3ピンにつながっているタクトスイッチを押すことで行います。スリープから復帰するとすぐに4分タイマーとして動作するので、あまりスリープを意識することはないでしょう。

4分間の計測中は旧バージョンと同様にLEDの点滅で動作中であることを知らせます。このときタクトスイッチを押すと計測を中断させることが出来ます。4分経過した後はブザーとLEDの点滅が繰り返されるので、タクトスイッチを押して停止させます。MicorCoreを使ったので旧バージョンのbitDuino13を使ったときに比べプログラム領域に少し余裕ができ、タイマー計測終了時のLEDの点滅をちょっとだけ派手にすることが出来ました。ブザー音も周波数の異なる音を複数使い分けるようにしました。
ちなみにtone()のdurationオプションで音を鳴らす時間を設定すると最後にノイズが聞こえたので、このオプションは利用せずにdelay()を使っています。

やっとまともなタイマーになった感じです。スリープモードに入れば電池の消耗もかなり少ないので、スイッチの切り忘れも気にせず安心して利用できます。



最新の画像もっと見る

コメントを投稿