周波数カウンタ＋エクセル VBA で 10 MHz マスタークロックの性能測定

[前回の記事](https://qiita.com/kan573/items/91371df1eaa778d8bb9f)では Teraterm から測定器を操作しました。
今回の記事では、同じ測定器をエクセル VBA で操作します。
ツイッターに投稿した内容を再構成して、Qiita 記事にしました。

# 1. はじめに
ヤフオクで GPSDO を購入しました。
GPS 衛星に搭載された原子時計に同期して、高精度・高確度(__※1__)な
10MHz マスタークロックを出力できる装置です。

原子時計と同等の精度が得られるのに、安価に販売されているのは、廃棄された設備から
取り外した中古の OCXO(__※2__) を再利用しているためです。
(10MHz OCXO が Aliexpress で沢山見つかります)

早速動かして、GPS ロックした状態で、オシロで波形を確認してみると、
どうも時間軸方向のブレが大きい気がします。

不良品かと思い、別な OCXO を搭載している物も入手しましたが、やはり同傾向です。
手持ちの 10MHz 水晶発振器との比較でも明らかにブレているので、ジッターが多いようです。

実際どのような性能になっているのか、測定して客観的な数字で出してみることにしました。

※1 高精度 = 周波数安定性が高く、ジッターが少ない
　　高確度 = 正確な周波数。10.00000000… と、ゼロの続く桁数の多い、正確な 10 MHz。

※2 Oven Controlled Crystal Oscillator = 恒温槽制御つき水晶発振器

![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/f7b809fc-775e-6668-6eac-5c70e4815c77.jpeg)


__出力クロック波形のぶれ幅を、トリガ位置から 1ms 後で比較した図__(∞パーシスト表示)
![s1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/9ca81764-71b0-5b10-e3ed-7ea8fae9079f.png)


# 2. 使用する測定器および環境
__DUT(測定対象)、オシロスコープ、周波数カウンタ、制御用PC(写っていない)__
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/27162867-a2e2-6f03-1cb4-7ade51de9075.jpeg)


## 2.1 測定器

周波数カウンタ [Keysight 53230A](https://www.keysight.com/zz/en/product/53230A/350-mhz-universal-frequency-counter-timer-12-digits-s-20-ps.html) (192.168.1.7 で LAN 接続)

オシロスコープ [Agilent(Keysight) MSO6104A](https://www.keysight.com/zz/en/product/MSO6104A/mixed-signal-oscilloscope-1-ghz-4-analog-16-digital-channels.html) (192.168.1.6 で LAN 接続)

## 2.2 測定器制御ライブラリ
Keysight IO Libraries Suite [IOLibSuite_18_2_27313.exe](https://www.keysight.com/zz/en/lib/software-detail/computer-software/io-libraries-suite-downloads-2175637.html)
Excel VBA から呼び出す VISA COM のライブラリです。

## 2.3 参考資料
2種類の測定器の SCPI 制御コマンドリファレンス

[Keysight 53220A/53230A Frequency Universal Counter/Timer Programmer's Reference](https://www.keysight.com/gb/en/library/manuals/programming-and-syntax-guide/53220a53230a-frequency-universalcountertimer-programmers-reference-1971001.html)

[Agilent InfiniiVision 6000 Series Oscilloscopes Programmer's Guide](https://www.keysight.com/zz/en/assets/9018-08107/programming-guides/9018-08107.pdf)

## 2.4 環境

1. Windows10 Pro 64bit (21H2)
2. Microsoft Excel 2013
3. Keysight IO Libraries Suite 2022 (Build 18.2.27313.1) IOLibSuite_18_2_27313.exe 


# 3. ジッターの規格について
ジッターを云々する前に、ジッターの基準について調べてみます。

各社の発振器や PLL IC のデータシートで、ジッター仕様のリファレンスとして
__JESD 65B__ が参照されています。
この規格書は、ユーザー登録すれば無料でダウンロードできます。
https://www.jedec.org/standards-documents/docs/jesd-65b

JESD 65B の中で、5 種類のジッターが定義されています。

![s5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/2cb8940d-7f95-2295-7c78-79fe94e03a76.png)

## 3.1 ジッターの定義 (JESD 65B)

1. cycle-to-cycle period jitter - tjit(cc), Page 10
サイクル・トゥ・サイクル・ジッタ：　連続する2つのサイクルの周期の差。

2. period jitter - tjit(per), Page 11
周期ジッタ：　ランダムに抽出したサイクルの周期と、理想サイクル周期との差。

3. half-period jitter - tjit(hper), Page 11
半周期ジッタ：　ランダムに抽出した上または下の半サイクルの周期と、理想の半サイクル周期との差。

4. duty cycle jitter - tjit(duty), Page 11
デューティサイクルジッター：　ランダムに抽出した 1 サイクルの中で、立ち上がりから立ち下がりまで(1st)の期間と、立ち下がりから立ち上がりまで(2nd)の期間の差。
(デューティ比のブレの大きさ)

5. phase jitter - tjit(φ), Page 12
位相ジッタ：　リファレンスクロックから生成されるクロックについて、リファレンスのエッジを基準とする(静的な)サイクル位相の平均値と、ランダムに抽出したサイクルの位相の差。

いずれも、数値が小さい方が、性能がよいです。
![s2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/5c088ed5-28bb-32ec-da6d-bef8dbfab4cf.png)

各ジッタは相関性があるため、全部を調べなくても、
一項目を見ればだいたいの性能は把握できます。

発振器の仕様表記では、2. 周期ジッターの数値がよく使用されます。


## 3.2 ジッターの測定方法

Table 2 (Page 2) に、実際の測定条件が例示されています。

1. サイクル・トゥ・サイクル・ジッター tjit(cc) - 1,000 cycles サンプルした場合の typ, max値で、単位は ps
2. 周期ジッター tjit(per) - 10,000 cycle サンプルした場合の typ, max値で、単位は ps
5. 位相ジッター tjit(φ) - 2,000 cycle サンプルした場合の typ, max値で、単位は ps

![s3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/9101f3db-6cf3-4266-a223-14e94e0b7ca8.png)


負荷の条件が、資料末尾 Page 13 に記載されています。

4.3 テスト負荷は、テスト対象の特定のロジックファミリの業界標準のテスト負荷であるか、
コンポーネントデータシートで製造元によって指定されているものでなければなりません。

4.4 また、試験の標準化のために、15pF と 500Ω の試験負荷を追加することを推奨します。

通常の回路では、立ち上がりまたは立ち下がりの、どちらかのエッジを基準にして
回路が動きます。
今回は、立ち上がりエッジで 2. 周期ジッター を測定して性能を評価してみます。


# 4. 発振器の ppm 数値とジッターの関係

発振器の製品仕様で、ppm 値で示されるのは周波数の確度(正しさ)であって、
ジッターの大きさではないです。
TCXO の ±1ppm 品は、必ず汎用 SPXO の±50ppm 品よりジッターが少ない、
とは言えません。

例えば、10MHz±50ppm(-40～+85℃)の発振器 KC3225K10.0000C1GE00 を
100 個購入したとき、-40～+85℃ の温度範囲で、正しい電源条件で使用すると、
100 個全部の出力周波数が 10.000000 MHz ± 500 Hz の範囲に収まります。

個々の発振器の出力周波数は微妙に異なり、ある一つの出力は 9.999572 MHz、
別のもう一つは 10.000321 MHz といったようにバラつき、
完全に同じ周波数の物を見つけることはできません。

周波数の分布をヒストグラムにすると、10.00000 MHz を中心とした
ベルカーブになる筈です。

発振器の出力周波数は、周囲温度や電源電圧、負荷条件や経年変化によって、
刻刻と変化します。
同一の発振器でも、昨日と今日で同じ周波数を出力してくれるとは限りません。

確度を上げる(ppm 値を小さくする)ために、温度条件や回路条件を整えると、
ジッターも減少する方向になります。
そのため、ppm 値の小さい発振器が、ジッターも少ない可能性はあります。
しかし、実力は現物を計ってみないとわかりません。
発振器の内部回路が低ノイズで、高速動作な物ほど、ジッターは小さくなる
可能性が高いです。


# 5. 53230A でのジッター測定
周波数カウンタ Keysight 53230A では、
シングル周期(クロックのあるエッジから、次のエッジまで)
= Single Period 測定により、周期ジッター(period jitter) を調べることができます。

入力クロック信号の任意の1波の周期を測定し、測定値を内部メモリに保存します。
測定値の保存数は、測定時に指定することができます。
保存した全データから、全体の平均周期と、実効ジッター値(rms jitter)、
最大ジッター値(p-p jitter) を統計算出します。

rms jitter は、1σ = 約 68% のサンプルが収まる周期の値を示します。
p-p jitter は、全サンプル中で、平均周期から一番大きくずれている周期の値を示します。

全くずれが無い理想クロックでは、rms jitter も p-p jitter も 0 ps になります。

前述の __JESD 65B__ では、period jitter 測定時の標本数 = 10,000 cycles
とされていましたが、実際やってみると 10,000 cycles では値が安定しないため、
100,000 cycles で測定します。

シングル周期 100,000 サンプルから、rms jitter と p-p jitter を算出します。

測定器を手で操作して、読み取った数値を 手書き or エクセルに入力、
というのは面倒なので、Excel からマクロで制御して、自動でシートに記録します。


# 6. マクロの作成
エクセルのシートにデータ記入枠を用意しておきます。
53230A からデータを取り込んで、セルに記入するマクロを作成しました。
各項目を10回測定して、最大・最小・平均値を自動算出します。

測定項目は、下記の通りです。
・実測の周波数(確度)と変動幅(安定性)
・ジッター(rms、p-p)
・波形データ(振幅3種、ライズ/フォールタイム、デューティ)

波形も残しておきたいので、オシロスコープ MSO6104A をマクロで設定して、
別途コピーしたスクリーンショットを貼り付けます。

得られた測定値と波形から、クロックの信号品質を判断することができます。
マクロを使うと常に同条件でデータが取得できるので、比較が容易です。

作成した .xlsm ファイルを、下記で公開しています。
[53230A_10MHz_性能測定.xlsm](https://drive.google.com/file/d/1fnONGkZPdKRssbWrfNBbszAhCssk0z96/view?usp=sharing)

![s4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/17890f42-c656-815b-0346-13c869ba165d.png)

__マクロを起動するボタン__ が3つあります。

1. 測定開始
53230A で測定を実施します。発振器は CH1 に接続します。

2. MSO設定
MSO6104A を波形保存用に設定します。発振器は CH1 に接続します。

3. スクショ貼付
事前に MSO6104A の WebUI で、Get Image を開き、Instrument screen image をクリップボードにコピーしておきます。
Excel シート上のスクショを選択しておいてから、「スクショ貼付」ボタンを押します。
古いスクショを削除して、クリップボード上の新しいスクショを貼り付けし、丁度よい大きさにリサイズします。
![s6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/fdb67b20-d244-7233-ee72-dc8d209ca2a4.png)


作成したマクロは下記になります。
```53230A_10MHz_性能測定.xlsm (VB マクロ)

Public write_colomn As Integer

Sub Main()
    write_colomn = 5

    Range("B5:K14").Select
    Selection.ClearContents
    Range("B5").Select
    
    Call setup_counter_jitter                                               'カウンタの設定(ジッター測定用)
    Call read_jitter                                                        'ジッター測定
    
    Call setup_counter_freq                                                 'カウンタの設定(周波数測定用)
    Call read_freq                                                          '周波数測定
        
    Call setup_counter_signal                                               'カウンタの設定(波形測定用)
    Call read_signal                                                        '波形測定
        
        
End Sub

Sub setup_counter_jitter()
    Dim RM As New VisaComLib.ResourceManager
    Dim UFC As New VisaComLib.FormattedIO488                                'UFC : Universal Frequency Counter
    Set UFC.IO = RM.Open("TCPIP0::192.168.1.7::inst0::INSTR")               'VISA Address
    
    UFC.WriteString "*RST"                                                  'カウンタのリセット
    UFC.WriteString "DISP:DIG:MASK 12"                                      '表示桁数 = 12桁
    UFC.WriteString "CONF:SPER (@1)"                                        '測定モード = シングルピリオド
    UFC.WriteString "SENS:FREQ:MODE CONT"                                   '切れ目なし連続測定モード
    UFC.WriteString "SAMP:COUN " & Range("B23").Text                        '測定サンプル数を B23 セルから取得
    UFC.WriteString "INP:COUP DC"                                           '入力カップリング = DC
    UFC.WriteString "INP:IMP 50"                                            '入力インピーダンス = 50Ω
    UFC.WriteString "INP:LEV:AUTO OFF"                                      '入力レベル自動設定 = OFF
    UFC.WriteString "INP:LEV1 0"                                            'CH1 入力レベル = 0V
    UFC.WriteString "CALC:STAT ON"                                          '統計モード = オン
    UFC.WriteString "CALC:AVER:STAT ON"                                     '平均値計算 = オン
    UFC.WriteString "DISPLAY:MODE NUM"                                      '表示モード = 数値
    UFC.WriteString "INIT"                                                  '設定開始
    UFC.WriteString "*WAI"                                                  '設定完了待ち
    
    UFC.IO.Close
    Set UFC = Nothing
    Set RM = Nothing
End Sub



Sub read_jitter()
    Dim RM As New VisaComLib.ResourceManager
    Dim UFC As New VisaComLib.FormattedIO488                                'UFC : Universal Frequency Counter
    Set UFC.IO = RM.Open("TCPIP0::192.168.1.7::inst0::INSTR")               'VISA Address
    UFC.IO.Timeout = 30000                                                  'TIMEOUT = 30秒
    
    Dim i
    
    For i = 0 To 9
    
    UFC.WriteString "INIT"                                                  'ジッター統計初期化
    UFC.WriteString "*WAI"                                                  '設定完了待ち
    UFC.WriteString "CALC:AVER:AVER?"                                       '平均値読み出し
    Cells(write_colomn + i, "B") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてB_セルへ書込む
    UFC.WriteString "CALC:AVER:SDEV?"                                       '標準偏差(rmsジッター)読み出し
    Cells(write_colomn + i, "C") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてC_セルへ書込む
    UFC.WriteString "CALC:AVER:PTP?"                                        'p-pジッター読み出し
    Cells(write_colomn + i, "D") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてD_セルへ書込む
    
    Next i
            
    UFC.IO.Close
    Set UFC = Nothing
    Set RM = Nothing
End Sub

Sub setup_counter_freq()
    Dim RM As New VisaComLib.ResourceManager
    Dim UFC As New VisaComLib.FormattedIO488                                'UFC : Universal Frequency Counter
    Set UFC.IO = RM.Open("TCPIP0::192.168.1.7::inst0::INSTR")               'VISA Address
    
    UFC.WriteString "*RST"                                                  'カウンタのリセット
    UFC.WriteString "DISP:DIG:MASK 12"                                      '表示桁数 = 12桁
    UFC.WriteString "CONF:FREQ (@1)"                                        '測定モード = 周波数
    UFC.WriteString "SENS:FREQ:MODE CONT"                                   '切れ目なし連続測定モード
    UFC.WriteString "INP:COUP DC"                                           '入力カップリング = DC
    UFC.WriteString "INP:IMP 50"                                            '入力インピーダンス = 50Ω
    UFC.WriteString "INP:LEV:AUTO OFF"                                      '入力レベル自動設定 = OFF
    UFC.WriteString "INP:LEV1 0"                                            'CH1 入力レベル = 0V
    UFC.WriteString "CALC:STAT ON"                                          '統計モード = オン
    UFC.WriteString "CALC:AVER:STAT ON"                                     '平均値計算 = オン
    UFC.WriteString "DISPLAY:MODE NUM"                                      '表示モード = 数値
    UFC.WriteString "INIT"                                                  '設定開始
    UFC.WriteString "*WAI"                                                  '設定完了待ち
    
    
    UFC.IO.Close
    Set UFC = Nothing
    Set RM = Nothing

End Sub

Sub read_freq()
    Dim RM As New VisaComLib.ResourceManager
    Dim UFC As New VisaComLib.FormattedIO488                                 'UFC : Universal Frequency Counter
    Set UFC.IO = RM.Open("TCPIP0::192.168.1.7::inst0::INSTR")                'VISA Address
    UFC.IO.Timeout = 30000                                                   'TIMEOUT = 30秒
    
    Dim i
    
    For i = 0 To 9
    
    UFC.WriteString "INIT"                                                  '周波数測定値初期化
    UFC.WriteString "*WAI"                                                  '設定完了待ち
    UFC.WriteString "MEAS:FREQ?"                                            '周波数読み出し
    Cells(write_colomn + i, "E") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてB_セルへ書込む
    
    Next i
            
    UFC.IO.Close
    Set UFC = Nothing
    Set RM = Nothing


End Sub

Sub setup_counter_signal()
    Dim RM As New VisaComLib.ResourceManager
    Dim UFC As New VisaComLib.FormattedIO488                                'UFC : Universal Frequency Counter
    Set UFC.IO = RM.Open("TCPIP0::192.168.1.7::inst0::INSTR")               'VISA Address
    
    UFC.WriteString "*RST"                                                  'カウンタのリセット
    UFC.WriteString "DISP:DIG:MASK 12"                                      '表示桁数 = 12桁
    UFC.WriteString "CONF:RTIM"                                             '測定モード = ライズタイム
    UFC.WriteString "SAMP:COUN 1"                                           '測定サンプル数 = 1
    UFC.WriteString "INP:COUP DC"                                           '入力カップリング = DC
    UFC.WriteString "INP:IMP 50"                                            '入力インピーダンス = 50Ω
    UFC.WriteString "INP:SLOP1 POS"                                         '有効エッジ = 立ち上がり
    UFC.WriteString "INIT"                                                  '設定開始
    UFC.WriteString "*WAI"                                                  '設定完了待ち
    
    UFC.IO.Close
    Set UFC = Nothing
    Set RM = Nothing

End Sub


Sub read_signal()
    Dim RM As New VisaComLib.ResourceManager
    Dim UFC As New VisaComLib.FormattedIO488                                'UFC : Universal Frequency Counter
    Set UFC.IO = RM.Open("TCPIP0::192.168.1.7::inst0::INSTR")               'VISA Address
    UFC.IO.Timeout = 30000                                                  'TIMEOUT = 30秒
    
    Dim i
    
    For i = 0 To 9
    
    UFC.WriteString "INP:LEV:MAX?"                                          '信号レベル 最大値 読み出し
    Cells(write_colomn + i, "F") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてB_セルへ書込む
    UFC.WriteString "INP:LEV:MIN?"                                          '信号レベル 最小値 読み出し
    Cells(write_colomn + i, "G") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてB_セルへ書込む
    UFC.WriteString "INP:LEV:PTP?"                                          '信号レベル p-p 値 読み出し
    Cells(write_colomn + i, "H") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてB_セルへ書込む
    UFC.WriteString "MEAS:RTIM?"                                            'ライズタイム 読み出し
    Cells(write_colomn + i, "I") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてB_セルへ書込む
    UFC.WriteString "MEAS:FTIM?"                                            'フォールタイム 読み出し
    Cells(write_colomn + i, "J") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてB_セルへ書込む
    UFC.WriteString "MEAS:PDUT?"                                            'デューティ比 読み出し
    Cells(write_colomn + i, "K") = Replace(UFC.ReadString(), vbLf, "")      '改行コードを取り除いてB_セルへ書込む
   
    Next i
            
    UFC.IO.Close
    Set UFC = Nothing
    Set RM = Nothing
    
End Sub

Sub setup_MSO6104A()                                                        'オシロスコープ MSO6104A の設定
    Dim RM As New VisaComLib.ResourceManager
    Dim MSO As New VisaComLib.FormattedIO488                                'MSO : MSO6104A
    Set MSO.IO = RM.Open("TCPIP0::192.168.1.6::inst0::INSTR")               'VISA Address
    MSO.IO.Timeout = 3000                                                   'TIMEOUT = 3秒
        
    MSO.WriteString "*RST"                                                  'オシロスコープのリセット
    MSO.WriteString "CHANNEL1:RANGE 2.4E+00"                                'CH1 入力レンジ = 300mV/div
    MSO.WriteString "CHANNEL1:OFFset -300.00E-03"                           'CH1 垂直位置 = -300mV
    MSO.WriteString "TIM:RANG +200.0E-09"                                   '時間表示スパン = 200ns (20ns/div)
    MSO.WriteString "CHAN1:INP FIFT"                                        'CH1 入力インピーダンス = 50Ω
    MSO.WriteString "TIM:POS +60.00E-09"                                    '表示トリガ位置 = +60ns
    MSO.WriteString "MARK:MODE MEAS"                                        'マーカー = QuickMeas
    MSO.WriteString "MEAS:STAT ON"                                          '統計表示 = オン
    MSO.WriteString "MEAS:CLE"                                              '統計表示項目全クリア
    MSO.WriteString "MEAS:FREQ"                                             '統計表示1 = 周波数
    MSO.WriteString "MEAS:RIS"                                              '統計表示2 = ライズタイム
    MSO.WriteString "MEAS:FALL"                                             '統計表示3 = フォールタイム
    MSO.WriteString "MEAS:VAMP"                                             '統計表示4 = 振幅
            
    MSO.IO.Close
    Set MSO = Nothing
    Set RM = Nothing

End Sub

Sub Paste_MSO_Screenshot()
    Dim aFmts
    Dim fmt
    Dim exist_scsho
    
    aFmts = Application.ClipboardFormats
    exist_scsho = 0

    For Each fmt In aFmts
        If fmt = xlClipboardFormatBitmap Then exist_scsho = 1               'クリップボードに画像が含まれていれば 1
    Next
    
    If exist_scsho = 0 Then                                                 'クリップボードに画像が含まれていないときは終了
        MsgBox "クリップボードに画像をコピーしてからボタンを押してください", vbExclamation
        Exit Sub
    End If

    If VarType(Selection) = vbObject Then Selection.Delete                  'オブジェクト(古いスクショ)が選択されていれば削除

    Range("H23").Select
    ActiveSheet.Paste                                                       'クリップボードのスクショを貼り付け
    
    ActiveSheet.Shapes(ActiveSheet.Shapes.Count).Select                     '最後に貼り付けたスクショ画像を選択
    Selection.ShapeRange.ScaleHeight 0.55, msoFalse, msoScaleFromTopLeft    'スクショ画像を55%サイズに縮小
    
    With Selection.ShapeRange.Line                                          'スクショの黒枠線を表示
        .Visible = msoTrue
        .ForeColor.ObjectThemeColor = msoThemeColorText1
        .ForeColor.TintAndShade = 0
        .ForeColor.Brightness = 0
        .Transparency = 0
    End With

End Sub

```


# 7. 測定
手元にある 10MHz クロック源を一通り測定してみました。

ヤフオク GPSDO は、1台目は購入したそのままの正弦波出力です。

2台目は波形整形回路で矩形波に変換して測定しています。
正弦波だと波形の傾きが緩いため、ジッター値が悪化する可能性を考えました。
矩形波に変換すると、少し影響はあるものの、大きくは改善しませんでした。

水晶発振器は、自作の基板に搭載しています。
タカチ SW-15B を保温カバーとして、発振器周囲の空気が動かないようにしています。

波形整形回路 兼 50Ω 出力ドライバがついており、
CMOS(矩形波)出力/クリップドサイン出力どちらの発振器も、
矩形波で出力して測定します。

回路は水晶発振用ドライバ 74LVC1GX04 を使用しています。
TI と Nexperia で波形や Rise/Fall Time がかなり違っていて、悩みどころです。

自作基板はバージョンが複数あるのと、出力振幅にバリエーションを作ったので、
波形はあくまで参考です。
(回路を煮詰めきれてない)

LTC6957 が正弦波 → 矩形波変換に最適らしいのですが、確認できていません。

各画像はツイッターに投稿したもので、Excel シートが旧バージョンです。
(スクショ貼付機能を追加する前のバージョン)


## 7.1 GPSDO1 10MHz
中古のシングルオーブン VC-OCXO が入っています。
GPS 同期させれば確度は良い値ですが、ジッタが非常に大きいです。
VC-OCXO が中古でくたびれているせいなのか、元からなのかはわかりません。
ジッターの数値は、SPXO に余裕で負けています。
疑って正解。
![7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/2fa5fe7e-08e6-89aa-c8b2-7380f35226e7.jpeg)
![8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/5cb86e1b-c30e-d115-6136-a0161390c325.jpeg)
![A1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/07ef15f2-3ae1-f1d7-6c69-41e80ce55b55.png)

## 7.2 GPSDO2 10MHz
ダブルオーブンの VC-OCXO が入っています。
シングルオーブンよりいくらかはマシですが、やっぱり良くないです。
回路追加して正弦波 → 矩形波に改造していますが、ジッタは改善しませんでした。
恒温槽の恩恵で、安定性は良いです。
![9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/cda42d78-f34a-6566-ef3f-710efa04c3fe.jpeg)
![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/c740df4c-a5aa-d580-81d5-7447826c6cc9.jpeg)
![A2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/7024f4d5-a3dd-7337-bf84-180e26b5c0ef.png)

## 7.3 VC-OCXO 10MHz
もう一台ある周波数カウンタ 53220A に Abracon AOCJY3A-10M(±5ppb, 0～+50℃) を入れて、
GPSDO 校正後にフリーランしています。
周波数安定性は、今回計った中では一番良いです。
正弦波出力なので、ジッター値が大きめに出るように思います。
(カウンタの入力回路で、スレッショルド電圧付近を通過する時間が長くなるため)

AOCJY3A-10M は矩形波出力の発振器なのですが、53220A 内部でフィルタして正弦波で出力しています。
![11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/ad439d92-047c-ec41-abb2-fdf53afdc88e.jpeg)
![B1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/307bc7c2-37da-caa7-bac4-fd4e135115eb.png)
![12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/10d37b58-7c3a-a0e8-a66c-986b007bd0d5.jpeg)
![A3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/bd2b0df7-8f09-af11-b762-015fd4be1ea1.png)

## 7.4 VC-TCXO 10MHz
村田 XTCLH10M000CHJA1P0(±0.28ppm, -40～+85℃) です。
(旭化成問題でディスコン?)
温度安定用にカバーと収縮チューブで覆っています。
ジッターの数値は OCXO よりも良いです。
周波数はボリューム調整式でもっと合わせ込めますが、周囲温度が変われば、またズレてしまいます。
恒温層が無いので、安定性は OCXO に劣ります。
![B2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/7d289a09-635b-3b3f-4d9e-6acbd8f03397.png)
![13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/5cdf938c-6a7e-b10d-93dc-6c4d1233720e.jpeg)
![A4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/78cfa65c-9252-c07b-37f7-a323f18b3ef4.png)

## 7.5 OCXO 10MHz
Abracon AOCJYR-10.000MHz-M5625LF(±25ppb, -40～+85℃) 廉価な OCXO です。
確度は ±0.5ppm で調整できませんが、フリーランで 10MHz +0.43Hz (+0.043ppm) が得られており、通常の量産用には便利そうです。
小型・低消費電力で、OCXO としてはウォームアップが早いです。
ジッターの数値も、TCXO/SPXO と同等に良いです。
![B3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/7f04a1ab-8c0f-dfb3-897d-33afce06d324.png)
![14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/69466d98-ff9a-9d58-7e77-0a1d0738652e.jpeg)
![A5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/c87e2dfe-71b9-f840-0d4d-43f805c23a4d.png)

## 7.6 TCXO 10MHz
秋月で売っているセイコーエプソン TG-5021CE-10N(±2ppm, -30～+85℃) です。
クリップドサイン出力ですが、基板上で矩形波に変換しています。
用意した中では p-p ジッタが最小で、安定性も OCXO に負けていません。
確度は OCXO に劣り、調整できません。
息をかけるだけで周波数が動くので、カバーが必須。
ジッタと安定性から見て、コスパは非常に良いです。
電源電圧が 2.8V なのが玉に瑕。
一応 3.3V でも動かせます。(周波数が少しずれる)
![B4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/07275e91-3b0e-b158-dd6d-0e1bc4049693.png)
![15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/c18faa34-7063-95c7-1307-c0d9ae981e01.jpeg)
![A6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/99146824-50fa-9a38-6da7-851940a11d06.png)

## 7.7 SPXO 10MHz
京セラ KC3225K10.0000C1GE00(±50ppm, -40～+85℃) です。
用意した中では rms ジッタが最小ですが、温度補償が無いので確度と安定性がいまいちです。
とはいえ、民生／工業向けに普通に使われているグレードです。
確度・安定性には期待できないので、カバーをつけていません。
![B5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/63eff3e4-1764-d3b7-42ba-a49f1ea1e0cc.png)
![16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/7488a9ac-0996-0ab1-cf9b-a4ed565bc923.jpeg)
![A7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/16f0842a-9c36-c4ef-5fdd-e372a8999f5b.png)

# 8. まとめ
エクセル VBA で測定器を制御して、自動測定を行い、
10 MHz マスタークロックの精度を調査しました。
どうやら、中古の OCXO は、GPS 同期で確度は得られるものの、
ジッター性能には期待しない方がよさそうです。

同じ基板を利用して、新品の OCXO を搭載すれば、ジッター値は向上しそうに思われます。


構造上、OCXO の内部恒温槽は、部品の使用上限温度よりも高い温度で維持されます。
工業用温度範囲 -40～+85℃ の OCXO だと、内部回路は +90℃ 以上の温度で動作しています。
この状態で 10～20 年使われ、廃棄された機器から回収して再利用しているので、
熱で劣化している可能性があります。

また、もともとその程度の性能だった可能性もあります。
この 20 年ほどの間で、半導体と水晶デバイスの性能は、かなり向上しています。
今見ると低精度でも、発売当時の水準では高精度だったのかもしれません。

超高価な機器で使われていた発振器なので、超高性能なイメージがありますが、
20年前の CPU には骨董的価値しかないのと同様に、20年前の発振器も
性能的な価値は無いのかもしれません。


調査により、精度は、最近の水晶発振器であれば、OCXO/TCXO/SPXO で
ほぼ差が無い事がわかりました。
確度は、もちろん OCXO > TCXO > SPXO の順です。

音楽再生用 DAC のマスタークロックで考えると、周波数が 1ppm ずれても、
10 分の曲が 0.6ミリ秒伸び縮みするだけですので、
確度を追求するのはあまり意味が無いような気がします。

それよりは、ジッター値の大小の方が、歪率等への影響が大きそうです。