190921:作成
もどる
■発端
「余っている90S2313で何か作る」シリーズ。
仕事でも趣味でも7segLEDを光らすこと無くったなあ。4桁アノードコモンのが余っているしなあ。
7segLED良いよね。でも、ネタがない。まさか時計ってわけにはいくまい(笑)。
時計……タイマー? キッチンタイマーで4桁LEDは大仰すぎるしなあ。
タイマー、タイマー……
そんなに熱心にストレッチとかやらないけど、あれのタイマーはどうだろう。
実際、運動している時は時間は確認できない。セット回数も「あれ? 何回目?」ってなるし。
セット回数、運動時間、休止時間をリスト化していくつかの時間設定を選択できれば良いんじゃないか。
■目標仕様
・トレーニグタイマー。運動時間、休止時間、セット回数をカウント。セットリストは4~8個。
・電源は持ち運びを考えて電池駆動にしたい。
・試しに書いていたAT90S1200のダイナミック点灯回路から転用。
・自励式で良いからブザーは欲しい。
・できるだけシンプルに。
■仕様検討
・AT90S1200のダイナミック点灯回路では8chのシンクドライバを使っているが、部品削減のために削除。4桁のダイナミック点灯なので20mAも流せばいけるはず。
・7segで8本、コモンのドライブで4本。残りは3本。ブザーに1本使うから、スイッチ入力は2本まで。
・コモンのドライブと組み合わせてマトリクスにすればスイッチの数は増やせるが、シンプルにしたいのでスイッチは2個でなんとかしよう。
・7seg側はアノードコモンなのでシンク。LEDの点灯は負論理。表示パターンはテーブル化。
・7segのアノードコモン側は、部品箱にあった2SA1015でドライブ。
・スキャン信号はシフトとかで作れないことはないが、これもパターンをテーブル化。(わずかとは言え、スキャン番号によって時間が違うのは気持ち悪いよね(笑))
・7segのシンク側は8本揃っているPBポートを、それ以外はPDポートを配分。
・自励式圧電ブザーは新しく買った。データシートにはmax30mAとある。駆動電圧によって変わるのだろうけど、念の為2SC1815でドライブ。
・基本タイミングは16bitTimer1をCTCモードで使用。割り込みはSIG_OUTPUT_COMPARE1Aを。
・システムタイミングは4mstickで使用する。LEDダイナミック点灯のタイミングは4msx4degitで16ms。
・源振には余っていた3.58MHzのセラミック振動子を。手持ちにコレより低いのはなかった。
■回路図
回路はコンパクト秋月電子のC基板に組んだ。実は回路図には電源と電源スイッチがないので、あとでちょっと配置に困ることになる。
元のAT90S1200の回路図ではINT0によるシリアル入力だったが、PD0(RXD)、PD1(TXD)をスイッチ入力している点でなんだか流用する気があるんだろうな。
■プログラム作成
システムタイミングの割り込み周期は、OCR1A = (FOSC/1000)*4で4msの割り込み。楽ちん。
プログラムはモード(シーケンス)によるループ。
大きく分けてモード制御と表示制御の2つ。
モード(シーケンス)は、
typedef enum {
mSetSelect,
mWaitTimer,
mMotion,
mPause,
mSetDown
} mSEQ; の5ステップ。
スイッチ入力のチャタキャンセル、トリガ検出は、いつもの怪しいルーチンでトリガ検出。
表示周りは割り込みルーチンに組み込み。このレベルで表示処理は、7segの各bitに対応したバッファ(4桁分)をスキャン番号(桁位置)に出力するだけ。数字→表示パターン変換はその都度別途行う。バッファに直接書き込めば、数字ではないパターンも表示可能。表示パターンは負論理。
セットリストは今の所4つ。セットリストで設定できるのは、セット回数、動作時間、休止時間。時間は秒単位で最大255秒まで。セット回数は10回まで。
電源ON直後はSetSelectで4つからSW1(黒)で選択。「SET0」→「SET1」→「SET2」→「SET3」→「SET0」→と循環。
選択後、SW0(白)で運動スタート。
ただし、最初の回だけ5秒の待機時間がある。「P.」+秒数表示
例えば表示が「8. 20」の場合
最上位はセット回数。下位3桁は秒数。
待機後、運動時間、休止時間で指定回数繰り返し。
動作時間、休止時間とも減算表示。
運動時間表示のときは最下位のDP点灯、休止時間は表示ブリンク。
運動時間、休止時間には1秒毎のブザー音が鳴る。
見ないでも聞き分けられるように運動表示のときは短い1回(0.1秒)、休止表示のときは短い2回のブザー音。
繰り返し回数も減算表示で、回数終了のとき長め(0.4秒)のブザー音。
大体こんな動作でROM50%くらい
■ちょっと改良
まずセットリスト数を4から8個に拡張。ただ、数が増えるとリスト内容が判らんちんになるので、セットリスト選択時に運動時間と休止時間を順次表示。
運動カウント中にSW0(白)を押すと一時停止。SW1(黒)を押すとカウントをキャンセルし、セットリスト選択に戻る。
プランクで30秒から始めて1秒ずつ足していくトレーニングがあるらしい。
+1していくには書き換え可能にする必要があるので、セットリストテーブルをEEPROMに移す。
実はAVRでEEPROMを弄るのは始めてだったりする。
操作方法は、SW0(白)を押しながら電源を入れると+1、SW1(黒)を押しながらだと初期値(30秒)に戻す方法にした。
この操作はセットリストの0番専用になっている。
Program: 1864 bytes (91.0% Full)
(.text + .data + .bootloader)
Data: 16 bytes (12.5% Full)
(.data + .bss + .noinit)
EEPROM: 24 bytes (18.8% Full)
(.eeprom)
電流を計ってみたが、ちょっと多いか。テスターでmax80mA
そのまま、雑に計算して2000mAhのNiHMで 2000mA/80mA=25
25時間かあ、マイコンの省電力を入れても大したことないかな。
気休めにメインループ終端にアイドルモードでスリープさせてあるけど。
LEDの抵抗をもうちょい大きくしていいかも。ちょっと明るすぎるし。(このボードは直さない)
R=(Vcc-Vol-Vf-Vec)/20mA=(5-0.6-2.0-0.1)/20mA=2.3/20mA=115ohmで120にしているけど、
10mAでは暗いか? 15mAだと153.33ohmか。150ohmくらいだとどうかな。
■プログラム
とりあえずFix版
現在のセットリスト内容
EEMEM uint8_t SetPattern[8][3]= {
// Set Motion Pause
{ 1, 30, 0 }, // 0 1set,30sec,0sec
{ 10, 20, 10 }, // 1 10set,30sec,10sec
{ 10, 50, 10 }, // 2 10set,50sec,10sec
{ 1, 60, 0 }, // 3 1set,60sec,0sec
{ 5, 60, 0 }, // 4 5set,60sec,0sec
{ 10, 60, 0 }, // 5 10set,60sec,0sec
{ 10, 120, 0 }, // 6 10set,120sec,0sec(20min)
{ 10, 180, 0 } // 7 10set,180sec,0sec(30min)
};
0番はプランク専用
1番はちょっと重い運動で運動時間短めのもの
2番は運動時間長めで1セットが1分になるもの
3番は1分運動用
4番は5分運動用
5番は10分運動用
6番は20分運動用
7番は30分運動用
まだ、どういう時間組み合わせがいいか手探り状態なので、変わる可能性が大きい。
■追加な思案
基本的に屋内か雨のない環境で使うつもりなので、ケースのことは考えていない。スペーサを組み合わせて「足」にしている。
最初は逆接続防止のショットキーダイオードをスイッチ直後に入れていたが、新しく買った電池ボックスには逆挿入防止になっていたのでダイオードはパスしている。
電源は単3を4本にしているが、ダイナミック点灯なのでNiHM専用としている。普通の乾電池は、新品だと1.6V近くあったりするのでオススメはしない。
逆電圧防止のダイオードが無い状態なのでダイオードの降下分も無い。まあ実力で動くだろうけど。
表示が4桁しかないので、セット回数が10回までになってしまったのがちょっと不満。時間表示を99秒までに限定すれば、セット回数も2桁にできるんだけど、どっちが良いのかまだわからない。
セットリストの編集機能を入れたいが、ROM容量が厳しいし、ボタン2個じゃ操作できそうに無い。EEPROM上にあるが、書き換えるにはISPが必要。
8bitTimer0を使ってないのでブザーを他励式にしたいが、データシート確認したらTimer0には出力がなかった。割り込みを使って汎用ポートを駆動してもいいんだけど。
LCD表示版も作ってみたい気もする。ただ、視認性を上げるためにバックライトとか使うと、場合によってはLEDダイナミック点灯と同じくらい電流が流れるからなあ。
文字が大きめのLCDモジュールってあまりないし、今年はもうLCDモジュールを買わないと約束したからなあ(自分とね)。
もっと沢山の7segを点灯したい! スキャンラインのデコーダを外の部品まかせれば、16桁くらいなら表示できそうなんだけどな。
あと、この回路を流用してアナログゲームの点数表示器とかはどうだろう? 上限点数のテーブル作って、点数に達したらブザーならすとか。
やろうと思えばスマートフォンのアプリで実現できるけど、それでも7segLEDはいいねぇ