今から始めるAVR #4 ATtiny2313 7セグ4桁ボード〜こんなアプリが動く
2008年10月 前回で7セグ4桁ボードが完成しました。ソフト次第で何にでも使えます。 今回は応用例をいくつか紹介します。 表示画面が数字の形なので、タイマーやカウンターは作っておきたいところです。 時間計測の代表格は時計ですが、それはまたの機会に紹介します。 7セグで表示できるのは何も数字だけではありません。 セグメントをバラバラに考えて記号や図形を表示してもよいのです。 その例としてゲームも作ってみました。 |
7セグ4桁ボードで動くアプリ
アプリが動作するボードのタイプについて 以下で公開するアプリのソースはカソードコモンの7セグ4桁ボード用になっています。先頭付近の行にある、 #define _CATHODE_CMN_ 1 の1を0にするとアノードコモン用のボードでアプリが実行できます。 ソースは拡張子.txtを.cに変更して使ってください。 改行コードはCRLF、TABは4スペースで記述しています。 ブラウザで閲覧して文字化けする場合、文字コードに日本語Shift-JISを指定してください。 |
|
(動画) ラーメンタイマー7セグ版(デモ) 動画はデモ用なので10倍速ですが 実際は正しく動きます。 |
3分タイマー(ラーメンタイマー) ソースはここをクリック。 「今から始めるAVR #1 導入〜ATtiny2313テストボード」で作った3分タイマーの7セグ版です。 スイッチA0で計時開始。0.00〜3.00。3.00で点滅。 スイッチA1で中止(リセット)。 ATtiny2313テストボード版3分タイマーと同じ理由で、この7セグ版3分タイマーも正確な時間を計れません。何秒かずれます。 ※ラーメンが伸びるほど狂ってはいないので安心して使ってください。 |
(動画) ストップウォッチ(デモ) 動画はデモ用なので途中で時間が 飛びます。実際は正しく動きます。 0.00.0〜(一時停止)〜0.30.0→ 0.55.0〜1.10.0→ 9.50.0〜(表示変更)〜10.20→ 99.50〜99.59(終了) |
ストップウォッチ ソースはここをクリック。 最初の10分は1/100秒単位で表示。0.00.0〜9.59.9(9分59秒9) 10分からは99分59秒まで1秒単位で表示。10.00〜99.59 スイッチA0で計測開始。計測中、同じくスイッチA0で一時停止、再開。 スイッチA1で中止(リセット)。 1/100秒単位の計測は最初の10分だけですが、ストップウォッチを使いたいときは比較的短時間を計測することが多いので、10分あれば事足りると思います。 長時間を計測したいとき……例えば何か作業をしていて、途中で休憩をはさんで作業を再開するようなとき、全部で何分作業したか計りたいことがあります。このような使い方を考慮して一時停止機能を付けました。 LAPタイムの確認ならともかく、ストップウォッチで完全な一時停止というのは奇妙かもしれませんが、長時間を計測する目的の時はあると便利な機能です。 このアプリも他の時間計測系のアプリと同様に正確な時間を計れません。「大体の時間」のつもりで使ってください。 |
(動画) HAKO(箱) |
HAKO(箱) ソースはここをクリック。 7セグなのに敢えて数字表現を使わないゲームを作りました。 タイマー/カウンタ割り込みを使わないシンプルなプログラムです。 【ゲーム内容】 3個の箱の位置を当てるゲーム。 【ゲームの始め方】 電源オンでタイトル画面「HAKO」。 スイッチA0/A1でゲーム開始。 【ゲームの操作方法】 1〜3桁目が箱、4桁目が現在当たっている個数。 スイッチA0: 桁を移動する。「.」が付いている桁が現在操作できる。 スイッチA1: 1〜3桁目のとき、箱を上下する。 4桁目のとき、回答する。 【判定】 回答は3回まで。 正解すると「Good」、スイッチA0/A1で次の問題へ。 外れると、現在当たっている個数が表示される。ゲーム続行。 3回目も外れると「bYE」、スイッチA0/A1でタイトル画面へ。 |
(動画) S.ATK(セグメントアタック) |
S.ATK(セグメントアタック) ソースはここをクリック。 パズルアクションゲームを作りました。 表示画面が7セグでも、4桁あれば案外ゲームは作れるもんです。 もし技術的に何か工夫するなら、PWM制御で明るさの違う表示を混ぜて見た目の変化を付ける、など考えられます。 ゲーム内容の工夫はソースを自由に改造して楽しんでください。例えば、かけらを複数同時に発生して投げられるようにするとパズル要素が高まります(難易度も上がりますが)。かけらを弾のように移動させたり、敵が飛び散るなど演出に凝るのもよいと思います。 【ゲーム内容】 壊れた数字にセグメント(数字のかけら)を投げつけて倒すゲーム。 【ゲームの始め方】 電源オンでタイトル画面「S.ATK」。 スイッチA0でゲーム開始。 スイッチA1でハイスコア画面へ。 【ゲームの操作方法】 1桁目が投げるかけら、4桁目が壊れている数字。 スイッチA0: かけらを投げる。 スイッチA1: ゲーム中は使用せず。 【ゲームの遊び方】 プレイヤー(1桁目)が投げるかけらがランダムで表示される。 投げたかけらが壊れた数字にはまって、数字が完成したら1個クリア(倒した)。 完成すると目印として「.」が付いた後、数字ごと消え、次の壊れた数字が現れる。 既に数字の一部があるところへ投げたら、その位置のかけらは消える。 一定時間が経過するとごとに壊れた数字はプレイヤー側へ移動してくる。 プレイヤーに重なったらゲームオーバー、スイッチA0/A1でスコア画面へ。 スコア画面からスイッチA0/A1でハイスコア画面へ。 ハイスコア画面からスイッチA0/A1でタイトル画面へ。 ※スコア画面の「P.」はポイント(Point)、ハイスコア画面の「H.」はハイスコア(HiScore)の意味。 |
乱数について ゲームで乱数を使います。 「HAKO」ではstdlib.hをインクルードして標準関数のrand()を使いました。 「S.ATK」でも最初はそうしたのですが、一旦完成したときプログラムサイズが1700byteくらいになりました。ATtiny2313のプログラムサイズの上限は2048byteなのでまだ余裕はあります。 しかし標準関数のrand()を組み込んだ影響でサイズが大きくなったことに気付いたので、これを使わないように変更しました。 結局、自作rand()関数ではCの標準関数で使われている(いた)ものとしてよく知られている乱数の式をそのまま使っています。検索サイトから「1103515245」で検索してみてください。 標準ライブラリを組み込まず、この関数を直接使うことでプログラムサイズが300byte程度減らせました。 ※余談ですが… ファイルを分けず、関数やポインタの使用を避け、長くなろうともswitch()文に詰め込むなどは、意図的にそうしています。 |
|
正確な時間を求めるには 7セグ4桁ボードの核であるATtiny2313は今のところ内部発振器によって動作しています。これまでに紹介した時間を計測するアプリもこのクロック(動作周波数)が基準となります。 内部発振器はRC発振器で、その正確さは電圧や気温などに大きく左右されます。 私は時計アプリを作って試験的に使っていますが、どれだけ調整しても必ず狂います(アプリのせいではなく)。 この不正確なクロックの問題を解決するには、正確な外部発振器でATtiny2313を動作させるしかありません。 実はもうその計画はできています。上記写真で赤い7セグの方のボードを見てください。スイッチが基板の部品面でマイコンに配線されています(正面中央、抵抗の隙間が空いてるところ)。この配線されているI/Oピンが外部発振器を接続する専用のI/Oピンです。つまりスイッチの入力を簡単に他のI/Oピンへ移せるようにしてあるのです。 外部発振器の取り付け検討については前回の記事中「なぜこのようなピンアサインにしたのか」を読んでください。 7セグ4桁ボードに外部発振器(クリスタル)を取り付ける工作と説明は記事にして公開する予定です。 |
7セグのフォント
7セグで数字やアルファベットを形作るフォントに、これだという標準形は特にありません。それでも高々7個のセグメントの組み合わせですから、誰が作っても似たものになります。ここでは私が作ったフォントを紹介します。 1行目は数字です。 「6」のセグメントA、「7」のセグメントF、「9」のセグメントDを付けるか付けないかは好みによります。 私は付けます。「6」「9」でそれぞれを付けないと、アルファベット小文字「b」「q」と区別が付かないからです。「7」はアルファベット大文字「T」との違いを明確にするために付けます。 2,3行目はアルファベット大文字、小文字です。 大文字小文字それぞれ26文字全てを7セグで表現することは無理なので、大文字小文字合わせて26文字をカバーするようにします。 大文字優先で考えて、作れないときは小文字を考える。大文字があっても小文字が作れれば作る。……という方針で作りました。 2行目、大文字について。 「I」は左側のセグメントを使っていて、数字「1」(右側のセグメント)と違うので区別できます。 「K」「M」「Q」「T」は若干苦しいながらも、元の字形を生かした記号化ができています。「Q」のデザインは最後の一画を強調しています。「T」は左右反転させた形(セグメントABC)も考えられますが、それだと数字「7」と認識しやすいので、こちらの向き(セグメントAFE)にしました。 「O」「S」は数字「0」「5」と同じです。実際に使うときは前後の文字も同じくアルファベット/数字であることが普通ですから、「O」と「0」、「S」と「5」はそれぞれ区別が付きます。 「O」は小文字「o」が作れるので大文字は無理に入れなくてもよいのですが、なるべく大文字は多い方がよいと思うので入れました。 「V」は斜体のイメージです。ギリシャ文字の「ν」(ニュー)みたいな形です。 「W」「X」「Z」は「言われてみれば元の字形の面影もあるような……?」という苦しい記号化です。 「Y」は筆記体のイメージです。小文字を考えると数字「4」と同じになってしまうので無しです。 3行目、小文字について。 「l」(エル)は大文字「I」(アイ)と同じです。大文字が作れているので小文字は無くてもよいのですが、独断で入れてしまいます。他にもこの2文字の区別が付かないフォントはよくあります。「Illustrate」の最初の3本が同じにしか見えないフォント、心当たりありませんか? 「v」「w」「x」「y」「z」はよく使いそうな割に7セグで作れないのが残念です。 ところで「l」は入れたくせに「g」は無しです。「g」は数字「9」と同じになります。「O」「S」と同様、前後の文字から区別が付くと思ったのですが、アルファベットに挟まれていても「9」と認識してしまうので無しにしました。小文字なのに大文字と同じ大きさ→アルファベット小文字だと認識しづらい→数字とも同じ大きさ→7セグゆえ優先的に数字として認識してしまう……といったことが原因じゃないかと思います。心理的に。 4行目は曜日です。 「Sun.」「Mon.」「Tue.」「Wed.」「Thu.」「Fri.」「Sat.」をこのフォントで表現するとこうなります。 見事に「大文字+小文字+小文字」で揃います。自分の時計アプリで使っています。 |
今回の記事を書いていて、別の角度からこの7セグ4桁ボードを 人に知ってもらえそうな方法を思い付きました。 それがケータイアプリとの連動企画です。 ハードを作ってケータイアプリでPR、こういうことをやっている人は 多分いないと思います。私が初めてじゃないでしょうか。なーんて。 |