p.persica が 2026年03月08日22時03分42秒 に編集
初版
タイトルの変更
水晶発振器の温度補正で月差0.2秒を実現したニキシー管時計
タグの変更
ニキシー管
時計
PIC
メイン画像の変更
記事種類の変更
製作品
本文の変更
## はじめに ニキシー管時計を作ってみたいと思ったのは、2012年ごろでした。YouTubeやニコニコ動画の技術系工作動画で見かけたのがきっかけです。ただ当時は、マイコンも電子回路も知識がほとんどなく、製作には踏み出せませんでした。 その後、2022年に知人のArduinoに触れる機会があり、Lチカ、CO2センサーの電圧の読み取り、7セグメントLEDの表示などを試したことで、「自分でも作れそうだ」と感じるようになりました。そこから、部品の調達と回路設計、プログラミングの勉強を進め、今回の時計を形にしました。 使用したニキシー管は、ソ連製の **IN-8-2** 8本です。中型サイズのため、基板の面積もある程度広く取れて、回路・基板設計がしやすいと考え、このニキシー管を選びました。数字(0〜9)とドット表示が可能で、`hh.mm.ss`、`mm.ss.s`、`YYYYMMDD` などの表示に対応できます。eBayでポーランドの業者から購入し、送料込みで1本あたり約2,200円でした。   ## 高圧発生は昇圧モジュールを利用 ニキシー管の点灯には **約170 Vの高電圧** が必要です。昇圧回路の自作も考えましたが、今回は初めての基板製作でもあったため、失敗要因を減らすことを優先しました。 そこで、ストロベリー・リナックス社の昇圧モジュール([商品ページ](https://strawberry-linux.com/catalog/items?code=18365))を基板上に組み込みました。 ## 表示制御 表示は、輝度を確保するため **8本中2本ずつのダイナミック点灯** で制御しています。構成は次の通りです。 - **マイコン**:PIC18F27Q43(Microchip社 8bit MCU) - **アノード制御**:TLP188(フォトカプラ)×4(1個につきニキシー管2本) - **カソード(数字)制御**:HV5812(20chシフトレジスタ)×1(同時に2本分を駆動) - **カソード(ドット)制御**:TLP188 ×2 ダイナミック点灯のスキャン周波数は **160 Hz** に設定しました。体感上のちらつきが出にくい範囲(おおむね100 Hz以上)で、0.1秒表示の設計のしやすさも考慮して決定しました。 表示パターンは以下の2種類を実装しました。 - **ノーマル表示**:数値を即時更新 - **クロスフェード表示**:点灯時間を制御し、数字を滑らかに切り替え ## 周波数源と温度特性 基板には TCXO付きRTC(PCF2129AT)を載せていますが、これは電源OFF時の時刻保持用として使用しています。通常の時刻生成については、**自作の温度補正でどこまで精度を追い込めるか**を主題としました。 基板上には **水晶発振器(4,194,304 Hz)** と **温度センサー(TI TMP236)** を近接配置し、発振器付近の温度をアナログ電圧で取得しています。そして、**GPSのPPS信号(1秒パルス)** を基準に、16パルス区間ごとの発振周波数の偏差と温度を測定・記録しました。 約20〜36 ℃の範囲で、発振周波数は **4,194,304 ± 10 Hz(±2.4 ppm)** 程度の変動がありました。測定結果は一次式で近似できる傾向だったため、補正範囲は **±20 Hz** まで広げて設計しました。  ## 温度補正 当初は、2^22 Hz(= 4,194,304 Hz)を単純分周して1秒を作り、温度に応じた遅れ/進みをカウントして補正する方式を検討しました。ただ、補正時に繰り下がり・繰り上がりが発生した場合の処理の実装が複雑で、検討時点ではうまくプログラミングできそうになかったため、採用を見送りました。 次に、PIC18F27Q43内蔵の NCO(数値制御発振器)をFDCモード(50%固定デューティ比)で使う方式に変更しました。入力周波数を `n Hz` とすると、`n/2 Hz` 未満の周波数を出力でき、最小刻みは `(n/2) / 2^20 Hz` です。 今回の条件(`n = 4,194,304 Hz`)では、1段NCOの最小刻みは **2 Hz** です。1段だけだと分解能が不足したため、**NCOを2段構成**にしました。2段にすることで設定値の組み合わせの最適化が可能になり、最終出力の誤差をより小さくできます。 最終出力は `n/4 = 1,048,576 Hz` 未満となるため、扱いやすさを優先して **655,360 Hz(= 10 × 2^16)** を採用しました。これにより次の流れで1秒を生成できます。 - 655,360 Hz → **1/16** 分周で **40,960 Hz** - 40,960 Hz → 8bitタイマ(/256)で **160 Hz** 割り込み - 160 Hz をソフトウェア側でカウントして **1秒** 生成 さらに実装を簡潔にするため、NCO 2段とも「レジスタ上位側は固定」「下位8bitのみ可変」という制約で補正テーブルを作成しました。この条件でも、最終的に **655,360 ± 0.002 Hz** 程度まで追い込めています。 入力が `4,194,304 ± 20 Hz` の範囲で変動しても、1 Hz刻み補正時の残差は最大でも約 ±0.5 Hzです。これは `0.5 / 4,194,304 ≒ 0.12 ppm` に相当し、1段NCO構成に比べて約10倍細かい調整が可能になりました。 ### 温度補正テーブル(NCOレジスタ設定値) | 実温度(約) | 温度(ADC取得値) | 入力周波数偏差(Hz) | NCO1段目レジスタ値 | NCO2段目レジスタ値 | 出力周波数残差(mHz) | |---|---|---:|---|---|---:| | ~10.31℃ | ~746 | +20 | 0xD04**04** | 0xC4A**F5** | -0.1 | | 10.35℃~11.14℃ | 747~766 | +19 | 0xD04**B4** | 0xC4A**4F** | -1.1 | | 11.18℃~12.04℃ | 767~788 | +18 | 0xD04**45** | 0xC4A**B8** | +0.9 | | … | … | … | … | … | … | | 40.72℃~41.50℃ | 1482~1501 | -18 | 0xD04**C4** | 0xC4A**47** | -1.4 | | 41.54℃~42.33℃ | 1502~1521 | -19 | 0xD04**67** | 0xC4A**9F** | +0.5 | | 42.37℃~ | 1522~ | -20 | 0xD04**CF** | 0xC4A**3D** | -1.2 | ※実温度は `TA(℃) = (VOUT(mV) - 400) / 19.5`、`VOUT = ADC × 3.3V / 4096`(12bit ADC)で算出。 ### 周波数生成の流れ(まとめ) - 水晶発振器:**4,194,304 Hz** 付近(+20 Hz〜-20 Hz) - 第1段NCO:中間周波数(**1,706,000 Hz** 付近)へ変換 - 第2段NCO:**655,360 Hz** へ変換 - プリスケーラで **1/16** 分周し **40,960 Hz** - 8bitタイマで **160 Hz** 割り込み - ソフトウェアでカウントして **1秒** 生成 ## 実運用結果 この回路で実際に運用した結果は以下の通りです。1ヶ月経過時点での遅れは0.16秒でした。理論上の見積もり(1日あたり約0.01秒、月差最大0.3秒)と概ね整合していたため、そのまま運用を続けました。 2025年11月12日(約7ヶ月後)、**1.0秒の遅れ**となり、温度補正が実運用で機能していることを確認できました。   ## 反省点 使用したマイコン(**PIC18F27Q43**)に、性能面の不満はありませんが、スイッチ、センサー、RTCとの通信などに端子を割り当てていった結果、最終的にI/Oを使い切ってしまいました。その結果、温度特性測定時にはマイコン書き込み用の端子をGPSのPPS入力に転用するなど、計測作業の自由度が低くなりました。 今後は機能を詰め込みすぎず、デバッグ・テスト用に2〜3本の端子を最初から確保する設計にしたいと思います。 ## おわりに 初めてのプリント基板製作としては難易度の高い題材でしたが、**オレンジ色の光のニキシー管時計**と**時刻精度の追い込み**を両立でき、満足度の高い作品になりました。 次回は、小型化やGPS連動を前提に、さらに扱いやすい設計へ発展させたいと考えています。