| ホーム |     私の電子工作作品集

184. ストップウオッチ II

[ 初公開日:2020年6月1日 ]

 私は以前から健康のために毎日ではないですが、週に3、4日ぐらいのペースで日に2時間ほどの散歩というかウォーキングをしています。 我が家の近所地域を歩くことがほとんどですが、 それでも飽きることがないように、東西南北いろいろな方向のコースをいくつも自分なりに設定をしていて、毎回ローテーションで回しながらなるべく異なったコースになるように務めています。

 また、同じコースを歩くことになっても、前回右回りだったから今回は逆の左回りにしようとか、そんな変化を加えながら自分なりにウォーキングを楽しんではいるのですが、以前からずっと気になっていることがありました。 それは同じコースを歩いていて、例えば出発から帰着までに要した時間はもちろんのこと、A地点からB地点までに要した時間とかが、前回と今回とではどのぐらい異なっているか。 しかも、この地点間の所要時間が1か所だけではなく複数あって、それらを簡単に把握できないものか。など。


 数年も以前からそのような時間計測ができるものを作ってみたい、と思っていました。 そんな構想を抱きながら今日に至っていたのですが、最近(といっても半年ほど以前)になって、"秋月電子通商" の商品カタログにある "I2C接続小型キャラクタLCDモジュール [AQM0802A-RN-GBW] " の消費電流が 1 mA という低消費であることを知って、一気に製作意欲が湧いてきました。

 製作物はウォーキングに携行できるものでなければなりません。 アマチュアが作るものですからある程度のサイズになることは仕方がありませんが、装置としてできる限り小型でそして低消費電流のものが望まれます。 上述のように週に3、4回、日に2時間ほどの、結構長丁場のウォーキングの友ができるように、電源には単4電池3本を使用としました。

 そんな構想で製作をしたストップウオッチは、長時間の使用に耐えられるように、低消費電流のLCDモジュールの採用だけでなく、スイッチ操作が一定時間なかったときにはスリープモードに移行して、 積極的に省電力化を図るようにしています。

 また、私の拘りで予め設定(任意であり必須ではない)をしておけば、携行中に現在時刻の表示も可能なようにしました。 メイン機能のストップウオッチとしての時間計測には、歩きながらでも簡単なスイッチ操作で、 (内蔵メモリ量の関係で)最大 58 個 (PIC16F628A の場合) / 68 個 (PIC16F648A の場合) までの、スプリットタイムとラップタイムの測定を記憶・表示が可能です。

■ 回路図 ■

*注. RA4 の出力はオープンドレインのため、外部抵抗でプルアップしないと、High が出力されない。 RA5 は入力専用で、出力ポートには使えない。
   RB1 〜 RB5 は内部プルアップ機能を ON にして使用。 また、SLEEP 中には RB4, RB5 にポート変化割り込み機能を使用。

| 回路図 (StopWatchII.CE3) | ページトップ |

■ ケース外観と内部の様子 ■

ケース正面の斜め上から見たところ ケース左側面の斜め上から見たところ ケース裏面の斜め上から見たところ
ケース右側面の斜め上から見たところ 蓋をあけてケース右側面の斜め上から見たところ
ケース上面を真上から見たところ 蓋をあけて内部を真上から見たところ( 拡大 ケース裏面を真上から見たところ

| ページトップ |

■ 機能概要と使用法 ■

  • 本機は、ウォーキングの友として毎日(1回あたり数時間程度)の比較的長時間の携行使用ができるように、なるべく電池の消耗が少なくて済むような考慮をしており、単4電池3本を電源としたストップウオッチである。 省電力化を第一としているため、測定ができる時間の最小単位は1秒で、それ以下の詳細な測定は本機ではできない。

  • 初めに、本機には次の遷移図に示すように大きく分けて3つのモードがあり、(XXXX) で示す各スイッチを操作することでそれらのモード間を移動する。 (XXXX) + (XXXX) と表現されているものは、+ 印の左側スイッチを押しながら 右側スイッチをちょんと押すことを表している。


    時刻設定・モード ........ 現在の時刻を設定する(必須ではない、省略可)。 設定された時刻をもとにストップウオッチが動作中は現在時刻を表示し続ける。
    ストップウオッチ・モード ........ ユーザがスイッチ操作をする度に、そのときのスプリットタイムをメモリ内に記憶しつつ、時間計算によってラップタイムを表示する。
    メモリ内容表示・モード ........ ストップウオッチ・モード中に記憶したメモリ内容を読み出し、改めてスプリットタイムとラップタイムを表示する。

  • なお、ストップウオッチ・モード、およびメモリ内容表示・モードのときに、(SELECT) + (START) のスイッチ操作をすると1つ前のモードに戻ることができるが、それまでに記憶したすべてのスプリットタイムが 無効となるので注意が必要である。

  • また、これらの3つのモードとは別に、ストップウオッチ・モードとメモリ内容表示・モードにおいては、ユーザのスイッチ操作が一定時間なかったときには スリープモード に移行し、 液晶(LCD)表示も消して省電力化を図るようにしている。 そして、このスリープモード中に (ENABLE) または (START) スイッチを操作することで、すぐに目覚めて元のモードに戻ることもできる。

  • さて、本機の電源スイッチをオンにすると、"ピポッ" と開始ブザー音とともに LED(緑) を点滅表示した後、LCDにも次の開始メッセージが交互に2秒間ずつ連続2回表示される。
      			[ ** Stop- ]			[ Ver x.xx ]
      			[ Watch ** ]			[  by M.Y  ]
      
 ◆ 時刻設定・モード ◆
  • その後、2秒間無表示の後、次のメッセージが表示され、"ピポッピポッ" ブザー音とともに LED(緑) を点滅表示して、本機が 時刻設定・モード に移行したことを知らせる。 そして、その後はユーザからの各種スイッチの入力待ちとなる。
      			[ Time Set ]
      			[ 00:00:00 ]	..... 2行目の先頭の "0" がブリンク表示される。
      

  • なお、本機には次図に示すように5個のスイッチが用意されており、本モードにおいては各スイッチを赤字で示した名前で呼ぶこととする。
  • 本機の機能の1つとして予め設定された時刻をもとに、ストップウオッチが動作中にも現在時刻を表示し続ける機能を持たせてある。 そのために初めに時刻を設定することを本モードで行うように想定しているが、 必須ではないため不要な場合には省略をしても構わないが、その場合には、ストップウオッチの動作中に無意味な時刻表示がされ続けることになる。

  • 本モードに移行した直後には、LCDの2行目には [ 00:00:00 ] と "時":"分":"秒" の形式で初期値が表示され、かつ、先頭(左端)の "0" がブリンク表示されている。 このブリンク表示されている位置の桁が今選択されていることを意味し、(SELECT) スイッチを押すことによってその選択桁を自由に変更することができる。

  • (SELECT) スイッチ を押すごとに選択桁が右に移動して行き、右端(一秒桁)の次には再び左端(十時桁)に戻る。 この選択桁を変更するときに、(START) スイッチを押しながら (SELECT) スイッチを押す ( (START) スイッチ + (SELECT) スイッチ ) と、押すごとに逆の左に移動して行き、左端(十時桁)の次には再び右端(一秒桁)に戻る。

  • 現在時刻を設定するときに、このようにしてまず、希望する "時"、"分"、"秒" それぞれの "十位"、または "一位" の桁を選択しておいて、次に (UP) スイッチ、または (DOWN) スイッチを操作することによって、 現在時刻に合わせることができる。

  • (UP) スイッチ は、現在表示されている値を押すごとに +1 ずつ増加(インクリメント)し、また、(DOWN) スイッチ は、逆に押すごとに −1 ずつ減少(デクリメント)する。 そして、(UP) スイッチの操作では、各桁の最大値を超えると "0" に戻る。 また (DOWN) スイッチの操作では、各桁の最小値の "0" を超えると各桁の最大値に戻る。

  • ただし "時" の入力では、"00" から "29" まで変更が可能であるが、"24" 以上を入力した場合には、その後 (SELECT) スイッチ、または (START) スイッチ + (SELECT) スイッチの操作を行なっても 他桁への移行はできず、"ブッ" というブザー音とともに赤色LEDが瞬間点滅して、エラー表示をする。

  • 本機ではこのようにして設定した設定値を、予め プリセット値 として登録をしておくことができる。 ウォーキング(散歩)というものは、毎日朝、または夕方の同時刻ごろに出かけることが多いため、 本機を次回(翌日など)の使用時には、登録しておいたプリセット値を呼び出して、その設定時刻をわずかな修正だけで済むように考慮をした。

  • (START) スイッチ + (UP) スイッチ の操作をすると、現在LCDに表示されている "時"、"分"、"秒" がプリセット値として、PICの内蔵メモリ(EEPROM)に書き込まれる。 また、 このプリセット値を読み出す場合には (START) スイッチ + (DOWN) スイッチ の操作をすると、現在LCDに表示されている "時"、"分"、"秒" がプリセット値に置き換わる。

  • ここで、プリセット値の登録数は5つまで * とした。 無駄を省くため書き込み時にチェックをして同値は書き込まないようにしている。 読み出し時には (START) スイッチ + (DOWN) スイッチ の操作を繰り返すごとに、登録数だけ変更表示されるので希望値を選択する。 ただし、最終値の表示の次には [ 00:00:00 ] を一度表示するようにした。
    * 実際にはもっと多くの数を登録することも可能であるが、逆に選択が面倒にもなるため最大5つに制限をした。)

  • なお、5つ以上の書き込みを行った場合には、最も古いものから順に消されて新しいものが登録され、いつも5つまでを保持する。 読み出しのときは最も古いものから順に読み出される。

  • このようにして設定をした設定値が実際に時刻として有効になるのは、次に (SET) スイッチ を押した瞬間からである。 その瞬間に本モードの時刻設定・モードは終了をして、次の ストップウオッチ・モードに移行をし、そして、時刻のカウントを開始する。 なお、このとき (START) スイッチ + (SET) スイッチ というスイッチ操作もあり、 その相違はストップウオッチ・モード中の 説明 を参照のこと。

  • ここで、時刻設定・モードにおいてのスイッチ操作をまとめておくと、次のようになる。

      (SELECT) スイッチ ........ 選択桁が右に1桁移動する (ブリンク位置ポインタ + 1)
      (START) スイッチ + (SELECT) スイッチ ........ 選択桁が左に1桁移動する (ブリンク位置ポインタ - 1)
      (UP) スイッチ ........ 選択桁の値をインクリメントする (ブリンク位置の値 + 1)
      (DOWN) スイッチ ........ 選択桁の値をデクリメントする (ブリンク位置の値 - 1)
      (START) スイッチ + (UP) スイッチ ........ EEPROM へプリセット値を書き込む
      (START) スイッチ + (DOWN) スイッチ ........ EEPROM からプリセット値を読み出す
      (SET) スイッチ ........ 時刻設定・モードを終了をする
      (START) スイッチ + (SET) スイッチ ........ 時刻設定・モードを終了をする、(スリープモード中のブザー音を抑止する) *
      * ストップウオッチ・モード中の 説明 を参照のこと )
 ◆ ストップウオッチ・モード ◆
  • 上で述べたように、(SET) スイッチを押した瞬間に時刻設定・モードが終了をして、そのまま ストップウオッチ・モード に移行をする。 そして、移行をした直後に 現在時刻 のカウントが開始されLCDには次のメッセージが表示されて、"ピポッピポッ" ブザー音とともに LED(緑) を点滅表示してそれを知らせる。 その後はユーザからの指示としてのスイッチの入力待ちとなる。
      			[ Start On ]
      			[ xx:xx:xx ]	..... 2行目に刻々と現在時刻が刻まれながら表示される。
      

  • ストップウオッチ・モードにおいて使用するスイッチは○色のスイッチを除いた3個で、本モードにおいては各スイッチを赤字で示した名前で呼ぶこととする。
  • なお、時刻設定・モード では述べなかったが、右2個のスイッチは他の3個のスイッチに比べてキートップ長が長いものを採用し、本機のケースの蓋を閉めた状態でも頭がケース外に飛び出すような構造にケース加工を施してあり、 その他のスイッチはケース内に隠れてしまう。 これは、ウォーキングを開始以降はその途中で右2個のスイッチ以外には触れられないようにするためである。

  • 次図は、本モードに移行してから本モードを終了(メモリ内容表示・モードへ移行)するまでを図に表したもので、初めに、前モードの時刻設定・モード のときに (SET) スイッチ の操作を契機として本モードに移行をし、 予め設定されていた時刻から現在時刻のカウントが開始される。


  • その後、ウォーキングを開始すると同時に、ユーザからは最初の (1) (ENABLE) スイッチ + (START) スイッチ 操作(上図で START の (1) の位置)が行われて、それを契機として スプリットタイム のカウントが [ 00:00:00 ] から開始され、LCDの1行目に表示がされるようになる。 そして、"ド ミ ソ ドー" ブザー音とともに LED(緑)(赤) が交互に点滅して、スプリットタイムのカウントが スタート (START) をしたことを知らせる。
      			[ 00:00:00 ]	..... 1行目にスプリットタイムのカウントが開始される。
      			[ xx:xx:xx ]	..... 2行目に刻々と現在時刻が刻まれながら表示される。
      

  • ウォーキングが始まると、本機は上図で (1)、および (2) の操作をするための各チェック地点以外では、邪魔となってポケットなどに入れられることを想定しており、そのために起こるであろう、 チェック地点以外でのスイッチの誤操作を極力防ぐために、2個のスイッチを組み合わせたスイッチ操作を採用している。 すなわち、(ENABLE) スイッチを押しながら (START) スイッチを押す (ENABLE) スイッチ + (START) スイッチ という方法である。

  • また、START の (1) を除いた各チェック地点での (1) のスイッチ操作ごとに、その時点の スプリットタイム がPICに内蔵のメモリ(SRAM)に書き込まれて記憶され、これを知らせるために "ポポッ" ブザー音とともに LED(緑) を点滅表示させる。 そしてその直後に、LCDの表示が一時的に約3秒間だけ次のように変わって、そのときの 記憶番号(チェック地点番号)とラップタイムが表示される。 ラップタイム は、今回測定したスプリットタイムと、前回測定してメモリ(SRAM)に記憶されているスプリットタイムとの差を、時間計算によって求めたものである。
      			[ ** xx ** ]	..... 1行目の xx に記憶番号が表示される。
      			[ xx:xx:xx ]	..... 2行目にラップタイムが表示される。
      

  • このとき、内蔵のメモリ(SRAM)に書き込むことが可能なスプリットタイムの最大数は、PIC16F628A を使用の場合には 58 個、PIC16F648A を使用の場合には 68 個までである。 もしも、 これらの最大個数になっているときに、 なおも記憶をさせようとしたときには、次のようなエラーメッセージをLCDに表示をして、かつ、"ブッブッブッブッ" ブザー音とともに LED(赤) が数秒間点滅を繰り返えす。
      			[ xx:xx:xx ]
      			[ Mem Over ]	..... 2行目にメモリオーバーエラーメッセージが表示される。
      

  • このようにウォーキング中は、各チェック地点で (1) のスイッチ操作をするだけで、それ以外のときにはスイッチ操作をする必要がないため、ユーザのスイッチ操作が一定時間(現在1分に設定)なかったときには、 LCDの電源を OFF にし PICも スリープモード に移行して省電力化を図るようにしている。 なお、このスリープモード中であっても (ENABLE) スイッチ、または (START) スイッチ のどちらかを操作することによって、いつでも即座に目覚めさせることができる。

  • また、スリープモード中にも本機の存在感を誇示するために、1分間に1度、瞬間 "ピッ" ブザー音とともに LED(赤) を点灯させている。 ただし、時刻設定・モードから本モードへの移行時に (START) スイッチ + (SET) スイッチの 操作をした場合には、"ピッ" ブザー音は抑止され LED(赤) だけを瞬間点灯させる。

  • さて、ウォーキングも終盤に近づいていよいよゴールをする場合には、上図のように (2) のスイッチ操作をするが、(1) と同じスイッチを使用するために両者の区別をしなければならない。 そこで (2) の場合には 5秒間ほどの長押しをしていると、"ド ソ ミ ドー" ブザー音が鳴り出すとともに LED(緑)(赤) が交互に点滅するので、それを合図に (2) の操作を止めるようにする。

  • このとき、ゴール地点のスプリットタイムがPICに内蔵のメモリ(SRAM)に最終的に書き込まれて記憶され、それらの合図で ゴール (GOAL) をしたことを知らせる。 またその直後に、LCDの表示が約3秒間だけ記憶番号とラップタイムが表示されることは、各チェック地点の場合と同様である。

  • そのゴールした後はスプリットタイムのカウントは停止されるが、次のスイッチ操作の指示があるまでは、現在時刻は更新されながら表示し続ける。 最終的にもう一度 (1)、または (2) のスイッチ操作をすると、 その瞬間に本モードのストップウオッチ・モードが終了をする。
      			[ xx:xx:xx ]	..... 1行目のスプリットタイムはカウントが停止される。
      			[ xx:xx:xx ]	..... 2行目の現在時刻は更新されながら表示し続ける。
      

  • 例外処理として、ストップウオッチ・モード中に何らかの理由があって、本モードを途中で中止をし前モードの時刻設定・モードへ戻りたいような場合には、(SELECT) スイッチ + (START) スイッチの操作をすると、 それが可能となる。 ただし、この場合にはそれまでに記憶されていたスプリットタイムのすべてが無効となるので、このスイッチ操作には十分注意する必要がある。

  • ここで、ストップウオッチ・モードにおいてのスイッチ操作をまとめておくと、次のようになる。

      (ENABLE) スイッチ + (START) スイッチ 通常のちょん押し ........ スタートの処理、各チェック地点の処理、ストップウオッチ・モードの終了
      (ENABLE) スイッチ + (START) スイッチ 5秒ほどの長押し ........ ゴールの処理、ストップウオッチ・モードの終了
      (SELECT) スイッチ + (START) スイッチ 通常のちょん押し ........ 時刻設定・モードへ戻る(例外処理)
◆ メモリ内容表示・モード ◆
  • 上で述べたように、前モードでゴール (GOAL) した後にもう一度、(1)、または (2) のスイッチ操作をすると、ストップウオッチ・モードが終了すると同時に メモリ内容表示・モード に移行をする。 そして、本モードに移行をした直後には次のメッセージがLCDに表示され、"ピポッピポッ" ブザー音とともに LED(緑) を点滅表示してそれを知らせる。 その後はユーザからの指示としてのスイッチの入力待ちとなる。
      			[ Mem Disp ]
      			[←DWN UP→]
      

  • メモリ内容表示・モードにおいて使用するスイッチは○色のスイッチを除いた3個で、本モードにおいては各スイッチを赤字で示した名前で呼ぶこととする。
  • 本モードでは、前モード中にPICに内蔵のメモリ(SRAM)内に書き込んで記憶をさせた、各チェック地点での スプリットタイム を、(UP→) スイッチ、または (←DWN) スイッチを操作するごとに読み出して、 そのときの 記憶番号(チェック地点番号)とともに、改めて時間計算を行って求めた ラップタイム の3つの情報をLCDに表示をする。 このとき読み出しのキーとなる記憶番号は、初めてスイッチ操作があった場合には、それが (UP→) スイッチのときは 1番が、(←DWN) スイッチのときは最大値が選択されて、それらが初期値となる。

  • そして、まず初めに記憶番号が次の形式でLCDに表示される。 この記憶番号は2つのスイッチの内どちらかを操作するごとに更新をするが、 (UP→) スイッチ の場合には、+1ずつ増加 (インクリメント、最大値に達したときは 次には再び1番に戻る)され、一方、 (←DWN) スイッチ の場合には、−1ずつ減少(デクリメント、1番に達したときは 次には再び最大値に戻る)されて、 LCDに表示がされる。
      			[ ** xx ** ]	..... 1行目には記憶番号 xx が表示される。
      			[          ]	..... 2行目には何も表示はされない。
      

  • 上で表示される記憶番号は、どちらかのスイッチを押している間中ずっと表示され続けるが、手を離した瞬間に次の形式でスプリットタイム、およびラップタイムの表示に切り替わる。
      			[ xx:xx:xx ]	..... 1行目にはスプリットタイムが表示される。
      			[ xx:xx:xx ]	..... 2行目にはラップタイムが表示される。
      

  • このようにして2つのスイッチの内どちらかを操作するごとに、記憶番号の表示と、スプリットタイム、ラップタイムの表示に切り替わりながらLCDに表示されるが、本モードにおいてもユーザのスイッチ操作が 一定時間(現在1分に設定)なかったときには、LCDの電源を OFF にし PICも スリープモード に移行して省電力化を図るようにしている。 なお、このスリープモード中であっても (←DWN) / (ENABLE) スイッチ、または (UP→) / (START) スイッチ のどちらかを操作することによって、いつでも即座に目覚めさせることができる。

  • スリープモードから目覚めたときには、一旦、次の形式で刻々と更新をしながら現在時刻が表示されるようになるが、次に、 (←DWN) 、または (UP→) スイッチ のどちらかを操作することによって、 再び上述した形式で、記憶番号(チェック地点番号)とスプリットタイム、ラップタイムの表示に切り替わる。
      			[ Mem Disp ]
      			[ xx:xx:xx ]	..... 2行目には刻々と更新をしながら現在時刻が表示される。
      

  • また、本モードにおいても例外処理として、メモリ内容表示・モード中に何らかの理由があって、本モードを途中で中止をし前モードのストップウオッチ・モードへ戻りたいような場合には、(SELECT) スイッチ + (START) スイッチの操作をすると、それが可能となる。 ただし、この場合にもそれまでに記憶されていたスプリットタイムのすべてが無効となるので、このスイッチ操作には十分注意する必要がある。

  • ここで、メモリ内容表示・モードにおいてのスイッチ操作をまとめておくと、次のようになる。

      (UP→) / (START) スイッチ ........ 次の記憶番号、スプリットタイム、ラップタイムを表示する
      (←DWN) / (ENABLE) スイッチ ........ 前の記憶番号、スプリットタイム、ラップタイムを表示する
      (SELECT) スイッチ + (UP→) / (START) スイッチ ........ ストップウオッチ・モードへ戻る(例外処理)

| ページトップ |

■ プログラム ■

・ 使用した割り込み機能の種類について

 ページトップで述べたように本機の使用目的が私のウォーキングの友とすることであり、本機の作製に当たって、携帯性の確保と如何にして電池を長持ちさせるかに重きを置いています。 家を出てから帰宅するまでの 間中ずっと現在時刻を始め、スプリットタイム* やラップタイム* の表示をさせておく必要もないので、スイッチ操作が一定時間なかったときには積極的にスリープモードに移行して 省電力化を図るようにしているのは上述した通りです。 ( * については 以下 を参照のこと )

 本機のLCDモジュールでの表示内容については、前項の "機能と使用法" で述べたように、PICがスリープ中にはLCDモジュールの電源も OFF になるようにしているので、LCDには何も表示がされません。 しかし、表示を再開したいときには、ENABLE、または START スイッチのどちらかを操作することで、いつでもすぐに目覚めさせることが可能です。

 10 年ほど以前に作製をして、既に私の他のページで紹介をしている "145. 長時間ストップウオッチ/タイマー" とは、使用目的や設計思想がまったく異なるために、本機ではその前作のように 1/100 秒までの詳細な測定はできません。 これは測定精度よりも省電力化を優先させたためで、最小単位が1秒のために、本機では最大1秒の誤差を伴います。 あくまでもウォーキングの友とすることが使用目的であって、 陸上競技のようなタイム測定には不向きであることを初めに断っておきます。

 積極的にスリープモードに移行をさせてはいますが、本機はストップウオッチという時計です。 ずっとスリープをしたままでは時を刻むことができません。 したがって、スリープ中にも1秒毎に割り込みをかけて一瞬だけ目覚めさせ、 時を刻んだ後に再びスリープをさせる、ということを繰り返しているのです。 この割り込み周期をもっと長くすればそれだけ省電力化にはつながりますが、計測の最小の単位を1秒にしたかったので、 本機では1秒毎に割り込みをかけています。

 このように1秒毎に割り込みをかけるために、本機では タイマー1割り込み を使用していますが、スリープモード中だけでなく目覚めているときにも、常にタイマー1割り込みで時を刻んでいるのです。 また、スイッチ操作が一定時間なかったときにスリープモードに移行させるための、この一定時間のカウントの監視にも同割り込みを使用しています。 そして、スリープ中のPICをスイッチの操作によって再び目覚めさせるためには、 RB ポート変化割り込み を使用しています。

 また、本機では様々な状態の変化をユーザに知らせるために、各種のビープ音を発生して注意の喚起に使用をしていますが、そのビープ音の発生には タイマー0割り込み を使用しました。

・ ビープ音の発生方法について

 私のこれまでの他のプログラムでは、ビープ音の発生には通常タイマー1割り込みを使用することが多いのですが、本機ではタイマー1割り込みは上で述べたように、既に時を刻む目的のために使用をしているので、 同目的にはタイマー0割り込みを使用しました。

 このビープ音を発生させるのに、タイマー1割り込みの場合には TMR1H、TMR1L の両レジスタで構成される、16 ビットカウンタがオーバーフローしたときに発生するタイムアウト割り込みを利用しますが、 これに対してタイマー0割り込みでは TMR0 レジスタだけの、8 ビットカウンタがオーバーフローしたときに発生するタイムアウト割り込みを利用しています。 前者ではビープ音の発生プログラムはかなり簡単でしたが、 後者でのプログラムは少しばかり面倒な作りになりました。

 例えば "ピポッ" というブザー音を発生させるために必要となるプログラムを示すと、次のようなコード群となります。
      ;==========================================================================
      ;		変数、定数の定義とレジスタ割付
      ;==========================================================================
      
      		radix	dec
      
      			:
      
      _BZ		equ	0		;アラーム音 出力
      
      			:
      ;						f		t = 1 / f
      f_do2		equ	 956		;ド(1046.52 Hz)		0.0009 55  5479111723
      f_soh		equ	1276		;ソ (784.00 Hz)		0.0012 75  5102040816
      f_mih		equ	1517		;ミ (659.26 Hz)		0.0015 16  8522282559
      f_doh		equ	1911		;ド (523.26 Hz)		0.0019 11  0958223445
      f_so		equ	2551		;ソ (392.00 Hz)		0.0025 51  0204081633
      f_mi		equ	3034		;ミ (329.63 Hz)		0.0030 33  7044565118
      f_do		equ	3822		;ド (261.63 Hz)		0.0038 22  1916446891
      ;								     |  |
      ;							   (100μS 桁)  (1μS 桁)
      po_tim		equ	100		;音長(ms)
      pi_tim		equ	100		;音長
      
      			:
      
      		cblock	h'20'
      
      			:
      const_high				;音階用分周定数 high の保存
      const_low				;音階用分周定数 low の保存
      t0_work					;音階用分周変数ワーク
      
      wt1cnt					;ウェイト用ループカウンタ
      wt2cnt					;ウェイト用ループカウンタ
      			:
      		endc
      
      ;==========================================================================
      ;		マクロ命令定義
      ;==========================================================================
      
      			:
      
      ;		Sound_M マクロ(タイマー0割り込み使用)
      
      Sound_M		macro	@scale,@time
      		movlw	@scale / 100	;出力音階
      		movwf	const_high
      		movwf	t0_work		;ワーク
      		movlw	@scale % 100 / 2
      		movwf	const_low
      		movlw	@time		;出力時間(ms)
      	;;	call	buzzer_control	;ブザー音出力コントロール
      		goto	buzzer_control	;スタックの消費を抑えるため変更
      		endm
      
      ;==========================================================================
      ;		アラーム(ブザー)音出力ルーチン
      ;==========================================================================
      
      			:
      
      		; "ピッ" ブザー音出力 (100 mS)
      buzzer_pi
      		Sound_M		f_soh, pi_tim
                      movlw   f_soh  / 100    ;出力音階			;
                      movwf   const_high					;
                      movwf   t0_work         ;ワーク				;
                      movlw   f_soh  % 100 / 2				; マクロ展開
                      movwf   const_low					;
                      movlw   pi_tim          ;出力時間(ms)			;
              ;;      call    buzzer_control  ;ブザー音出力コントロール	;
                      goto    buzzer_control  ;スタックの消費を抑えるため変更	;
      	;;	return
      
      		; "ポッ" ブザー音出力 (100 mS)
      buzzer_po
      		Sound_M		f_do2, po_tim
                      movlw   f_do2  / 100    ;出力音階			;
                      movwf   const_high					;
                      movwf   t0_work         ;ワーク				;
                      movlw   f_do2  % 100 / 2				; マクロ展開
                      movwf   const_low					;
                      movlw   po_tim          ;出力時間(ms)			;
              ;;      call    buzzer_control  ;ブザー音出力コントロール	;
                      goto    buzzer_control  ;スタックの消費を抑えるため変更	;
      	;;	return
      			:
      
      		; "ピポッ" ブザー音出力と LED(緑)点滅 (Total 260 mS)
      buzzer_pipo
      		call	buzzer_pi	;"ピッ" ブザー音出力
      		bsf	PORTA,_ledG	;LED(緑) 点灯
      		call	wait_30ms
      		bcf	PORTA,_ledG	;LED(緑) 消灯
      		call	buzzer_po	;"ポッ" ブザー音出力
      		bsf	PORTA,_ledG	;LED(緑) 点灯
      		call	wait_30ms
      		bcf	PORTA,_ledG	;LED(緑) 消灯
      		return
      			:
      
      		; ブザー音出力コントロール
      buzzer_control
      		movwf	wt2cnt		;退避
      		movlw	256 - 200	;4 / 8MHz * 200 = 100 μS
      		movwf	TMR0
      		movf	wt2cnt,W	;復帰
      		bsf	INTCON,T0IE	;bit5(T0IE)=1: タイマー0割り込み許可
      		call	wait_xxms	;入力 W: 音長(ループカウンタ)
      		bcf	INTCON,T0IE	;bit5(T0IE)=0: タイマー0割り込み禁止
      		return
      
      ;==========================================================================
      ;		ウェイト・ルーチン (8 MHz)
      ;==========================================================================
      
      			:
      
      		; xx m 秒( 1m 秒 x W )ウェイトルーチン
      wait_xxms
      		movwf	wt2cnt		;1
      
      w1m01		movlw	221		;1
      		movwf	wt1cnt		;1
      
      w1m02		goto	$ + 1		;2
      		goto	$ + 1		;2
      		goto	$ + 1		;2
      		decfsz	wt1cnt,F	;1,2
      		goto	w1m02		;2,0	(2+2+2+1+2)*220+(2+2+2+2+0)=1988
      
      		nop			;1
      		goto	$ + 1		;2
      		goto	$ + 1		;2
      		decfsz	wt2cnt,F	;1,2
      		goto	w1m01		;2,0	(1+1+1988+1+2+2+1+2)*(W-1)+(1+1+1988+1+2+2+2+0)=1998*W-1
      
      		return			;2	1+(1998*W-1)+2=1998*W+2
      					;Total	(1998*W+2)/8MHz*4 = (999*W + 1) μS
      			:
      
      ;==========================================================================
      ;		割り込み処理
      ;==========================================================================
      
      interrupt
      			:
      			:
      
      			; タイマー0割り込み処理( 100μ秒毎に割り込み: ブザー音出力時のみ )
      
      int_tmr0	bcf	INTCON,T0IF	;タイマー0割り込みフラグをクリア
      		decfsz	t0_work,F	;t0_work - 1 = 0 か?
      		goto	int02		;No
      
      		movf	const_low,W	;音階用分周定数 low
      		movwf	t0_work
      					;(4/8MHz) * (1+1+2) * (const_low) = 2μS * (const_low)
      int01		nop			;1
      		decfsz	t0_work,F	;1,2	t0_work - 1 = 0 か?
      		goto	int01		;2,0	No
      
      		movlw	1 << _BZ	;対象ビットをセット
      		xorwf	PORTB,F		;出力をビット反転
      
      		movf	const_high,W	;音階用分周定数 high
      		movwf	t0_work
      
      int02		movlw	256 - 200	;4 / 8MHz * 200 = 100 μS
      		movwf	TMR0
      		goto	int_end
      
      			:
      			:
      
 以上に示したプログラムで、音階を作り出すための定数定義の部分を再掲してみると、次のようになります。
      ;						f		t = 1 / f
      f_do2		equ	 956		;ド(1046.52 Hz)		0.0009 55  5479111723	;buzzer_po で使用する音階定数
      f_soh		equ	1276		;ソ (784.00 Hz)		0.0012 75  5102040816	;buzzer_pi で使用する音階定数
      f_mih		equ	1517		;ミ (659.26 Hz)		0.0015 16  8522282559
      f_doh		equ	1911		;ド (523.26 Hz)		0.0019 11  0958223445
      f_so		equ	2551		;ソ (392.00 Hz)		0.0025 51  0204081633
      f_mi		equ	3034		;ミ (329.63 Hz)		0.0030 33  7044565118
      f_do		equ	3822		;ド (261.63 Hz)		0.0038 22  1916446891
      ;								     |  |
      ;							   (100μS 桁)  (1μS 桁)
      
 この内、"ピッ" と "ポッ" で使用する音階定数を再掲でコメントの追加をしましたが、例えば "ピッ" の場合の音階定数は 1276 ですが、どのようにして求めたかというと、この音階は高い方の ソ (784.00 Hz) で その周期を求めると T = 1 / f = 0.0012 75 5102040816 ≒ 0.0012 76 秒(小数点以下 7 桁目を四捨五入)、すなわち、0.0012 76 秒 = 1276 μ秒となります。

 本機では、システムクロックに 8 MHz のセラロックを使用しているため、基準クロックは ( 1 / 8MHz ) * 4 = 0.5μS となります。 したがって、この基準クロックを TMR0 で 200 カウントして 4 / 8MHz * 200 = 100 μS 周期で タイマー0割り込みを起こさせています。

 また、上で示した "ピッ" サブルーチン( buzzer_pi )を同様に再掲してみると、
      		; "ピッ" ブザー音出力 (100 mS)
      buzzer_pi
      		Sound_M		f_soh, pi_tim
                      movlw   f_soh  / 100    ;出力音階			;
                      movwf   const_high					;
                      movwf   t0_work         ;ワーク				;
                      movlw   f_soh  % 100 / 2				; マクロ展開
                      movwf   const_low					;
                      movlw   pi_tim          ;出力時間(ms)			;
              ;;      call    buzzer_control  ;ブザー音出力コントロール	;
                      goto    buzzer_control  ;スタックの消費を抑えるため変更	;
      	;;	return
      
 このマクロを使用したサブルーチンでは何をしているかというと、まず、音階定数 (1276) の上2桁を取り出して const_high = 1276 / 100 = 12、次に、音階定数 (1276) の下2桁を取り出したものを 1 / 2 して const_low = 1276 % 100 / 2 = 76 / 2 = 38 と、2つの値を作り出してそれぞれのレジスタに格納をしています。

 そして、これらの2つの値が上に示した 100 μS 周期の、タイマー0割り込み処理ルーチン内で使用されます。 まず const_high = 12 で、タイマー0割り込み処理ルーチンが 12 回繰り返され( 100 μS * 12 = 1200 μS )、 次には、その 12 回目に const_low = 38 で、タイマー0割り込み処理ルーチン内の次に示すループを、38 回繰り返します( 2 μS * 38 = 76 μS )。
      					;(4/8MHz) * (1+1+2) * (const_low) = 2μS * (const_low)
      int01		nop			;1
      		decfsz	t0_work,F	;1,2	t0_work - 1 = 0 か?
      		goto	int01		;2,0	No
      
 このように 1200 μS + 76 μS = 1276 μS が経過すると、最終的には次のようにブザー音出力ポートのビットを反転させます。
      		movlw	1 << _BZ	;対象ビットをセット
      		xorwf	PORTB,F		;出力をビット反転
      
 ただし、この場合には指定周波数よりも1オクターブ下の半周期分を作成していることになります。 したがって、以上説明をした過程(ビット反転まで)を2度繰り返すことによって 1周期分を作成することになりますが、あくまでも指定周波数よりも1オクターブ下の音階であるので注意が必要です。

 なお、"ピポッ" ブザー音出力時には LED(緑) も点滅をさせて、ユーザへの注意喚起をより強調させています。

・ 時間データの取り扱いと記憶の方法について

 本機で取り扱う時間データには、現在時刻、スプリットタイム、ラップタイムの3種類がありますが、それぞれ "時"、"分"、"秒" で構成されており、プログラムの内部では3バイトの BCD データ(BCD とは、Binary Coded Decimal の略で 2進化 10進数 の意味)とし、各バイトは次図に示すように4ビットずつに分けて、2桁の2進数として取り扱っています。
 本機では、取り扱う時間データの内、現在時刻は後の2つとは全く無関係で、ストップウオッチの動作中にも完全に独立して時間を刻み続けます。 これはウォーキング中に現在の時刻を知りたい場合があるもので、 そのためだけに現在時刻の表示機能を設けました。 恐らく誰しも腕時計を携帯してウォーキングをすることが多いと思うので、必ずしも必要ではないかもしれません。

 したがって、本機の電源スイッチを ON にした直後に時刻の設定をする仕様(設定が簡単に行えるようにプリセット値を、PICに内蔵のメモリ(EEPROM)へ書き込みや読み出しの機能もあり)になっていますが、 必須ではないため不要な場合には省略をしても構いません。 ただし、その場合には、ストップウオッチの動作中にも無意味な時刻表示がされ続けることになります。

 次に、スプリットタイムとラップタイムについてですが、次図のような関係にあります。 スプリット(SPLIT)タイム とはスタートしてからゴールまでの途中経過時間のことを言い、また、ラップ(LAP)タイム とは スタートからゴールまでの区間経過時間のことを言います。

 そして、ユーザのスイッチ操作によるスタートの合図を起点として、スプリットタイムの "時"、"分"、"秒" を [ 00:00:00 ] にしてカウントが始まります。 このように本来、現在時刻とは非同期でカウントが開始されるのですが、 上述 したように本機の割り込み周期が1秒で同じ割り込みを使用しているために、更新のタイミングは現在時刻と同期をしてしまいます。
 この2つのタイムの内、本機ではウォーキング中にユーザによるスイッチ操作を検出して、その時点でのスプリットタイムだけをPICに内蔵のメモリ(SRAM)に書き込んで行きます。 このときのデータ形式が上述した3バイトの BCD データで、ラップタイムについては時間計算をした結果をLCDに表示をさせています。 今回検出したスプリットタイムから、内蔵メモリ(SRAM)に記憶されている 前回のスプリットタイムを読み出して、引き算をするわけです。
          ラップタイム = 今回のスプリットタイム - 前回のスプリットタイム
 このこと(新しいスプリットタイムの記憶とラップタイムの時間計算およびLCD表示)を、ユーザによるスイッチ操作を検出する度に繰り返します。

 次図は PIC16F628A と PIC16F648A のデータメモリの構成を図に表したものですが、着色した部分が汎用レジスタ(GPR)でユーザが自由に使用できる RAM メモリです。 ただし、各バンクの最下位 16 バイト分については、実際には バンク0に存在するだけで他のバンクには物理的に存在しませんが、バンク切り替えを行わなくても他のバンク指定のままで、バンク0の 16 バイト分にアクセスすることが可能となっています。

 両PICではバンク2のメモリ量が異なっているのが分かりますが、本機ではどちらでも使用することができます。 ただ、PIC16F628A では RAM メモリが少ない分だけスプリットタイムの記憶量も少なくなります。 具体的には、1スプリットタイム当たり3バイト必要なのでバンク2での記憶量は、PIC16F628A では 48 / 3 = 16、PIC16F648A では 80 / 3 = 26 となります。 (ただし、これらの両PICの仲間に PIC16F627A というものもあり、データメモリの構成は PIC16F628A と同じですが、プログラムメモリが 1 K ワードしか存在しないため、本機で使用することはできません。)
 話は少しばかり変わりますが、本機では、バンク1とバンク2については(GPR)のすべてをスプリットタイムの記憶用に使用をしていますが、バンク0の(GPR)についてはプログラム内で使用する、 他の一般的な変数を優先してそちらで使用をしなければならないので、それらで使用した残りの(GPR)をスプリットタイムの記憶用に割り当てました。

 また、スプリットタイムの記憶用として使用するバンクの順は、まず初めにバンク1としました。 そして 80 / 3 = 26 個と満タンになると、次にバンク2に移ります。 そして PIC16F628A では 48 / 3 = 16 個、PIC16F648A では 80 / 3 = 26 個とそこも満タンになると、次にはバンク0に移ります。 上述のようにバンク0では 80 + 16 = 96 バイトから、一般的な変数の総数を差し引いた残りの(GPR)を使用します。 まだプログラムの開発途中の現在ですが 50 バイトの残り(GPR)がありますので、50 / 3 = 16 個まで記憶することが可能です。

 したがって、全体を通してもう一度まとめてみると、PIC16F628A の場合には 26 + 16 + 16 = 58 個、PIC16F648A の場合には 26 + 26 + 16 = 68 個まで記憶することができます。 そして、もしも、 これらの最大個数になっているときに、なおも記憶をさせようとしたときには、[ Mem Over ] とLCDにエラーメッセージを表示して、かつ、"ブッブッブッブッ" ブザー音とともに LED(赤) が数秒間点滅を繰り返します。

 さて、時間データを3バイトの BCD データとして取り扱っていることと、ラップタイムを求めるための時間計算についてを先に触れたところですが、この時間計算に引き算をするということが、 私にとってそれほど容易なことではありませんでした。 私はこれまでに時間関連におけるいろいろなプログラムを作成してきて、3バイトの BCD データを単純にインクリメント(+1する)したり、 デクリメント(−1する)したりするだけのプログラムに関しては、比較的容易に実現をさせることができていました。

 しかし、今回のようにラップタイムを求めるために、3バイトの BCD データ同士の引き算をするということに関しては、まったく初めての経験でその実現にはずいぶんと頭を悩ませました。 何とかそのサブルーチン( lap_time_calc )を作り上げたのですが、現在はかなり冗長なコードになっています。 もう少し頭を捻ればより簡潔な方法になるかもしれないですが、とりあえず現行のままとします。

 BCD データを文字化する場合には超簡単ですが、このような時間計算をさせる場合には、本機のプログラムを通じてかなり面倒であることを、改めて認識をしました。 このような時間計算をさせる場合には、BCD データではなく バイナリデータを扱ったほうが単純に引き算ができて面倒さがないと思います。 反面、本機のプログラム内でも使用をしていますが、バイナリデータを文字化する場合には、サブルーチン( bin8_dec2chr )のように 若干面倒さを伴います。

現在の最新バージョン: Ver. 1.01
上述しているように、本機で使用するPICは、PIC16F628A、PIC16F648A のどちらでも可で、ソースファイル (StopWatchII.asm) も両方に対応した記述をしていますが、 アセンブルするときにはどちらにするかをアセンブラに指示をしなければなりません。

ソースファイル中の "変数、定数の定義とレジスタ割付" の 10 行ほど上辺りに
      #define 	x16f628a		;どちらかを有効にする
      ;#define 	x16f648a		;
      
の 2行が書かれた部分がありますが、ここでどちらにするかを指示をします。 選択をしないほうの行頭に ; 印を付してコメント行にしてください。

| ページトップ |

■ プリント基板の加工と部品配置 ■

 下の ケース加工図 で示したケース内にぴったりと収めるためには、プリント基板の切断等の加工が必要です。 使用したプリント基板は、"秋月電子" の "片面ガラス・ユニバーサル基板 Bタイプ(95×72mm)めっき仕上げ(通販コード P-00518)" で、下図に示すように まず、横の ----- 線の位置で切断をします。 次に、縦の ----- 線2ヶ所の位置で切断をします。 最後に、ケース取り付け用のΦ3.2 の穴を4個と木片固定用のΦ2 程度の穴を2個開けます。

| プリント基板部品配置図 (StopWatchIIPC0.CE3) | ページトップ |

■ プリント基板パターン図 (部品面) ■

 プリント基板に各パーツ類を取り付けるに当たって、いくつかの注意をすることがあります。 その1つ目は、PIC用のソケット周りのハンダ付けをするときに、 使用するソケットの形状にもよりますが、ソケット内に配されている 0.1μF のコンデンサを、ソケットよりも先に取り付けておかないと、後からでは取り付けが少しばかり困難になります。

 2つ目は、右側に5個並んでいるタクトスイッチの内、下から2番目の DOWN スイッチについても同様で、スイッチよりも先に青線で示したジャンパーの配線をしておかないと、 スイッチの取り付けの後からでは配線が難しくなります。

 LCDモジュールの取り付けについては 下で詳述 しているので、そちらを参照してください。

 また、左下に位置している 100μF のコンデンサは、通常のものよりも背が低いタイプのものが必要で、通常タイプでは背が高くて本機で使用しているケース内には収まりません。

 本機で使用している2個のLEDについては通常のものを使用していますが、できれば VF が小さくて高輝度なものを使用することが望ましいと思います。 私の場合には、緑(3 mm)の高輝度LEDが手持ちになかったので赤緑とも通常のものを使用してしまいましたが、消費電流を抑えるために通常よりも大きな制限抵抗を使用していることもあって、 やはり光具合には多少の不満が残ります。

 次に、右上に位置している2個のタクトスイッチについては、他の3個に比べてキートップ長が長いものを採用し、本機のケースの蓋を閉めた状態でも頭がケース外に飛び出すような構造にしています。 私が使用したものは、"ラーメン・タイマー II(2号機)" や "ラーメン・タイマー III" で使用したものと同じもので、 キートップ長が 9.5mm のものを使用しています。

 そして、プリント基板をケースへ取り付けるときの考え方などを、"ラーメン・タイマー II(2号機)" の "ケースへのプリント基板の取り付け" で詳述していますので参考にしてください。

| プリント基板パターン図 (部品面) (StopWatchIIPC.CE3) | ページトップ |

■ プリント基板パターン図 (ハンダ面) ■

| プリント基板パターン図 (ハンダ面) (StopWatchIIPC1.CE3) | ページトップ |

■ LCDモジュールのプリント基板への取り付け ■

 本機で使用したLCDモジュールは、"Xiamen Zettler Electronics" 社の "AQM0802A-RN-GBW" ですが、本機に採用した理由として、I2C接続で必要とするPICの I/Oポート数が2本だけで済み、 また、小型で消費電流も 1 mA と少なく携帯用にはぴったりなことと、"秋月電子通商" で購入をしたのですがすごく安価である、ということなどが挙げられます。

 半面、このモジュールの、基板との接続用の足ピンのピッチが 1.5 mm のため、通常の 2.54 mm ユニバーサル基板には、そのままでは搭載することができません。 そのために、ピッチ変換基板なるものも販売されていますが、 その価格設定が私にはどうしても納得が行きません。 LCDモジュールに必要な外付けのCR類が付属されているとはいうものの、本体のLCDモジュールよりも高いということに、どうしても納得が行かないのです。 (下図は AQM0802A の外観図で、"秋月電子通商" のホームページに収録の PDF データシートから抜粋したもの)  そこで、ピッチ変換基板を購入することはやめて、何とか 2.54 mm ユニバーサル基板に取り付ける方法を考えてみました。 "AQM0802A-RN-GBW" の足ピンは、上図に示すように 1.5 mm ピッチですが 9 本が横一列に並んでいます。

 また、次の図は既に上で示した、プリント基板の 部品配置図パターン図 (部品面) の、LCDモジュールの取り付け部分を切り取ったものです。


 右側の図中のやや中央下部分に、千鳥足状に 1 〜 9 の番号が付けられている基板の穴の場所に、上図に示す横一列に並んでいる 1.5 mm ピッチの 9 本の足ピンを、予め千鳥足状に曲げておいて差し込もうというものです。 そのために、まず 2, 3, 5, 7, 8 のピン先を元位置よりも 2.54 mm 上にずらすように曲げて、横一列だったものを横二列にします。 次に、横二列になったそれぞれのピン先の横幅の間隔を右図になるように広げます。 これらの曲げ加工は足ピンを折ってしまわないように慎重に行います。 といってもそんなに簡単には折れるようなことはありませんが。

 このようにして足ピンの曲げ加工を行ったLCDモジュールを基板に搭載する前に、もう 2、3 先に行っておく作業があります。 左側の図中で、2つの縦長の緑色長方形のものはLCDモジュールを乗せるための台座となる木片で、 他に適当な素材のものが見つからなかったので、私は手持ちにあった 5 x 5 mm の木材を 18 mm 長ほどにカットをして使用しました。

 また、台座としての高さ(厚さ)も出来れば 4 mm 程のものが良いのではないかと思われるため、少々やすりで削ってみましたがこの作業が意外と難しくほどほどで止めてしまいました。 そして、このように加工をした木片を基板に固定をするために、プリント基板の裏側から M2 x 6 程の木ねじで取り付けました。 このとき木片側に予め Φ1.5 程の穴をドリルで開けておくと、木ねじの通りもよく木片が割れにくくなります。 このようにして私は木ねじを使用しましたが、接着剤で固定をさせても良いのではないかと思います。

 次に、この取り付けた2つの台座同士の間にできた空間には、LCDモジュールの取り付けよりも先に上図に示した位置に、3個のコンデンサと2個の抵抗を取り付けておかなくてはなりません。 3個のコンデンサ類は恐らく台座の高さよりも背が高くなるため、LCDモジュールの裏側とぶつからないように、少し斜めに寝かせなければならないと思います。(下の写真を参照)

 このように下準備をした上でLCDモジュールを取り付けるのですが、その前に最後になりますが、LCDモジュールとの密着度をよくするために、2つの台座の上面には両面テープを貼り付けておくと良いと思います。 そしていよいよ、足ピンの曲げ加工が済んでいるLCDモジュールを取り付けるのですが、先の細いピンセットなどで誘導をしながら、各ピンが確実に所定の穴位置に入るように差し込んで行きます。

 このようにして所定の穴位置に差し込んだ 9 本の足ピンの内、4, 5, 6 についてはまったく問題はないと思いますが、通常のプリント基板の厚さは 1.6 mm ありますので、特に 2 と 8 については問題ありで、 恐らく足ピンが基板裏のハンダ面まで達しないと思います。これは、台座の高さが 5 mm と少々高いことと、元々 7 mm 程の長さしかない足ピンを、最も端位置にある所定の穴まで曲げ広げるには少々の無理があるものと思います (場合によっては、他のピン 1, 3, 7, 9 についても同状態になるかもしれません)。 このままではハンダ付けができません。

 そこで、このような場合には裏技を使います。 まず、不要となったACコードなどを用意してその被覆を剥き、複数の細線で構成された芯線を取り出します。 そして、その細線 10 数本を束ねたものをハンダ面側から 該当ピンの穴に差し込んで、その状態でハンダ付けをします。 このときの注意として、決して芋ハンダにならないように十分に熱を加え、ハンダが細線を通して穴の中に流れ込んでその細線と足ピンがハンダで結合するようにします。 また、差し込んだ細線がバラけて他のピンと接触することが決してないように注意が必要です。

 以上述べてきたように、LCDモジュールの足ピンの曲げ加工を行ったり、プリント基板への取り付けを行ったりするときに、気を配っていても指先がLCDモジュールの各部分にしばしば触れてしまうことがあります。 そして、LCDモジュールの表面の下1/3を占める黒い部分に触れてしまった場合には、指先に付着している油脂とか埃とかがその黒い部分(ブラックシリコン)に移ってしまい、 地が黒いだけにその汚れが極端に目立ってすごくがっかりします。

 しかし、心配はいりません。 簡単にこれらの汚れを取り除く方法があります。 どこの家庭にもあると思いますがセロテープを用意してください。 そして、取り扱いやすいように数センチにカットしたもので、 ブラックシリコンの表面上を数回ペタペタを繰り返していると、それらの汚れが次にはセロテープに移って、汚れていたLCDモジュールは元のように復活をします。

LCDモジュールの足ピンの様子を見たところ LCDモジュールの下の空間を後側から見たところ

 上の写真は、このようにして取り付けた後のLCDモジュールの足ピンの様子を撮ったものです。 なお、これらの写真の他にも、LCDモジュールを取り付ける以前のプリント基板の様子写真や、 足ピンの曲げ加工を行った直後の足ピンのアップ写真なども数枚あったのですが、残念ながら、今となってはお見せすることができなくなってしまいました。 その理由については 後書き を参照願います。

( 2020/9/23 追記 )

 最近になって、"187. FMステレオラジオ" を製作しているのですが、本機と同様にLCDモジュール "AQM0802A-RN-GBW" を使用しています。 そこで、ユニバーサル基板に取り付けてしまう前に、 写真を撮っておきましたので、次に掲載をしておきます。 足ピンの曲げ加工を行うときの、要領をつかむための参考にしてください。


 上でLCDモジュールを乗せるための台座となる木片について述べていますが、今回はその高さ(厚さ)を何とか 4 mm 程に削って使用をした結果、上で述べているような裏技を使わなくても、 長短の差はありますが全ピンとも基板裏のハンダ面まで達して、通常のハンダ付けをすることができました。

 また、LCDモジュールの黒い部分(ブラックシリコン)が汚れてしまう件についてですが、予め黒い部分の表面にセロテープを貼って保護をしておき、一連の取り付け作業が終了してから剥がすようにすれば、 何ら問題は起こらないと思います。

 なお、"187. FMステレオラジオ" は、まだ製作途中なので現在はページのアップもしておりません。 したがって、リンクは切れた状態です。 念のため。

( 2020/10/7 追記 )

 昨日、"187. FMステレオラジオ" を公開しました。 中国製の超安価なFMラジオモジュール、デジタルアンプモジュールを使用した "FMステレオラジオ" で、FMラジオモジュールは LCD とともに、 PIC から I 2 C 接続で制御をしています。 興味のある方は是非ご覧になってください。

| ページトップ |

■ ケース加工図 ■

 使用したケースは、100均(セリア)で購入した "トラベルケース L 1P (No.1432) 山田化学" というポリスチレンケースです。


 上図では、ケースの形状を正確に描くことが難しいので、かなり単純化して全体像を表していますが、実際には、上下左右の各 "かど" などは、角ではなく丸みを帯びていたり、 しかもテーパ状になっていたりして、2次元の図では表現がしきれません。 特に、右側の(下面図)では実際に裏側から見ると、複雑?な形状をしていて表現をすることができません。

上の(上面図)において下側面側から見たところ 上の(上面図)において左側面側から見たところ

 したがって、ケースの加工図として寸法を記入してありますが、これらの値は参考までに見ておいてください。

 そこで実際にケース加工を行う場合には、(上面図)に示す右上の2個のΦ4 タクトスイッチ用の穴位置は、ケースが透明で中が透けて見えるので、現物合わせで行った方が確実です。 その方法は、まず、(下面図)に示す4個の穴をあけて(これも現物合わせ) プリント基板を仮に取り付けておいて、上蓋を閉めると2個のキートップの位置が透けて見えるので、実際の穴位置が明確になります。 圧電ブザー用の5個のΦ3 の穴位置についても同様で、初めに中央の穴位置を決めると良いでしょう。

| ケース加工図 (StopWatchIICS.CE3) | ページトップ |

■ 使用部品表 ■

(主要部品: IC, トランジスタ等)

(データシート)
PICマイコン .................... PIC16F628A / PIC16F648A
三端子レギュレータ .................... S-812C33AY-B-G
トランジスタ .................... 2SA1015
LCDモジュール .................... AQM0802A-RN-GBW
圧電ブザー .................... PKM17EWH4000

| 部品表 | Excel ファイル (StopWatchII_parts.xls) | ページトップ |

■ 後書き ■

 突然ですが、皆さん、パソコンなどの重要なデータのバックアップを取っていますか?

 災難というものはいつわが身に降りかかってくるか分からないもので、今回の件でつくづくそう思わされました。 また、昔から、備えあれば ・・・・・ といわれているように、まさにその通りだと反省をしております。

 実は、私が日ごろ愛用しているPCが、2月末頃のある日に、突然 Windows 10 が立ち上がらなくなってしまいました。 当初は事態を安易に考えていたのですが、また、話が長くなるのでここでは詳細に述べることは避けますが、 原因はどうやらハードディスクがクラッシュしたようで、後日、ハードディスクを他の正常なPCに SATA-USB3.0 変換ケーブルで接続をしてみたのですが、ハードディスクにアクセスすることができない様子で、 ディスク内のフォルダやファイルの存在をエクスプローラで確認することがまったくできない状態です。

 ここで、事の深刻さを改めて知らされたようでがっくりと力が抜けてしまいました。 システムはもちろんのこと、最も重要な各種のデータ類を救い出すことがまったく不可能となって、すべてがオシャカになりショックで落ち込んでしまって、 しばらくは立ち直れないほどでした。 データ類のバックアップは、不定期ではありますが一応、外付けのハードディスクに取ってはいたのですが、その最終のものが昨年の11月末頃で、その間、約3か月分の更新されたデータについては、 完全に蒸発をしてしまいました。

 また、バックアップについてはすべてのデータ類ではなく、私にとって最も重要な趣味の開発環境で使用するためのデータ類(約 30G bytes 分)だけで、その他のものについてはバックアップを取っておらず対象外でした。 このバックアップの対象外としていたデータ類の中にも、重要なファイル類がたくさん含まれていたのですが、ただ、ため息が出るばかりで何ともなりません。

 蒸発をしてしまった3か月分の更新データの中には、本作品 "ストップウオッチ II" の開発のために必要な各種のデータファイルなどがたくさんありました。 回路図を始めとしてプリント基板パターン図、ケース加工図などの各種図面類は 既にほとんどが完成しており、他にはまだ開発途中ではありますが、本機のプログラムやこのページである HTML ファイルも含まれています。 また、一部ですが、ホームページ用の写真もありました。 しかし、それらのすべてが一瞬の内に消えてなくなってしまったのです。

 唯一残ったものは、既に完成をしていた本機のハードウエアだけでした(ハードディスクとは関係がないので当たり前か)。 このように、本機の開発もかなり進んでいたころのことで、一瞬にしてそれらのすべてを失ってしまったため、 それからひと月以上もの間、何もする気が起こりませんでした。

 気を取り直して本格的に再開を始めたのは4月に入って何日も経ってからのことでした。 まず初めに行ったのは回路図の再現からでした。 本機は比較的簡単な回路ですがそれでも頭の中に入っているわけではないので、 完成をしている現物のプリント基板のパターンを見ながら回路図を起こして行きました。 そして、プリント基板パターン図などの再現も行いました。

 開発途中ではありましたが既に1か月以上ものブランクがあったために、プログラムの作成では以前にはどんな考えのもとでどこまで進んでいたのか、まったく記憶にはなく思い出すことができません。 プログラムリストが一瞬で消えてしまい文字通りまた一からの再出発でした。 私の場合には、プログラムというものは毎日毎日の積み重ねで、その日の一瞬一瞬でどんどんと内容の更新がされて変わって行きます。

 ですから、どのようなことをさせるか概略では大まかに似ていても、それを HEX レベルにしたときにはまったく異なった別のものとなります。 もしも、作成が途中で打ち切られることなく以前のまま進めていたとしたら、 どのようなプログラムができ上がっていたか、やむなくの再出発で別ものを完成させた現在でもすごく興味があります。

 また、昨年の11月末以降に私が公開をした作品として、他のページで紹介をしている "110. 音声(お喋り)時計 2題" がありますが、この作品に関してもバックアップがまったく取られてないので、 外付けのハードディスクの中には何もなくPC上だけに存在していたわけですから、それが消えてしまった時点ですべてがなくなってしまいました。 その中にはホームページ上に表示がされている各種の図面や写真などの元となった、 数多くの重要な元ファイルが含まれています。

 たとえば回路図を例にしてみると、元ファイルは "回路図エディタ BSch3V" で作成をした ".CE3" ファイルのことで、その後 ".BMP" ファイルを経て私の場合には彩色を施して最終的に ".GIF" ファイルに変換をした後、 ホームページ上で表示をさせています。 したがって、今後回路図を変更したいとかの要求が起こっても元ファイルが存在しないと、その変更をすることがかなり困難になります。

 また、写真ファイルでは、まずデジカメで撮った ".JPG" ファイルが元ファイルになり、サイズが極端に大きな元ファイルをサイズ変換ソフトで適度なサイズに縮小した後、 必要な部分だけをトリミングして、場合によっては明るさやコントラストなどを調節して、ホームページ用の写真ファイルに仕上げています。

 この作品では、PC内の元ファイルなどを含んだすべてが失われてしまったのですが、それでも僅かに救いとなったのは、ホームページ上で公開のために既にWEBサーバ上にアップロードをしてあったので、 それらを新しいPC上にダウンロードをして、とりあえず元ファイルなどを含まないデータだけの復元をすることができたことでした。

 このように昨年の11月末以降でバックアップが取ってなかったために大きな影響を受けてしまった作品には、前者のまだ開発途中であった本作品 "ストップウオッチ II" と、後者の既に公開済みの "110. 音声(お喋り)時計 2題" の 2作品があったのですが、前者については開発の二十手間、という実に大きな犠牲を払わされました。

| ページトップ |

■ 参考資料・サイト ■

長時間ストップウオッチ/タイマー ..... http://xyama.sakura.ne.jp/hp/StopWatchTimer.html
初心者にもわかるPICマイコン活用法&電子工作の基本 ..... http://t4053x.jp/index.htm
 ダウンロード < X.PICマイコン アセンブラ入門 > ..... http://t4053x.jp/download.htm

| ページトップ | ホーム |


Copyright (C) 2020-2023 やまもとみのる
初版:2020年6月1日、初公開:2020年6月1日、最終更新:2023年10月25日