190923:保護カバー作成
190921:誤記修正
190920:作成
もどる
■発端
AtmelのTiny13(無印)をパーツ箱で見つけた。以前ChaNさんのCircuitTesterを作ったときの予備だと思う。
CircuitTesterでTiny13のパワーダウンモードの消費電流の少なさは知識で知っていたけど、実際どうなの?
なら自分で作って見よう。
■目標仕様
・俗に言うカップラーメンタイマー。時間は最低3分、4分、5分の三種類。
・パワーダウンモードを(自分で)試したい。
・なら動作時の電流も少なくしたいよね。システムクロックもなるべく低く。
・よし、ならもっと電流減らしたいので、LED等の光り物も無し。
・ブザーも自励式は圧電スピーカーでも結構電流流れたりするようなので、他励式で(ようするに圧電スピーカー)。
・電源はCR2032ボタン電池 3V
■仕様検討
・ポートは、PB0~PB5の6本。ただし、PB5は/RESETと兼用。ISPで開発するならPB5は使用不可。
・PB0~5は、それぞれPCINT0~5のピンチェンジ割り込みが使用可能。
・タイマー0の出力は、OC0A、OC0Bの2本。PB0、PB1と兼用。
・タイマー0の出力は圧電スピーカーの駆動に使用。
・入力は4本。それぞれに時間を割り当てずに1本はシフト動作(加算)。
・入力は部品削減のため、内蔵プルアップ。スイッチは負論理。
・ポートの割当が飛び飛びになるのも後々面倒だし、ブザー出力はPB0(OC0A)。
・タイマー0はCTC動作。出力はトグル出力。
・アナログコンパレータ電源は切る。ADCも念の為disable。BODも使わない。ウォッチドッグ? 黙っていろ、ハウス!。
■回路図
回路図はここ。(PDFです)
とりあえずユニバーサル基板に組んだ。電池フォルダはハンダ付けだけでは強度が不安なので、エポキシ接着剤で接着してある。
電子工作って、エポキシ接着剤と両面テープを良く使うよね?
■問題1
低いシステムクロックにするため、ウォッチドッグの内蔵発振器125KHzを使おうと思っていたが、カップラーメンタイマーとは言え時間を計るには、ちょっとばかり精度が悪そう。データシートでは125KHz/3V公称となっているが、データシート後ろのグラフを見ると結構ずれている。
結局、校正されている内蔵CR発振器を使うことに。今回は低い方の4.8MHzを使う。Tiny13にはシステムクロックの分周できる(CPUPR)のだが、これとヒューズビットのCKDIV8との関係はどうなっているのかと思ったら、CKDIV8がプログラムされるとCPUPRは8分周にセットされるらしい。逆に言うと別にCKDIV8をプログラムしなくても、後からCPUPRで分周値を設定できるってことか。
なお、CPUPRの設定はちょっと特殊な手順が必要。
■問題2
Tiny13には8ビットタイマーが一本だけ……。
この8ビットタイマーでシステムタイミングを作って、ブザーをドライブしなきゃならない。
システムタイミングをどれくらいで区切るか。ブザーは何Hzで鳴らすか。
■プログラム作成
テストバージョンとして、システムクロックを1.2MHz、ブザーの周波数を4KHzとして作成。大まかな骨組みはChaNさんのCircuitTesterを参考にした。システムの基底タイミングは、ある考えによって125ms(1/8秒)とした。
ブザーの周波数を4KHzにしたので、timer0はCTC動作で8KHz(125us)でOC0Aはトグル動作させる。また125us毎にOC0A割り込みを発生させる(ちょっと早い気もするが)。
パワーダウンモードからの復帰には、PB1~3のONによるピンチェンジによる。
大きな動きとして
①システム全体の初期化
②一旦パワーダウンモードに
③スイッチ1~3のON(ピンチェンジ検出)でパワーダウンから復帰。
④スイッチの状態で時間を決定し、時間計数動作
⑤終了ブザー制御
⑥時間計数後に②に戻る。無限ループ。
動作中にインディケートするLED等がないので、動作中を示すように5秒毎に音を鳴らすようにしている。また、何分のタイマーかも示すように、時間設定によって鳴動パターンを変えている。鳴動パターンは1/8秒単位で一秒分断続する形にした。
スイッチと設定出来る時間と鳴動パターン
SW1 | 3分 | HLHLHLLL |
SW2 | 4分 | HLHLHLHL |
SW3 | 5分 | HHLLLLLL |
SW1+SW4 | 6分 | HHLHLLLL |
SW2+SW4 | 7分 | HHLHLHLL |
SW3+SW4 | 8分 | HHLHLHLH |
鳴動パターン Hで鳴る、Lで無音
「+SW4」はSW4を押しながら他のスイッチを押す
OC0Aの割り込みを1000分周して125msのシステムタイミングにしている。システムタイミングは割り込みルーチンで直接操作せず、フラグのみ渡している。
最初はシステムクロックを1.2MHz にしていたが、一段落として600KHzにした。600KHz未満の周波数では、ブザーを8KHz(125us)にするとTimer0の設定値が割り切れなくなるので使用できない。
Timer0の設定値=125uSxシステムクロック=125uSx600KHz=75(実際は75-1)
ブザーの鳴動制御は、Timer0のTCCR0AのCOM0A0ビットでON/OFFしている。COM0A0ビット=1でOC0Aトグル出力、COM0A0ビット=0でPBO出力。PB0はL固定なので、ブザー周期のバースト出力とL出力が切替えができる。
ちょっとソフトプリスケールの分周比を間違ったりしてたけど、それなりに動作。一発動作とは言わないが、三発くらいで動いたのでいい気になっていたら、はたと気づく。
時間計数動作をキャンセルできない。
間違って設定したときに、その時間待つなんて出来ないよね。
ここからがたいへんなのであった。
■苦闘?
キャンセル操作として、再度いずれかのスイッチが押されたらキャンセルとするとした。
ただ、これがちと面倒くさい。パワーダウンから復帰と時間設定で押されたスイッチが一旦離された(OFF)ことを検出しなければならない。あるいはスイッチONのトリガーだけを検出出来るようにするか。ONトリガーを検出するための方法は手持ちにあるが、システムタイミングが125msではちょっと長い。
OC0A割り込みに別のソフトプリスケーラを組み込んでキースキャンに具合の良いタイミング(20ms)を作り、そこにトリガー検出のキースキャンを入れる。このルーチンのロジックは昔から使っている方法で、一つ前の状態と今の状態からチャタリング除去とトリガー(立ち上がり)検出が行える。
動作させたところ、おお、ちゃんとキャンセル出来る。うんうん。
じゃあ消費電流を確認しとくかと測ってみると、パワーダウンモードになってない(動作電流が500uAで、パワーダウンで0.5uA未満なので、なんとかテスターで測れる)。
なんで? その辺りは弄ってない。見た目の動作はするけど、肝心なパワーダウンしないの困る。
Timer0の周期を一段落として250KHzにもしてみたが、圧電スピーカーの周波数が2KHzでは音が小さくなりちょっと使えない。
スイッチの全部OFFを監視しても、誤動作することが多くてダメ。
鳴動パターンは変えたくないので、システムタイミングは125msから変えたくない。
どうやら、システムクロックの600KHzに対し、OC0A割り込み周期が短いため割り込み処理は75クロックを超えるのは不可なのに、それを超えることがある割り込みルーチンを書いていたことが原因っぽい。割り込み処理中に新しいOC0A割り込みが発生するけど、割り込み処理中なので許可されず、割り込みルーチンから復帰でメインループを一命令だけ実行してまた割り込みルーチンという動作なのだろう 。で、SLEEP命令のときに割り込みがかかるとどうなるかはデータシートを見ても不明。
小手先は止めて、根本的に修正。
ソフトプリスケーラを25ms周期に変更。以前あったdelayカウントやキースキャン処理は無くし、他の動作はしない。
メインループは二重にし、一段目は25mSのループ、二段目は一段目の5倍の125msとした。1段目はキースキャンを組み込み、2段目は以前と同じシステムタイミングを制御。これでなんとかキャンセルも効き、パワーダウンモードに入れるようになった。
■もうちょっと工夫
ちょっと使ってみて不便かもと思ったのは、動作中の時間経過がわからない点。表示が無いので残り時間は表示出来ないが、一工夫してみる。動作中のブザーの間隔を変えてみよう。
残り1分未満→2秒間隔
残り2分未満→3秒間隔
残り3分未満→4秒間隔
残り4分未満→5秒間隔
残り5分未満→6秒間隔
残り6分未満→7秒間隔
残り7分未満→8秒間隔
残り8分未満→9秒間隔
残り9分未満→10秒間隔
という感じで。
最小間隔を1秒にしていないのは、鳴動パターンによっては判別出来なくなるため。
■プログラムソース
まだバグが残っているかもしれないけれど公開版
使用状態 ROM 87.9% RAM 12.5%
chk_keyのロジックは、本来はもう一弾遅延させてエッジ抽出しているが、周期が25msと長めなので遅延一段でチャタリング除去とエッジ抽出(ONエッジ)を行っている。今の所は動作に問題は無いが、スイッチが劣化すると問題が出るかもしれない。ちなみにエッジ抽出のロジックを変えるとOFFエッジの抽出もできる。OFFエッジがわかれば長押し対応もできるはず。本来は10~20msの周期割り込み中でつかっている。トリガフラグはアプリケーション側が取得時にクリアする必要あり。
1段目のループの終端に気休めにアイドルモードしているが、どれくらい効いているんだろうか。
メインの計数ループと同じような2重ループがあるが、こちらは終了ブザーの制御部分。鳴動パターンHLHLLLLで、5秒間ブザーを鳴らす。
計数時間と鳴動パターンは、<avr/pgmspace.h>でプログラムメモリ上に配置した。あまり有り難味はないが(笑)
↑この辺は、今のAVRstudioではどうなん?
一応電流値
ブザーon0.53mA
ブザーoff0.35mA
パワーダウン時0.4uA未満
安いデジタルテスターなので、ブザー鳴動時には瞬間的にもっと流れている可能性があり。
オシロが壊れてしまったので、タイミング等は未測定です。タイマー時間に誤差があるかも。
ちなみにこの回路では、ISPの信号線とブザーが繋がっているので、ISPするとガーガー音がするよ。
コンパイル、書き込みはAVRstudio4を使用。
これはISPプログラマの古いやつしか持っていないから。プログラムもそれに合わせて書いた。
パチもんmk2を買った方が良いですか?
■操作説明
白 3分タイマー
黄 4分タイマー(最近、この時間のカップ麺があるので)
オレンジ 5分タイマー
青 このボタンを押しながら他のボタンを押すと+3分されます(パスタモード)
このボタンだけではパワーダウンモードは解除されません。
■追加な思案
電流を抑えるために出力はブザーだけにしたが、高輝度LEDなら数mAで結構明るいのでLEDを追加しても良いかもしれない。空いているポートがないので、ブザー出力と兼用するか、ISPを使わずパラレル書き込みでPB5を使うか。ただブザー出力と兼用すると、シンク接続では論理が逆だし、シンク/ソースどちらでもVoh,Volが変化してブザー音量に影響が出るだろう。ブザー出力と兼用するなら、デジトラ等で反転バッファした方が良いかも。
平均電流としては、高い周波数で動かしてさっさとアイドルするのと、低い周波数でチンタラ動かすのと、どっちが有利なんだろうか。
ユニバーサル基板で組んだけど、ケースどうしよう(笑)。使う環境が水分が多いだろうしなあ。3Dプリンタが欲しい。あ、ようつべで見たホットボンドでスマホのケースを作る方法を流用してみるか。
プリント基板を作る予定は無しですよ。
■保護カバーを作成
流石に剥き出しのままでは良くないので、絶縁と配線を保護するためにケースと言うかカバーを作ってみた。
以前Youtubeで見た方法で、スマホをラップで包み、その上からホットボンドで形成する。平面は凸凹するけど、スマホでは逆に滑り止めになって良いみたい。
で、作ってみた。結構、メルターの動かし方とボンドの流量のコントロールが難しい。縁で裏面から表面に向けてのフックになる部分がうまくできない。スマホの様にある程度厚みがある方が良いのか? でもフックの部分を大仰に作りすぎると、ホットボンドが多少伸縮性があっても、はめ込む時に苦労しそうだしね。
Youtubeで使っていたラップの材質が違うのか、ラップが上手く剥がれない。本体に引っ掛ける部分が、思いの外弱そう。まあ、ホットボンドだから修復は簡単だけれど(笑)
絶縁と配線の保護が目的で、防水は考えていない。防水を考えると、スイッチやブザーから考えないとダメだろうし、水かぶったら自分で治す、それが自作のいいところ。
黒のマジックははめ込む方向を示したマーク。
保護カバーをはめたらこんな感じ。不格好すぎるが、使うのは自分だけだ(笑)。これでステンレスのシンクに置いても平気。