ESP8266のJJY電波時計のスケッチ公開
これまで作っていたESP8266を使ったJJY電波リピーターと電波時計受信機のうち、受信機の方が何とか安定して時刻を知らせるようになった。とりあえずこちらを先に、ソースコードと回路図を公開することにする。
電波時計は長時間動かすものだから、本来はESP8266のような大喰いのWiFiモジュールで作るのは筋違いだが、WiFi環境が必要な電波リピーターにESP8266を使ったので、開発環境を共通にしたかったのと、気楽に始めたのにうまく動かず、止めるに止められなくなったせいでもある。
前にも書いたが、JJYの受信パルスは1秒に一回の超低速通信(1bps)である。クロック80MHzのESP8266なら沢山のロジックを組み込んで、相当インテリジェントなエラー修正が出来ると意気込んで始めたのだが、これがとんでもなく難関で、ほんの少しでもノイズが出るような受信環境では全く正しくデコードができない。
リピーターのコイルから数十センチも離すと、受信モジュールが正規の福島(おおたかどやま)からの電波も受け始めて干渉を起こすらしく、年月日などに目茶目茶な数字を出し始めて全く話にならない。出来ないとなると、むらむらと反抗心が出てきて何とかしてやろうと、いつもの悪い癖が出る。
この3週間、半分泣きべそをかきながら、意地になってデバッグに熱中していた。その結果、何とか市販の電波時計程度の信頼性のある時計になったので、Arduinoのスケッチソースリストと、回路図を公開することにする。どれだけ迷走したか。詳しくはこれ以降の作業記録で。
やっぱり日本の女子は強い(9/9/2018)
その前に、ちょっと電子工作とは違う話題を少し。プロテニスの話である。手が届きそうで届かなかったテニス4大大会(グランドスラム)の日本人の優勝は、天真爛漫なあの「大坂なおみ」があっさり全米で達成してしまった。
4年前の錦織の全米準優勝も驚いたが、今度はもっとすごい。勝ち方が豪快である。彼女のことだったら、本当のグランドスラム(1年間に、全米、全豪、全仏、全英すべてに優勝)をやってのけるかもしれない。
錦織のときにも同じことを書いたが、野球はアメリカと日本でしか騒がないのに対し、テニスは全世界が対象である。しかも、サッカーは庶民が中心だが、テニスはセレブのスポーツファンを巻き込む。ウィンブルドンの観客の平均年収は2000万円という話を聞いたこともある。世界に与える影響は、野球の比ではない。
ちょっと気になるのが、彼女の出自の問題だ。今、世界は、水面下では色々あっても建前上は人種の区別をしないことに極度に神経質になっている。それなのに日本のマスコミが彼女の帰国会見で、実に無神経な質問をしたのには驚いた(あなたは何人?)。
こういう話は、すぐに世界中にひろまる(マスコミの浅はかさは世界共通)。世界から日本が馬鹿にされるのは身から出た錆でしようがないけれど、大坂選手が日本に愛想をつかしてアメリカ国籍に換わってしまわないことを祈るばかりである。
I2C液晶を2台とも4本の結線だけで動かす(9/10/2018)
電子工作の話に戻ろう。Aitendoで入手した2台のI2C液晶の始末である。このうち一台は電源を逆接してしまい、破損が心配されたが、幸運にも壊れていなかった。バックライト付きだから今のところACアダプターのついた電波時計に使う予定である。
インターフェースはI2Cだが、液晶の本体は12本のピンが出ており、内部で使うコンデンサーや、I2C/SPIの識別をする制御線などの追加の配線が必要である。工作のついでに、2つの液晶がいつでも使えるようチップコンデンサーなどを使って整備しておくことにした。
このままでは、ブレッドボードに配線を加える必要があり、特にひとつは動作テストを急いだため、ジャンパーコードやコンデンサーを空中でハンダ付けする完全なバラック状態になっている。なお、このコンデンサーは省略することが出来ない。はずすと簡単に動かなくなる。
久しぶりに秋月にでかけ(このところはAitendoが多かった)、1μFのチップセラコンを入手した。相変わらず、ここはいつも賑わっている。帰って早速チップセラコン(2012)の空中配線を楽しむ。I2Cだけだとピンヘッダーは4 本ですむのだが、4本だとやや強度に不安が出る。
課題が残った。液晶とバックライトの発光面との接着である。両面テープで貼るのは手軽で良いが、蛍光面にテープが見えて見栄えが悪い。それと時計の表示装置にするのならバックライトなしの液晶の方が消費電力が少なくて済む。また買いに行かなければ。
JJY電波リピーターのバグを解消した(9/14/2018)
電波時計の前にやることが残っている。JJY電波リピーターの不具合である。リピーターはNTPから時刻を貰っているので正確無比のはずなのだが、長時間動かすと、何故か分単位で遅れることがある。
NTPや、WiFiが原因であることは考えにくいので、すべてこちらが悪いのだが、原因が思い当たらない。NTPの正時(0秒)を待ってパルスシーケンスを始めるのだが、パルスシーケンスは59 秒間の最後がポジションマーカーパルスで0.2秒、この残りの0.8秒で次のNTP時刻が変わるのを待って同期させるロジックである。
たとえ遅れたとしても、秒単位の遅れのはずなのにパルスシーケンスは、1分以上の時刻遅れを表示する。しかも、エラーは長時間のときにたまに発生するだけで、普通は全く問題ない。
長時間(2時間以上)コンソールにメッセージを記録し続けてやっと原因がわかった。何と本来は59.2秒で終わるはずなのに、59秒より早く送り終えるところが見つかった。ロジックは59とか0などの絶対値ではなく、NTPで得た秒データの変化をトリガーにしている。
このままだと59秒の時に、そのときの「分」データを得てそれを新しい時刻の「分」にするので結果として1分遅れることになる。なぜ早くなるのかの原因は全く見当がつかない。どうしようか。
迷ったけれど、対症療法で、NTPの秒データが00になるまでべたに待つことにした。CPUは回りっぱなしで精神衛生上あまり愉快ではないが背に腹は代えられない。幸いなことにこの修正後は全く問題なく動いている。
焦電型人感センサーを更新(9/15/2018)
さらに道草を食っている。階段の照明の入り切りに使っていた焦電型人感センサーが何となく感度が悪くなり、階段の前でパントマイムをやらされることが増えてきた(動きがあると反応する)。
人感センサーについては、実は、一年前、秋月で偶然これを見つけて買ってある。以前、千石で買おうと思った赤外線センサーNapionの改良形のようだ、値段は半分以下の¥480だった。テストしただけで、部品箱に眠っている。
階段の上での身振り手振りが、段々煩わしくなったきたので、これに更新することにした。久しぶりの汎用基板でのハンダ付けが楽しい。UEW線を持ち出さずに、すべてのパーツのリード線を活用し配線する。
作り替えたのはセンサー部だけで、電源の入り切りなどの制御ユニットはこれまでのものを流用する。何事もなく完成した。ちょっと物足らなかったが、出来上がりには満足である。今度のセンサーはやたら高感度で、階段に近づくだけで反応する。
考えてみたら、最初のセンサーを作ったのは、もう6年も前のことだった。まあ、6年も使ったのだがら減価償却はできているだろう。
エラー回復ロジックをつけた電波時計ロジックの工夫(9/20/2018)
電波時計の開発にぐずぐずしているのは理由がある。今回のプロジェクトの本筋は、JJY電波リピーターで、電波時計は単なるテスト環境のつもりだった。我が家にある市販の電波時計は、腕時計、目覚まし、掛け時計とあらゆる種類が整い、今さら電波時計を自作する必要性はない。
それなのに電波時計の方に夢中になっているのは一種の逃避である。電波リピーターはハードの要素が大きい。しかもハードと言っても電波という高周波の世界である。所長の高周波の知識は、60年近く昔の少年時代から一歩も進んでいない。大学時代の知識は超絶的な理論ベースで、実践には見事なほど役に立たない(自分であきれるばかり)。
何となくハードを避け、自分の得意なソフトにこだわりたくなる潜在意識があるようだ。電波時計のハードは、いじるところがないが(受信モジュールには手が出せない)、ソフトには改良の大きな余地があるような期待がある。
JJYの標準電波のロジックは簡単な構造である。一秒に一回の立ち上がりパルスのタイミングが、その時の正確な秒を示し、そのあとのパルス幅でコードが決定する(0.5秒が1、0.8秒が0)。10秒に一回、マーカーパルス(0.2秒)が出て、次のフレームへ進む。
さらに1分に一回、このマーカーパルスが冒頭に出て正時(0秒)を定義する。6つのフレームは、時分、月日、西暦、曜日などに分かれ、時分については第4フレームにパリティビットがついて誤り検知が出来るようになっている。
この連続マーカーパルスさえ正しく検知できれば、データが途中乱れても相当なエラー回復が可能である。いわゆるフレーム同期というやつで、月日、西暦などのデータは数多く重複するので、フレーム単位にデータを貯めておけば、大きな狂いを防ぐことも出来る。
こうしたことを頭に入れて、オシロでJJY受信モジュールの出力波形をつぶさに観察すると、ノイズはパルスの立ち上がりや立下りでチャタリング風に出る短いパルスが多く、パルスの真ん中を分断することは少ない。チャタリング抑止のロジックを入れればだいぶエラーを減らせそうだ。
さらに、パルス巾の認定にも工夫をした。参考にさせて貰ったソースリストでは、パルス巾の有効範囲がひどく狭く、それ以外をエラーにしている。このため、ちょっとノイズが出始めると、エラービットばかりになって話にならない。
考えてみれば、パルス巾は、0.2、0.5、0.8秒以外はないので(15分、45分に出るモールス信号列を除けば)、中間値をすべてエラーにするのはおかしい。少々強引だが、ここではエラーの範囲をなくし、適当な区切りですべてを何らかの有効データとみなして後で調整することにした。
思いつくエラー修正を片っ端から盛り込むも迷走(9/23/2018)
さらに、次のようなフレーム単位の修正ロジックを入れて、実験を開始した。測定では正式のJJY標準電波は、PCルームではノイズだらけで全くデコード不能になるので、主にNTPを使った電波リピーターの出力をソースにする。それでも正規のJJY電波と干渉するせいか少し離すとノイズが出る。
●正時(0秒)と正時の間のフレーム数が、6つ以外はエラーとしこの間のデータは捨てる
●マーカーとマーカーの間のパルス数が規定以外(9ビット)ではエラーとし、このフレームのデータを無効とする。
しかし、この程度では少し波形がノイズっぽくなってくると、データが全く有効ではなくなり、表示は目茶目茶になる。特に致命的なのが、正時を判断する連続ポジションマーカーの取りこぼしで、たとえそのあとのフレームを正しく受信していても、西暦などもとんでもない数字に変わってしまう。
そこでさらに、
●キャッシュにデータを蓄えておいて、1分間正しくデータ(6フレーム、9ビット)を拾ったとき にのみ始めて、そのときの時分、年月日を表示する。
●10秒ごとのフレーム単位に 有効/無効フラグを設定し、年月日のデータは使いまわしをする。
などのデータ保全を狙った改善を行った。だいぶん精度が高くなった半面、正しい時刻に戻るのに時間がかかるうえ、時々、月日や西暦が出鱈目になる不具合は改善されない。エラーの程度を定量的に把握することが難しく何が効果があるのかわからないので泥沼状態である。
試しに正式なJJYの受信できる場所で動かしてみる。電波が安定しているときは良いが、やっぱり、少しノイズが出始めてエラーになったら全くダメダメで、なかなか回復しない。既に正しく受信できているはずの西暦や、月日も目茶目茶になってしまう。
別の不具合が落着。やっと日にち違いの原因が究明された(9/25/2018)
それでも受信エラーが僅かなうちは修正が効き、リピーターに近づけている限り、正しい時刻を表示するようになってきた。JJY標準電波の方も場所を選べば安定して受信できる。しかし、受信機にはまだもうひとつ大きな問題が残っている。
実際のJJY標準電波を受信すると受信機の日付が一日先になるのだ。リピーターから受信していれば合っているのに、標準で一日ずれるのは、要するにリピーターが出すパルスシーケンスがずれていることを示すが、リピーターが表示している日付とパルスシーケンスは全く同じリソースからとっており、ここで誤りが起きるのは不可思議としか言いようがない。
例の辻褄合わせで直した「とがめ」が出ている感じがする。今度も閏年を疑って再度テストステートメントを挿入して確かめるが、問題はない。そこで少しづつ、printfを入れ込んで犯人を追跡していった。その結果、電波時計の方が帳尻合わせをしているようで、犯人はリピーター臭い。
ビットの送り込みや、UNIX経過秒なども調べるが問題なし。さんざん調べまわった結果、やっと原因がわかった。NTPの通算日データが0オリジンだったというオチである(JJYは1オリジン)。NTPでは通算日と月日の両方のデータが独立して取れるようになっており、これが発見を遅らせた。
奥歯に物がはさまったように気になっていたJJYリピーターと電波時計の一日の狂いが遂に究明された。最近は物忘れが激しく、つい10年も経たない職場の同僚の名前を思い出せなくて数日悩むことがあるが、それに匹敵する「もやもや感」が解消され、気分が良い。
もう一歩踏み込んでエラー補正。何とか及第か(9/27/2018)
市販の電波時計が受信できるところでは、殆どエラーなしに受信ができるようになってきた。ただ、一分ごととフレーム毎のエラーチェックを厳密にしているはずなのに、まだ年月日が、ときどきインチキになるときがある。
これがなぜ起きるのか、調べているうちに、この現象は偶にではなくしょっちゅう起こりうる現象であることがわかった。つまり誤ったポジションマーカーを途中で拾うと本来入るべきフレームではないところに別のデータが送り込まれる。
当然、そのフレームはエラーになるが、次のフレームは0から始まるのでビット数が合ってそのフレームが有効になってしまうのだ。このフレームは所定の場所ではないので、データはでたらめになるというわけである。これを避けるには、正時から積算しているシステム内の秒数とフレーム数の照合をする必要がある。
生の秒数と、フレーム番号を比較するのは少し抵抗があったのだが、この秒数は、連続したポジションマーカーの時、0に戻しているので信頼性は高い。やってみると、この効果は絶大で、年月日はまずどんなことがあっても変化しなくなった。やっと電波時計らしくなった。
さらに、一度、正確に手に入れたデータはUNIX経過秒の形で残し、1分後のデータに不安がある時は、これを更新せず、前の経過秒に秒数を足す形で表示を守る。この秒数は、ArduinoIDEのタイムスタンプmillis()まで動員した。ちょっと禁じ手に近い技だが、理論上は、とりあえずは電波が受信できない状態でも時間は守れる。
JJY電波時計のESP8266用スケッチソースコードの公開(9/30/2018)
居間に持ち込んでフィールドテストを続ける。本来のJJY電波の到達するところは殆どエラーなしで順調である。たまに数分遅れる時があるが、すぐに復帰する。これを避けるのは、電波時計の中にRTC(リアルタイマークロック)を入れれば完全に解決するが、元はと言えば、電波リピーターのテスト環境のつもりで開発してきたので、そこまでやる気はない。
消費電流の多いESP8266とバックライト付きの液晶を使った電波時計だが、何かの参考になるかと思い。ここに回路図と一緒にスケッチソースコードを公開することにする。参考にさせていただいたソースコードはここである。復号のところは大いに参考にさせてもらった。あらためて御礼申し上げたい。
回路について少し説明をしておくと、JJY受信モジュールはAitendoの古い40/60Khz受信モジュールで、もう販売しておらず、今は新しい受信モジュールになっているが、所定のところにつなげば(GPIOへは新しいモジュールのTNというネガティブ信号入力)、問題なく動くと思われる。
受信モジュールとESP8266のGPIOとの間にトランジスター(2SA1015)が入っているが、これは、受信モジュールが負論理(0がデータ受信)の逆転をするためと、受信モジュールと直接ESP8266とつないだときの高周波ノイズを避けるためである(以前オシロにプローブをあてると誤動作した)。
液晶の表示は、上段が年月日と時分、下段は、秒数とフレームの処理推移のプログレッシブバーもどき、さらに頭に正式なJJYからではなく推定の時には「X」マークが出る。
以下に、zipファイルでかためたスケッチソースファイルのフォルダーと、BSCH3Vの回路図ファイルを置きます。
| 固定リンク
「電子工作」カテゴリの記事
- 生存証明2(2022.10.19)
- 生存証明(2022.01.23)
- パソコン連動テーブルタップの修理を諦めて自作(2021.02.16)
- 半年ぶりのブログ更新に漕ぎつけた(2019.09.19)
- 研究所活動は停滞したままでCCDカメラ顕微鏡導入など(2019.02.08)
「esp8266」カテゴリの記事
- 半年ぶりのブログ更新に漕ぎつけた(2019.09.19)
- ESP8266のJJY電波時計のスケッチ公開(2018.10.02)
- ESP8266による電波時計リピーターの完成(2018.09.09)
- また脱線。今度は電波時計リピーターでさらに迷走(2018.08.03)
- ESP8266の赤外線リモコンウェブサーバー実装にはまる(2018.06.23)
「Arduino」カテゴリの記事
- 半年ぶりのブログ更新に漕ぎつけた(2019.09.19)
- ESP8266のJJY電波時計のスケッチ公開(2018.10.02)
- ESP8266による電波時計リピーターの完成(2018.09.09)
- また脱線。今度は電波時計リピーターでさらに迷走(2018.08.03)
- ESP8266の赤外線リモコンウェブサーバー実装にはまる(2018.06.23)
コメント