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

174. グラフィック液晶表示 万年カレンダー

[ 初公開日:2014年11月24日 ]

 この作品は、過去に製作してあったものではなく、久しぶりに新規に製作をした作品です。 私が3年も以前から構想を温めていたもので、 この度ようやくその製作の実現に至り、このホームページ上で公開することができた、私の最新のオリジナル作品です。
 "万年カレンダー" ・・・ 文字通り、西暦(グレゴリオ暦)4桁(0001年〜9999年)に対応した "万年カレンダー" の製作です。 グレゴリオ暦元年1月1日 (もちろんこのような日付けは歴史上は存在しない)から、便宜上4桁の最終未来 9999年12月31日 までに対応しています。

 自分が生まれた生年月日は何曜日だったか? とか、XX年先の何年何月何日は何曜日か? なんて疑問が、この万年カレンダーを使えばすぐさま解決できます。

 また、紙のカレンダーのように、毎月のページの更新も使用者の手を煩わせることなく、すべてが自動で更新してくれますから面倒さがまったくありません。 当然ながら、カレンダー機能の大元は、刻々と刻み続ける時計機能が源となっており、その刻々と変化する時計表示も、この "万年カレンダー" の特徴となっています。

LARGE モード画面表示の機能を追加 ( 2014/12/20 更新 )

 NORMALモード画面表示に加えて、文字サイズが縦横2倍(面積4倍)で表示する、右写真のような LARGE モード画面表示を追加しました。

 ただし、この LARGE モード画面表示では、文字が大きくなったため遠目からも見やすくなりましたが、反面、7曜カレンダーを表示することはできません。

 しかしながら、NORMALモード画面表示と LARGE モード画面表示は、どちらへも相互にワンタッチで切り替えることが可能ですから、何ら問題はないものと思います。

 詳細は 機能と使用法プログラムファイル を参照してください。


【 お知らせ 】 ( 2024/5/29 更新 )

 本機のプログラムには 10 年も以前の製作時から、重要な不具合(電源を入れたときの状態によって、不具合が発生したり、発生しなかったりする)が潜んでいましたが、 この度ようやくその原因が判明しました。 詳細は "潜在的に潜んでいた不具合を修正" の項を参照してください。

■ 回路図 ■

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

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

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

| ページトップ |

■ 機能概要と使用法 ■

  • 本機の電源を投入すると、"ピポッ" と開始ブザー音を出力後、プログラムのタイトル、およびバージョン番号などの表示とともに、 グラフィック液晶のデモ表示が数秒間行われる。

        電源を投入直後の液晶画面

  • グラフィック液晶のデモ表示が終了すると、本機の時計機能が開始され、液晶画面は時間表示と ともにカレンダー表示に切り替わる。 このとき表示される画面を、NORMAL モード と言う。

        NORMAL モードで時計機能が開始

  • 初めて電源を投入するとカレンダーおよび時間は、"2014/11/01"、"00:00:00" と、本機をプログラミングしたときの設定値を表示するため、 次の手順で現在の年月日、時分秒に設定し直す必要がある。

  • なお、本機には操作するための押しボタンスイッチが6個あり、以下にその使用法を順に説明して行く。

        MODE / SET スイッチ

        UP スイッチ

        DOWN スイッチ

        ZERO / BACK スイッチ

        SIGNAL スイッチ

        LIGHT スイッチ

  • 設定手順の説明をする前に、Ver. 1.20 にて機能アップをしたので、そちらを先に少々触れる。

  • 上記のように、デモ表示の後 NORMAL モードに移行して、画面は通常の7曜カレンダー表示をするが、この状態のときに MODE / SETスイッチ を押すと、画面は大きな文字が表示されるようになり、この状態を LARGE モード と言う。 当然ながら文字が大きくなったため、7曜カレンダー表示はできない。

        LARGE モードに切り替わった

  • NORMAL モードと LARGE モードは、MODE スイッチを押すごとに交互にそのモードを切り替えることができる。 このように MODE スイッチを チョンと押して、NORMAL モードと LARGE モードを切り替えるのではなく、次のように長押しをすることにより、年月日、時分秒を 希望値に設定変更することができるモードとなる。

  • 話を戻して設定手順は まず、MODE スイッチを数秒間押し続けると、画面右下のメッセージエリアに "SET MODE" と反転表示されて、 NORMAL モード、または LARGE モードから SET モード に切り替わったことを示し、年月日および時分秒の表示は 更新が停止する。

  • なお、このとき LARGE モードから SET モードに切り替わった場合には、メッセージエリアの確保のため、2行目(曜日、am/pm)の表示と 3行目(時分秒)の表示が、以降 SET モードの間中は上部位置に移動して表示される。

        SET モードに切り替わった LARGE モードから SET モードに

  • そこで MODE スイッチを放すと、メッセージは "Year Hi ?" に変わり、左上の年月 "xxxx/xx" 表示エリアの先頭2桁が反転表示されて、 年の上位2桁の変更が可能となる。

        年の上位2桁の変更が可能 LARGE 画面で年の上位2桁の変更時

  • もし変更が必要であれば、UP スイッチを押すごとに現在値より1ずつ増加し、また DOWN スイッチを 押すごとに1ずつ減少するので、適宜希望する値に変更する。

  • 年の上位2桁の変更が済んだら、再び MODE / SET スイッチを押すとメッセージは "Year Lo ?" に変わり、左上の年月 "xxxx/xx" 表示エリアの 年の下位2桁が反転表示され、年の下位2桁の変更が可能となる。

        年の下位2桁の変更が可能 LARGE 画面で年の下位2桁の変更時

  • 同様に変更が必要であれば、UP スイッチまたは DOWN スイッチを押すことによって、適宜希望する値に変更する。

  • 以降、同様に SET スイッチ を押すごとに、月 → 日 → 24H/12H → 時 → 分 → 秒 と設定項目を変更することができるので、 変更が必要であればその該当項目の選択時に、UP スイッチまたは DOWN スイッチを押すことによって、適宜希望する値に変更する。

  • また、このときのメッセージエリアには、それぞれ "Month ?"、"Today ?"、"24H/12H ?"、"Hour ?"、"Minute ?"、"Second ?" と反転表示され、 NORMAL モードでは1行目の該当項目の月、24H/12H、時、分、秒も反転表示されて選択項目を表す。 LARGE モードにおいても位置は異なっているが、 該当する項目が同様に反転表示される。

        ( 設定例 )
        年 "xxxx"、月 "xx" は変更なし 日 を "16" に設定 デフォルトは "24H" になっている
        "12H" に切り替え後、時を "pm 3" に設定 分 を "26" に設定 秒 を "20" に設定

        ( LARGE 画面での設定画面例 )

  • 選択項目の日 "xx" については、NORMAL モードでは7曜カレンダー内で該当日(本日)が反転点滅で表示されるので、同様に UP スイッチまたは DOWN スイッチによって、その位置を移動変更することにより選択をする。 また、LARGE モードにおいては1行目の右端2桁が反転表示され、 他の項目と同様に UP スイッチまたは DOWN スイッチを押すことによって、適宜希望する値に変更する。

  • この SET スイッチによって項目を選択中に、誤って希望する項目を通り過ぎてしまったような場合には、BACK スイッチを押すごとに ひとつずつ前の項目に戻ることができる。

  • 最後の秒の項目選択時に更に SET スイッチを押すと、SET モードから NORMAL モード、または LARGE モードに再び切り替わり、 今まで変更してきた設定値で年月日、時分秒の更新表示が再開される。

        設定再開後、"49 秒" が経過した SET モードから再び LARGE モードに

  • SET モードでの選択項目の推移をまとめると次図のようになる。
    	                                BACK            BACK  BACK  BACK       BACK  BACK  BACK
    	              MODE               ←              ←    ←    ←         ←    ←    ←
    	              /SET              SET             SET   SET   SET        SET   SET   SET   SET
    	  NORMALモード ─→ 年(上位2桁) → 年(下位2桁) → 月 → 日 → 24H/12H → 時 → 分 → 秒 ─→ NORMALモード
    	  (LARGEモード)          │                                                            ↑     (LARGEモード)
    	                     BACK└──────────────────────────────┘
          
  • ここで項目 24H/12H について補足をしておくと、これは時表示を 24時間表示にするか 12時間表示にするか、どちらかを選択することで、 UP スイッチまたは DOWN スイッチのどちらかを押すことによって、交互に切り替えることができる。

        デフォルトは "24H" になっている "12H" に切り替えた

  • 24H を選択した場合は、次項目に移った時に "24H/12H" 表示エリアには何も表示されないが、12H を選択した場合は、次項目に移った時に "am" または "pm" が、そのときの時 "xx" の設定値によって変更表示される。

        次項目に移ると "pm" が表示される

  • 次に、12時間表示と24時間表示の対応を示す。 なお、12時間表示の場合のみ 時 "xx" の先頭の1桁目は、ゼロサプレスを行なって 表示をする。
    	 (24H)  00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┐
    	 (12H)  12  1  2  3  4  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10 11  │(←修正前)
    	     pm am am am am am am am am am am am am pm pm pm pm pm pm pm pm pm pm pm ┘
    
    	 (24H)  00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ┐
    	 (12H)  12  1  2  3  4  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10 11  │(←修正後)
    	        am am am am am am am am am am am am pm pm pm pm pm pm pm pm pm pm pm pm ┘
    	        ↑                                  ↑
    

  • 以上のように、SET モードで年月日の設定変更を行うと、その値のバックアップがとられて次回(同一日であれば)に 電源の投入をし直した時には、 その設定値で年月日、時分、および 00秒からスタートする。 また、年月日の設定変更を行なった場合ばかりでなく、毎日日付が更新された時点でも、やはり同様に年月日、時分のバックアップが とられるため、次回に電源の投入をし直したときには、 そのバックアップ値で年月日、時分、および 00秒からスタートする。

  • ZERO/BACK スイッチは、SET モードでは上記のように BACK スイッチとして機能するが、それ以外の NORMAL モード、および LARGE モードでは 毎正時プラス・マイナス5分以内に押されると、00分00秒に設定するための ZERO スイッチとして機能する。

  • また、NORMAL モードにおいての UP スイッチまたは DOWN スイッチの振る舞いは、それぞれの項目の設定値を変更するのではなく、 現在画面表示されている年月表示とカレンダー表示を、月ごとに前進、または後退させて表示する。 なお、時分秒の時刻については、 当然ながら現在時刻をきざみ続ける。

  • このときメッセージエリアには、"←Down Up→" が表示され、かつ、"←Down" または "Up→" のどちらかが反転表示されて、 本日の年月日(現在位置)からどちらの方向に偏っているかを表している。 本日の年月日にもどると、これらのメッセージは消えて 7曜カレンダー内の該当日(本日)が反点表示される。

        1か月前を表示(後退) 本日の年月日(現在位置) 1か月後を表示(前進)

  • なお、この "←Down Up→" が表示されているときには、SET スイッチの操作をしても無視されて、LARGE モードへの切り替え、または SET モードへの移行はできない。 ( 2019/4/20 修正 )

  • LARGE モードにおいては7曜カレンダー表示されることがないため、 UP スイッチまたは DOWN スイッチを押しても、画面は何の変化もなく無視される。

  • SIGNAL スイッチは、押すごとにメッセージエリアに "Signal On" と "Signal Off" を交互に数秒間表示し、 毎時の時報音出力をブザーから鳴らすか止めるかを設定する。 なお、電源を投入直後は "Signal On" の状態に設定されている。

        時報音を鳴らす状態に設定 時報音を止める状態に設定

  • また、LARGE モードにおいては SET モードに切り替わったときと同様、メッセージエリアの確保のために2行目と3行目が上部位置に移動して表示される。

        LARGE モード時の時報音 ON の状態 LARGE モード時の時報音 OFF の状態

  • LIGHT スイッチは、グラフィック液晶画面のバックライト用 LED の照明点灯を制御するもので、押すごとに消灯と点灯を 交互に繰り返す。 また、どのスイッチも操作しない状態が15分以上続くと、省エネのため自動的にバックライト用 LED は消灯する。

        液晶画面の LED 照明が OFF LARGE モード時の LED 照明 OFF

  • なお、バックライト用 LED が消灯しているとき、どれかのスイッチが操作されると、再び点灯をする。 ( 2019/4/20 修正 )

| ページトップ |

■ 液晶画面レイアウト ■

 万年カレンダーを、縦 64 x 横 128 ドットのグラフィック液晶(SG12864A)の画面上で、如何にレイアウトさせるかいろいろと考えてみましたが、 最終的に次図に示すように決定しました。 後はこの図に従って各項目(年月日および時分秒等)をプログラミングしていきます。

・ NORMAL モード画面

 1行目(Page 0)には、年月 "xxxx/xx" 、"  "/"am"/"pm" の種別、および時分秒 "xx:xx:xx" を表示するエリアです。 2行目(Page 1)は、 曜日の表示エリアです。 3行目(Page 2)から8行目(Page 7)までが、カレンダーの各日にちが表示されるエリアです。

 また、最下行の8行目(Page 7)は、行頭から6文字目以降はカレンダーの日にち表示がされることはないので、画面右下の赤細線枠で囲んだ部分を、 いろいろなメッセージをユーザーに伝えるための、メッセージエリアとして使用しています。

・ LARGE モード画面

 バージョン (Ver. 1.20) で機能追加した画面で、文字サイズを NORMAL モード画面に比べて、縦横2倍(面積4倍)のサイズで表示します。 したがって、 次図に示すように文字表示には1行に 2 Page 分を必要とし、行間には 1 Page 分を割り付けました。 当然ながら日にちの表示は、 NORMAL モード画面のように 7曜カレンダーで表示することはできません。

| Excel ファイル (PerpetualCalendar_parts.xls) | ページトップ |

■ プログラム ■

 当初、CPU にプログラムメモリのサイズが4Kワードの、私の手持ちに多くある PIC16F873A を使用して開発を進めてきました。 しかし、 開発途中でプログラムサイズが肥大化し、残りのメモリが数百ワードとなってしまったため、倍のサイズの8Kワードの CPU に変更することにしました。

 そこで、PIC16F876 または PIC16F876A にしようかとも思いましたが、最近入手したこれらの改良品である PIC16F886 を思い出し、私にとって初めての使用ですが これを使ってみることにしました。

 しかし、改良品である PIC16F886 を、扱い慣れた従来の PIC16F87x と同等のように扱うためには、やはり新たな知識が必要でした。 両者の違いをマニュアルで よく確認する必要があります。 私も少々悩みました。 新たに設けられた ANSEL、ANSELH レジスタの扱いと、CONFIG レジスタが2ワードに増えている点などが 大きく異なっています。

 私にとって初めて使用するものがもう一つありました。 本機の目玉であるグラフィック液晶モジュールで、初めこれには泣かされました。 不運としか言いようがありません。

 液晶でもキャラクタディスプレイモジュールについては、既に何度も使用を経験しているので殆んど問題はないのですが、グラフィック液晶モジュールについては 今回がまったく初めての取り扱いで、アクシデントのため散々な目に合いました。

 次に示す縦左から1列目と2列目の写真を見比べてください。 1列目が正常なモジュールで表示したもので、2列目が不運な異状なモジュールで表示したものです。

 横2行目と3行目の結果写真のようなプログラムはまだ開発前で、1行目のように文字表示のテストだけをしていた頃のことで、ずいぶんと悩まされました。 横2行目と3行目の写真を追加したことで、その表示の異状(異常)さがよく分かると思います。 すべての表示が異状になるのではなく、ある Page のある Column だけが、 しかも複数の箇所で異状な動作(表示)をするのです。

 当時、横1行目の中央の写真のような画面だけがテストプログラムの結果であり、初めはどうしても自分の作ったプログラムを疑ってしまいます。 一体プログラムの どこが悪いのか? 何度も何度も見直します。 どこか思いもよらないところでミスを犯しているのかもしれない。 論理的に合わないところがあるのではないか?

 思いつくことはすべて試みました。 ・・・でも結果は変わらない。 ・・・異状のままだ。 ――― わからない。 分からない。 解からない。 ・・・・・・

 3週間ほど悪戦苦闘で悩み続けた結果、やはり自分の作ったプログラムに間違いはない。 この液晶モジュールが不良なのだ。 ――― と結論付けました。

新たに購入した正常なモジュール 3年前に購入した不運なモジュール
PIC16F873A で作成の同一プログラム PIC16F886 で作成の同一プログラム

 そして、早速 "秋月電子通商" へ新たに グラフィック液晶モジュールの注文をしました。 これまで開発で使用してきた不良(?)のモジュールも、 この万年カレンダーの構想を抱いた3年ほど前に、同じく "秋月電子通商" で購入したもので、今回のプログラム開発まで保管をしてあった新品のものです。  ちなみに私の場合、パーツを購入するときにはいつも、必要とする個数以上の数量を予備を含めて購入しているのですが、この液晶モジュールは比較的高価なため そういうわけにはいきませんでした。

 そして、新しく購入したモジュールに交換すると、・・・私の考えは的中しました。 見事に私の考えている通りの正常な表示をするではありませんか?  それが上写真の縦1列目のものです。 今までの私の悪戦苦闘は一体何だったのだろうか? この間に過ごした無駄な時間を返してくれ・・・。 正常に表示したことへの清々しさと、 一気に気が抜けてしまった空しさを、同時に味わいました。

 これで一件落着。 不良な液晶モジュールはいずれ廃棄するつもりでいました。 ・・・ところが、ところがなんです。 上写真の縦3列目を見てください。 不良と決断した縦2列目のモジュールと同一のものなんです。 これには参りました・・・。 液晶モジュールに、いつまでも呪われている・・・。

 本機の万年カレンダープログラムも一段落がついて、このホームページの資料を作成するためのついでに、不良と決断した液晶モジュールを コントロール基板に繋いでみたのです。 ・・・正常に表示するではありませんか? PIC16F886 との組み合わせであれば正常なんです。

 PIC16F873A との組み合わせでは縦2列目のように異状な表示をするのに対して、PIC16F886 との組み合わせであれば縦3列目のように正常に表示をするのです。

 両者のPICの各出力ポートの出力電圧が、微妙に違っているのでしょうか? それとも出力タイミングが異なっているのでしょうか? そこまでは分かりません。 調べる気力すら今の私には残っていません。

 ちなみに、新しく購入したモジュールへのケーブル配線を、下写真のように間違って基板の表側に付けてしまったため、PIC16F886 では正常と化した3年前に購入したモジュールを、 この万年カレンダーでは使用することにしました。

 ・・・ そのようなわけで、すったもんだをしていて、このホームページの発表が長らく滞っていた原因となりました。
      本機プログラムの開発中(デバッグ中)の様子

○ LARGE モード画面表示の機能を追加 ( 2014/12/20 更新 )

 冒頭でも述べたように、文字サイズが縦横2倍(面積4倍)で表示する、LARGE モード画面表示を追加しました。 MODE / SETスイッチを押すことによって、 通常の NORMAL モード画面表示と LARGE モード画面表示を、どちらへも相互に即座に切り替えることができます。

 とは言うものの、当初はうまく考え通りにはいきませんでした。 NORMAL モードから LARGE モードに切り替えた途端、・・・ 暴走でした。 テストプログラムによって メインルーチンから直接 LARGE モードを呼ぶときには何ら問題なく表示するのですが、MODEスイッチで切り替えると暴走する ――― というものです。

 ピンとは来ましたが、一応はプログラム中の "MODE / SET スイッチの処理" (set_switch) を隅々まで目を通しました。 やはり (set_switch) 自体には、 特におかしなところは無さそうです。

 そこで、スタックとの関係を調べてみることにしました。 次は一例ですが、MODEスイッチで LARGE モード画面に切り替えたときに、画面1行目の "年月 (yyyy/mm) の表示 " (yyyymm_display_lg) をするときの、数字1文字を表示するサブルーチンコールの様子です。 (次に示す (xxxx) の xxxx はサブルーチン名を表す。)
    (main) → (set_switch) → (yyyymm_display) → (yyyymm_display_lg) → (number_disp_lg) → (Glcd_DispChr_lg) → (yGlcd_WriteData) → (Glcd_WriteData) → (Glcd_Write)
           (1)             (2)                 (3)                    (4)                 (5)                  (6)                  (7)                 (8)
 メインルーチンから数えると、最終の (Glcd_Write) までに8回サブルーチンコールのネストを重ねています。 PICにはスタックが8ワードしか存在しないため、 これでいっぱいいっぱいです。 ところがここに、タイマー0割り込みが 0.32 m秒 (= 1/(12.8M/4) * 4(プリスケーラ値) * 256) の周期で割り込んできますから、 スタックはオーバーフローして壊されてしまいます。 結果、サブルーチンからまともにリターンできる筈もなく、プログラムは暴走状態となります。

 同様なことが LARGE モードでは、"年月 (yyyy/mm) の表示 " (yyyymm_display_lg) だけでなく、"時分秒 (hh:mm:ss) の表示" (time_display_lg)、"カレンダー(日と曜日)の表示" (calendar_display_lg) でも、数字を表示するときにはいつでも起きうることになります。

 そこでこれを回避する方法として、サブルーチンを呼ぶ方と呼ばれる方が1対1の関係になっているところ (1)と (3)には、スタックを使用しないように CALL, RETURN命令を止めて、 GOTOで飛び GOTOで戻るように改めました。 そのためプログラムが少々分かり辛くなったかもしれませんが、やむを得ません。

 スタックがオーバーフローする場面がもう一か所見つかりました。 実は LARGE モードの機能追加をする以前のバージョンのときから、時々起きる事象がありました。

 それは、NORMAL モードのカレンダー表示をしているときに、UP スイッチまたは DOWN スイッチを押すことによって、現在画面表示されている年月表示とカレンダー表示を、 月ごとに前進、または後退させることができるのですが、このとき UP スイッチまたは DOWN スイッチを連続的に何度も押していると、時々ですが画面が固まってしまって 時分秒の表示が止まり、スイッチ入力もまったく受け付けなくなってしまうのです。

 ??? でした。 UP スイッチまたは DOWN スイッチを操作していて、いつも必ず起きるわけではなく、時々この事象が発生するのです。 一体これは何なのだろう ・・・ と思っていました。 しかし、結局これもスタックのオーバーフローが原因と分かりました。 上の事例と同じようにサブルーチンコールの様子を調べてみると、
    (main) → (up_switch) → (down_up_display) → (Glcd_DispStr) → (Glcd_DispChr) → (font_write) → (Glcd_WriteData) → (Glcd_Write)
           (1)            (2)                  (3)               (4)               (5)             (6)                 (7)
となり、この状態のときに上事例と同じように 0.32 m秒周期で割り込みがかかりますが、3125 回に一度、すなわち1秒間 (= 0.32 * 3125) に一度の割で、 "時分秒 BCD カウンタのインクリメント" (bcd_ssmmhh_inc) のため、割り込みルーチンからサブルーチンコールが行われます。
    → (interrupt) → (bcd_ssmmhh_inc) → (bcd_ss_inc) → (inc_bcd)
    (8)            (9)                 (10)            (11)
 これでは一たまりもありません。 UP スイッチまたは DOWN スイッチを押したときと、丁度 3125 回目の割り込みが重なったときに事象が現れるのです。 そこで上事例と同じように、(1)と (9)には GOTOで飛び GOTOで戻るように改め、また (10)のところでは (bcd_ss_inc) のサブルーチンコールの使用をやめて、サブルーチン (bcd_ss_inc) の内容を直接埋め込みました。

 以上、どちらの場面においても現在は、サブルーチンのネスト数と割り込みルーチン、および割り込みルーチンからのサブルーチンコールの総回数は最大の8回で、 満タン状態ですが一応スタックの容量を超えることはありません。 しかし、今後機能追加等でプログラムを更新するような場合には、以上を踏まえて十分注意を払う必要が あります。

 趣味で PICを使ったプログラムを作るようになって早や 10年近くになりますが、スタックをオーバーフローさせたことは私にとって初めての経験でした。

○ スイッチの操作性を改善 ( 2014/12/29 更新 )

 LIGHT スイッチで、グラフィック液晶の LEDを ON → OFF、または OFF → ON させたいのに、自分の意志とは違って若干長めにスイッチを押したような場合に、ON → OFF → ON、 または OFF → ON → OFF となってしまうことが時々起こりました。

 スイッチ入力の読み込み(sw_input)サブルーチン内では、250ms のウエイトを持たせてその間は、次のスイッチ入力を受け付けないようにしてありますが、それでも上記の ようなことが時々起きるため、LIGHT スイッチの処理(light_switch)内にも 500ms のウエイトを置き、すなわち 0.75秒経過しないと次のスイッチ入力を受け付けない ように改めました。

 また SET モードのとき、NORMAL モードまたは LARGE モードに再び戻るために、最後の"秒"の更新の後に SET スイッチを押したとき、やはり LIGHT スイッチのときと同じように SET → NORMAL → LARGEモード、または SET → LARGE → NORMALモードとなってしまうことが時々ありました。

 そこでこれを回避するため、SET モードから戻る時に限り、フラグとカウンタ(modeflg)を設けて約3秒間は、新たな NORMAL / LARGE モードの切り替えを受け付けないように 変更しました。

○ 12時間表示時の am / pm 表示の不具合とその他を修正 ( 2019/4/20 更新 )

 12時間表示時の am / pm の表示に一部誤りがありました。 私の認識違いからその表示が妥当ではありませんでした。 詳細は、別ページ "014. 7セグメントLED表示時計" の "12時間表示の扱いについて" の項を参照願います。

 他に、Ver.1.20 から Ver.1.21へ更新をしたときに、デグレを起こしていたのを修正。 LARGE モードにおいて、SIGNAL スイッチの押下時に、"Signal On" または "Signal Off" のメッセージ が表示されなくなってしまったのを、表示するように修正をしました。

 以下はデグレとは関係はありませんが、併せて修正をした点について挙げておきます。

 グラフィック液晶画面のバックライト用 LED の照明点灯の制御について、本機の起動直後は LED の点灯をデフォルトとしており、その後どのスイッチも操作しない状態が15分以上続くと、 自動的にバックライト用 LED を消灯させています。

 そして、再び点灯させるためには必ず LIGHT スイッチの操作が必要だったのを、どのスイッチが操作されても点灯をするように修正をしました。 LIGHT スイッチの本来の機能である、 OFF → ON または ON → OFF の押すごとに点灯と消灯を交互に繰り返す、トグル動作については従来と変更はありません。

 また、NORMAL モードにおいて、UP スイッチまたは DOWN スイッチの操作で、年月表示とカレンダー表示を、月ごとに前進、または後退をさせて表示することができる機能を持たせてありますが、 私の考慮不足から、その表示中にも SET スイッチによって LARGE モードに切り替え、または SET モードへの移行ができました。

 しかし、これらの振る舞いは少々不都合なため、このときには SET スイッチの操作は無視をして、LARGE モードへの切り替え、または SET モードへの移行ができないように修正をしました。 あくまでも、SET スイッチによる LARGE モードへの切り替え、または SET モードへの移行は、年月表示とカレンダー表示が現在(本日)を表示している場合のみを、 可能とするように変更をしました。

○ 潜在的に潜んでいた不具合を修正 ( 2024/5/29 更新 )

 本機「174. グラフィック液晶表示 万年カレンダー」の他、次の3つの作品のプログラムには共通した機能を盛り込んでありました。 これらのディジタル時計では、最近の私が作製をするディジタル時計とは異なって、 バックアップ用の電池等を内蔵していないため、何らかの理由があって一度電源を落としてから次に電源を入れ直したときには、当然ですが、時、分、秒を始めすべてのカレンダー情報は、 プログラミングをしたときの初期状態に戻ってしまいます。
      「173. 6桁ニキシー管時計(改良版)」
      「104. ドットマトリクス 5 x 7 2色 LED 表示時計」
      「097. ドットマトリクス 8 x 8 LED 表示時計」
 そのために再度これらのカレンダー情報を、リアルな現在値に設定をし直さなければなりませんが、電源を入れ直したときがプログラミングをしたときよりも、時間的に離れていれば離れているほど、 大幅な設定し直しが必要になります。 また、プログラムの開発者である私の場合には、特にデバッグ中にはこの設定し直し作業が頻繁に起こります。

 そこで、この設定し直し作業を少しでも軽減するために、時刻、年月日を変更したときや、1日に一度日付が変更されたときには、そのときのカレンダー情報を自動的に EEPROM にバックアップを取って、 リアルな現在値との差を最大でも1日以内になるようにしています。

 そして、電源を入れ直したときには、EEPROM にバックアップのカレンダー情報を読み出して、その情報で時計が起動するようにしています。 ところが、その読み出し情報に問題があったのです。 実は最近、上に挙げた「173. 6桁ニキシー管時計(改良版)」の機能追加で、プログラムを修正していたときにバグを発見しました。

 次の図は、Microchip Technology Inc 社のデータシート PIC16F882/883/884/886/887 から抜粋をしたものですが、PIC16F87XA でも共通で、この EECON1 レジスタ の bit7 EEPGD ビット に注目をしてください。


 この EEPGD ビットは、EEPROM データメモリにアクセスするか、またはプログラムメモリにアクセスするかを選択するもので、EEPROM にアクセスする場合には EEPGD ビットをクリア します。 結論から先に言うと、上述の4つのプログラム内では、EEPROM にバックアップデータを書き込む場合には、間違いなく EEPGD = 0 にクリアをしていましたが、読み出しを行う場合だけ何故?か EEPGD の指定が見当たりません。 どのプログラムも右に倣えで 10 年以上も前のことなので定かなことは分かりませんが、たぶん、単純にクリアするのを忘れていただけなのでしょう。

 上述のように「173. 6桁ニキシー管時計(改良版)」の機能追加で、プログラム全体の一新を行ったのですが、EEPROM のバックアップに関する部分だけ旧コードをコピーして使用しました。 そして、電源を入れ直すごとに正常に時(とき)を刻み始めたり、そうでなかったりで、どうも動きが一定ではなく定まらないのです。

 もう一度上図の EEPGD ビットを見てください。 R/W-x の x とあるように、電源を入れる度にビットの初期値は 0 になるか 1 になるかは不明で定まらないのです。 したがって、たまたま 0 になっていたときには、 以降の EEPROM のアクセスには問題がありません(次に電源の入れ直しを行うまでは正常が続く)が、1 になっていたときには、読み出しを行っても EEPROM がアクセスされることはなく、思惑とは異なってプログラムメモリが 読み出されて、バックアップのカレンダー情報を読み出すことはできません。

 何年か以前に、本機「174. グラフィック液晶表示 万年カレンダー」を作製された方から、今思えばこれが原因と思われる異常の報告を頂いたことがあったのですが、そのときには原因の発見には至りませんでした。 本機の起動時に、EEPGD = 1 になっている場合だけに不具合が発生し、EEPGD = 0 になっていれば以降は何の問題もなく不具合が再現することがないため、原因の発見ができませんでした。 このように、単純なケアレスミスというか凡ミスが原因でしたが、これが今日まで潜在的な不具合として潜んでいたわけです。

 同一のプログラミングが原因なので、上述したように本機の他、3つの作品のそれぞれのプログラムを一斉に修正を行いました。 これらの作品の複製を作製された方々には、大変ご迷惑をおかけしました。 遅きに失する ― 感は拭えませんが、ここにお詫びをいたします。

現在の最新バージョン: Ver. 1.31  ( 2024/5/29 更新 )




ソースファイル (PerpetualCalendar.asm)
 サウンド・サブルーチン (Sound.sub)
 グラフィック液晶表示器 (SG12864A) 制御サブルーチン (G_LCD.sub)
 文字フォント(5 x 7)データテーブル (Font5x7.tbl)

HEX ファイル (PerpetualCalendar.hex)

 上記の文字フォント(5 x 7)データテーブル (Font5x7.tbl) については、後閑哲也さんのホームページ "電子工作の実験室" 中のダウンロードファイル ( http://www.picfun.com/PIC24H/AP/GLCD2.zip ) に含まれる font.h を使用させていただき、私がアセンブラプログラム用に編集し直したものです。 ( 参考サイト を参照 )

| ページトップ |

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

 ここに示すプリント基板(1)は改造前のもので、図と写真にそれが反映されていませんので悪しからず。 実際には CON4 の L型ピンヘッダを 通常の縦型のピンヘッダに変更がしてあります。 これはケースに収納する際に相棒のピンソケットが、プリント基板(2)と接触する恐れがあったためにとった処置です。

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

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

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

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

 このプリント基板(2)については、当初、右の参考写真のように作製していたのですが、やはりケースに収納する際にサイズ的にいろいろと問題があったので、一回り小さなものに作り直しました。

コネクタ, ケーブルを 取り付け前の様子 , 取り付け後の様子 ( 参考 )

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

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

コネクタ, ケーブルを 取り付け前の様子 , 取り付け後の様子

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

■ ケースへの液晶モジュールの取り付け ■

 グラフィック液晶モジュール(SG12864A)をケースへ取り付けるのに、このモジュール基板の取り付け用の穴がΦ2.5(実際にはΦ2.6?だと思う)と なっているため、通常私が使用する M3 用のスペーサーが使用できません。 また長さも今回のケースへ取り付けるのに 24 mm のものが必要で、一般的ではありません。

 そこで、M2.6 用のスペーサーを自由な長さで自作してしまおうという試みです。 実はもうすでに "沖電気 MSM5509 デジタル時計" で経験済みで、 詳細はそちらの "ケースへのプリント基板の取り付け" の項をご覧になってください。


 左上写真の中央の4個の白いものが、今回自作をしたM2.6 用 長さ 24 mm のスペーサーです。 右上写真がそのスペーサーを使用して、実際にモジュール基板をケースに取り付けた様子です。

  [ 工具の紹介 - 1 ]
左の写真は、タップを切る(めねじ)ための工具で、左下のT字型のものは大昔に購入したT型タップホルダーですが、 私が購入したものはM3 以上のサイズのタップしかチャックに装着できないため、今回の用途のM2.6 の使用ができません。

そこで上の横に長いレンチ式のタップハンドルを数年前に購入しました。 これであればM1 〜 M6のサイズに対応できます。

右下の4本並んでいるのが実際にねじを切るタップで、左の小さいものから順に、M2.6、M3、M4、M5 用のものです。 もちろん今回の用途では、 M2.6 が使用できればそれでいいのですが。

  [ 工具の紹介 - 2 ]
左の写真は、真鍮、銅、アルミなどの金属パイプをカットするための工具で、これも比較的最近の数年前に購入したパイプカッターです。 写真のものではパイプ直径が 3 〜 22 mm まで対応しています。

今回の用途では対象物が細くて金属ではないため、カッターナイフでも代用が可能ですが、この工具が一つあるといろいろと重宝します。

ただ、私のまだ数少ない使用経験では、精度を出す(必要な長さ)のが比較的難しいように思います。 長さ的にある程度のアバウトさが許されるような用途には、 カナノコなどでギコギコ切ることに比べればいとも簡単に、しかも切り口を垂直に切断することができてしまいます。

| ページトップ |

■ ケース加工図 ■

 使用したケースは、100均(セリア)で購入した "クリアケース ミニ (L-8033) サナダ精工" という、ポリスチレンケースです。 前項の ケースへの液晶モジュールの取り付け で述べた、"沖電気 MSM5509 デジタル時計" で使用したケースと同じものです。

| ケース加工図 (PerpetualCalendarCS.CE3) |

ケース左側面から見たところ 蓋をあけて上面を真上から見たところ ケース右側面から見たところ

ケース加工においてのヒント

 上の ケース加工図 中の下箱右側面図では、縦に並んだ押しボタンスイッチ(タクトスイッチ)用、および基板の取り付け用の8個の穴の各間隔が、 便宜上小数点以下2桁の 7.62 mm と指定がしてありますが、実際にこの値をケースに写し取るにはどうしたらいいのでしょうか? (右上の写真も参照)

 通常のメートル目盛りの物差しなどでは至難の業でとうてい無理でしょう。 それではどうすればいいのか? そもそも押しボタンスイッチが取り付けられているユニバーサルプリント基板が、 2.54 mm すなわち 1/10 インチ ピッチで穴開けされているため(2.54 x 3 = 7.62 mm)で、インチ目盛りの物差しがあれば可能ですが、あまり一般的ではありません。

 話は少々それますが、ケースを加工する場合にその穴開け等の位置を、どのようにケースに写し取っていますか? 物差しで測りながら直接ケースに書き込んでいますか? ――― それでは、私がいつも行っている方法をご紹介しましょう。

 まず1ミリ方眼の方眼紙(グラフ用紙)を用意します。 最近では 100均で簡単に入手が可能です。 このグラフ用紙を、加工するケースの面と同じサイズになるように、 カッターナイフ等で切り取ります。 上図の下箱右側面図の例では 36 x 76.5 mm (実際には各辺とも 1 mm 程度小さい方が後の工程がし易いかも) となります。

 そして、この加工面のサイズに切り取ったグラフ用紙に対して、穴開けの位置等を記入していきます。 記入は鉛筆等で十分です。 記入がすべて終了したらこのグラフ用紙を、 実際のケースの加工面にセロテープで貼り付けます。 このときセロテープはグラフ用紙が加工面から移動しない程度の量で、四方をちょい止めできれば十分です。

 ただし、グラフ用紙と加工面が正確に重なるように慎重に行う必要があります。 そのために前述のように、切り取ったグラフ用紙の各辺が 1 mm 程度小さい方が、この作業が し易いと思います。

 そして最後に私の場合は、千枚通しで穴開けの位置を押す力でポイントしていきます。 もちろんポンチも所有していますが、今回のケースのように樹脂系の材料の場合などには、 千枚通しがいいと思っています。 ポインティングがすべて終了したらグラフ用紙はもう必要ないため、加工面から剥がします。 後は通常のドリル作業に入ります。


 そこで話を元に戻しますと、まず未使用のユニバーサルプリント基板を用意し、これを物差しとして使用するのです。 そして左上写真のように切り取った グラフ用紙に対して、鉛筆で穴位置をプリント基板の3穴(2.54 x 3 = 7.62 mm)ごとにポイントします。 この方法であればインチ目盛りの物差しから位置を写し取るよりも、 かなり正確にしかも簡単にポイントすることが可能です。

 右上写真は鉛筆でのポインティングが終了したグラフ用紙を、ケースの加工面に貼り付けたところです。 ここでは透明なセロテープでは写真で分かり辛いため、 色が付いたビニールテープで貼っています。 後は前述のように、千枚通しで穴開けの位置をケースの加工面にポイントしていきます。

| ページトップ |

■ 使用部品表 ■

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

(データシート)
PICマイコン .................... PIC16F886
トランジスタ .................... 2SC3669Y
グラフィック液晶モジュール .................... SG12864A
超高精度クリスタルモジュール .................... KTXO-18S

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

■ 参考サイト ■

ドットマトリクス LED 表示時計 .......... http://xyama.sakura.ne.jp/hp/MatrixLED_Clock.html
電子工作の実験室 / グラフィック液晶表示器用ライブラリ .......... http://www.picfun.com/app24Hframe.html
寝ても覚めてもPSoC / グラフィックLCD[SG12864A]について .......... http://blog.goo.ne.jp/mimipsoc/e/b25d80a77d17b8ea3a234b8a8b8c4d42
国立天文台 / 暦計算室 / トピックス / 1月1日あれこれ 等 .......... http://eco.mtk.nao.ac.jp/koyomi/topics/html/topics1994.html

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


Copyright (C) 2014-2024 やまもとみのる
初版:2014年9月2日、初公開:2014年11月24日、最終更新:2024年5月29日