そういえば作ってあった。いろいろ説明が不足しているが C のコードを吐く機能がある。そのうちなんとかしたい。
BDF Font のグリフを一覧で見るやつ
SパラメータとZパラメータのメモ
Sパラメータは「ある基準インピーダンスのとき」のパラメータなので、50Ωとか75Ωとか、基準が決まっていないといけない。Sパラを表記するときには基準インピーダンスの表記も必須。
Zパラメータの場合はSパラメータ+基準インピーダンスの情報を含んでいる。ZパラメータはSパラメータの基準インピーダンスの逆数(基準アドミッタンス)が0の場合と考えることもできる。「じゃあ最初からZパラメータで示したほうがよくない?」という気がするが、基準に0を使っているので「Zパラメータでは表現できない」というケースがあり、万能ではない。0除算が発生しないSパラメータはどんな回路でも必ず存在するが、Zパラメータはそうとは限らない。
出力インピーダンスはどれ?
Sパラだけではわからない。さらに前の信号源インピーダンスが影響する
Zパラメータの意味
2ポートの場合のZパラメータの意味は以下の通り
- : 端子2を開放したときの、端子1から見たインピーダンス
- : 端子1を開放したときの、端子2から見たインピーダンス
- : 端子1を開放したときの、開放端電圧と端子2の流入電流との比
- : 端子2を開放したときの、開放端電圧と端子1の流入電流との比
ref.
https://www2-kawakami.ct.osakafu-u.ac.jp/osakafu-content/uploads/sites/407/Lecture_Data/Electric_Circuit_II/01_Lecture/02_lecture_electric_circuit_II.pdf
https://home.hiroshima-u.ac.jp/amakawa/files/amakawa_S-parameter_20180528_1.pdf
GPSDO 10MHz 回路と温度安定度
回路と制御方法はだいたい決めたのでそのへんを書いておく
VFC をどうコントロールするか
OCXO がいくら安定しているといっても、それはVFC(Voltage Frequency Control)次第で、短期的にはこれが十分に安定していなければいけない。
手元の OCXO (MORION MV102) は Uref と呼ばれる端子から 5V の基準電圧 (OCXO 内で安定化された電圧源) が出ており、これを使って VFC へ入力する電圧を生成するようになっている。VFC は 0〜5Vの範囲で ±5Hz ぐらいの調整ができ、約2.5V付近で10MHzになる。
PWM + ローパスフィルタ
最初は MCU 内蔵の 16bit PWM をローパスフィルタにかける方法を試していた。やることは簡単で、PWM の出力でFETを駆動してレベルシフトしつつ一定の範囲に調整して、その結果をサレンキー型のアクティブローパスフィルタ(1倍)に通すというもの。
これでいいはずなんだけど、部品点数が増え、誤差の扱いがよくわからなくなるのでかえって難しく、やめてしまった。ちゃんとシミュレーションすれば、これで十分な結果は出せるはずだとは思う。特にレベルシフトに使う FET のオン抵抗温度特性がよくわからなかった。
現在の回路
(この回路図に出力フィルタは含んでいない)
12bit DAC
DAC だとスペックが決まっているので、誤差に対する考えかたはいくぶん簡単になる。ただ、抵抗ラダー型のDACは性質上リニアリティに劣るのと、12bit ぐらいまでしか気軽に手に入らないので出力可変範囲が狭くなる。
2.5V±0.25V (0.5V範囲) ぐらいを可変するように抵抗分圧回路を設計して、この範囲を12bitで調整する。つまり 0.12mV/count。手元のOCXOは2Hz/Vなので、結果として0.24mHz 単位で調整できるようになる。
今回使うのは、MCP4725。温度特性は Offset Error Drift が ±1ppm/℃、Gain Error Drift が -3ppm/℃。出力は 0〜5Vの範囲で、これを0.5Vの範囲に圧縮しているので、Offset Error Drift は ±0.00000024mHz/℃ Gain Error Drift は -0.00000072mHz/℃ となり、ほぼ無視できる。
1PPS の精度と確度
GNSSモジュールの 1PPS の UTC に対する精度はスペック上、99% で ±60ns (60e-9) と書いてあった。これは1秒あたりのジッタなので、10秒なら 6e-9 100秒で6e-10(0.6ppb)になる。
10MHz をカウントする場合は100秒で±6mHz、1000秒で±0.6mHzの確度があることになる。
以下で書くように周波数カウントの確度のほうが低いので、こちらは無視できる (はず)。
周波数カウントの確度
ゲート時間1秒だと、周波数測定確度が1Hz単位しかない。ゲート時間を徐々に長くしていき、ゲート時間1000秒で1mHzの確度(1e-10 = 0.1ppb)が得られる。
±1カウント誤差(量子化誤差)があるため、±1のカウント誤差は無視し、±2以上の誤差が発生したら補正をかけるようにする。この積分時間には特に上限を設けず時間に応じて補正値を計算する。
OCXOの温度安定性
スペック上、使っているOCXOの温度安定性は最大±2e-10 (-55〜80℃) (0.2ppb)。温度変化で最大2mHzは変化する可能性がある。この温度範囲でこの変化量なのでかなり変動は少ない。
↑のスペックは一番良いモデルの場合のようで、一番下のモデルだと(手元のがどのモデルか不明なので)、±5e-9 (0〜55℃) のようだ。つまりこの範囲で50mHzほど変動する可能性があり、雑に計算しても1℃で約1mHzほど変化するかもしれない。
抵抗分圧の温度安定性
抵抗の温度特性で気軽に手に入る±100ppm/℃の場合をLTSpice でシミュレーションしてみると、VFC は最悪 ±0.25mV/℃ 変動することがわかる。これは±0.5mHz/℃ に相当する。5℃変化すれば±2.5mHz動くことになる。最悪というのは全部の抵抗の温度特性が正負も含めてバラバラというケースなので実際はもっとマシだとは思うが、ちょっと大きすぎる。
±10ppm/℃であれば出力温度係数は1桁減って、約±0.025mV/℃、±0.050mHz/℃ になる。PPS によって制御されているとはいえ、1000秒(16分)ぐらいの頻度でしか調整できないので、ここはできるだけ温度安定性を上げておきたい。
温度安定性のまとめ
- OCXO ±50mHz (0〜55℃)
- DAC Offset Error Drift は ±0.00000024mHz/℃ Gain Error Drift は -0.00000072mHz/℃
- 抵抗分圧 (TCR=±10ppm) ±0.050mHz/℃
1PPS は 1000秒(約16分)で±0.6mHzの確度。あとは室温の安定性で調整する頻度などが変わる。
経過
温度は MCU 内蔵の精度の低いものを利用しているので、相対的な傾向ぐらいしかわからない。また、MCU と OCXO 自体は熱結合しているわけではない (基本的には室温を計測する意図)。error_mHz はn平均で何mHzの誤があるか。temp はMCUの温度、sum は誤差カウントの蓄積、dac は実際に DAC に与えている値、デバッグ用の無意味なグラフが含まれているので注意(drift)
アラン偏差も出しているが1000秒未満は見てもしかたなく (PPSの精度的に)、1000秒以上も意味がある値かどうかよくわからない。まぁさすがにGPSにロックしているので長期ドリフトがない(右上がりにならない)ぐらいは確認できていると思う。
備考: 精度
1e-10 の精度 (1mHzオーダー)であれば (1/1e-10) / (60*60*24*365) = 317年で1秒しか狂わない。
STM32F103C8 激安ボード (BluePill) のセルフパワー化
BluePill は VBUS と 5V と書かれた端子が直結しており、5V ピンに給電してセルフパワー化しようとしたときにUSB接続すると危険です。なので5Vピンに自力で給電したい場合、これを切り離して純粋なセルフパワー化する必要があります。
基板上のカットポイントは写真の通りです。ここをカットすれば、基板上の 3.3V LDO を生かしたまま VBUS だけを分離し、5V ピンから給電できるようになります。
模倣チップ
ところで STM32F103C8 激安ボード (BluePill) ですが、載っているチップが中華製の模倣チップであることが多々あるようです (というより種類が異なる模倣チップがいくつかある?)。模倣チップでも動けばいいじゃんという話でもなく、SWG 経由で得られる coreid が本物と一致せず、若干面倒な手順を踏まないと書きこめないことがあります。
買う前に見分ける方法はあまりなく、親切な業者ならよく読んでみると STM32F103C8 とともに CKS CS32F103C8T6 と書いてあったりすることがあります。まず説明ページをよく読んでおく必要があります。GigaDevice GD32F103C8 というのもありますが、これは coreid も STM32 と同様のようです(未確認)。
ICをけずってリマークしてある悪質なものも存在しています (ebay で買ったらそうだった)。ダメだった場合に雑に dispute できるので、値段もかわらないし ebay よりも Aliexpress がおすすめ。
クリスタルラダーフィルタ
クリスタルラダーフィルタとクリスタルの特性測定
- http://www.giangrandi.ch/electronics/crystalfilters/xtalfilters.shtml
- https://www.changpuak.ch/electronics/Quartz_Crystal_Filter_Designer_1.php これが一番わかりやすいかも
- LCR メーターで容量 Cp を測る
- VNA で直列共振周波数・並列共振周波数を測る
- VNA の CH0/CH1 に直列で接続する
- VNA でR を測る。直列共振周波数付近で読む
- VNA の Ch0 に接続して読む。狭スパンで見ればスミスチャート上の等Rにそって表示されるはず
例
f_s = 9.997753 f_p = 10.015550 R = 10.7Ω C_p = 1.67pF C_s = C_p * ( (f_p**2) / (f_s**2) - 1) //=> 5.950825783949261e-15 (5.951fF) L = 1 / (4 * (Math.PI ** 2) * (f_s ** 2) * C_s) //=> 0.04258515389890184 (42.6mH)
これをもとに LTSpice などで等価回路を入力する。LTSpice の場合、xtal の記号はあるので、これ使うのが良い。といっても実体は C そのもので、右クリックで上記で計算した詳細パラメータを入力することで xtal の等価回路になる。
備考
C_s は fF (フェムトファラド) 単位と非常に小さいので、直接は測れない。C_p は pF、R は数Ωオーダーになる
電解コンデンサは常温放置でも劣化する
http://www.rubycon.co.jp/products/alumi/technote3.html#3-7
https://www.nichicon.co.jp/lib/aluminum.pdf
「放置特性」という形で言及されていることがある。放置していると、漏れ電流が増加していく。もともと経年劣化で必ず増加するが、電圧がかかっていれば自動修復されるものが、放置状態だとこれが行われないということのようだ。「電圧処理」をすれば修復されて元に戻る。
また経時劣化で内部圧力が高まり、液漏れすることがある。これも無負荷でも発生する。この場合、膨らんでいるコンデンサは「消費期限切れ」なので捨てるしかない。
pcb2gcode mirror-axis
https://github.com/pcb2gcode/pcb2gcode/wiki/Options:-Alignment-for-two-sided-PCB-and-offsets
mirror-axis まわりが追加された?ようで、デフォルトの挙動が変わってしまっていた。かなりハマった。しかもこれ、面倒なことにプロジェクトごと(ボードの大きさごと)に決められた値を入れないと今までと同じ挙動にならない。
mirror-axis には width の半分を入れる。一回変換してみて表示される数字を半分にわればいいが……
タカチ電機工業のサイトの検索結果を値段でソート
ケースのタカチの製品検索 ( https://www.takachi-el.co.jp/search/detail ) で結果をソートする方法がないので、JS でやる。
JS コンソールで以下を実行する。
p = $x('//*[@id="mCSB_1_container"]/table/tbody')[0];$x('tr[@class="child"]', p).sort( (a, b) => $x('number(./td[9])', b) < $x('number(./td[9])', a) ? 1 : -1 ).forEach( (e) => p.appendChild(e));
SPI TFT 液晶 (ST7735など) で色がおかしいときに試すこと
- RGB BGR の設定は正しいか
- 0xdddddd がグレーで表示されるか?
- されない場合 GBRG / GRBG の可能性あり
ドライバが同じでも、載っている液晶のデータ形式が違うことがある。
備考 RGB888 (24bit) から RGB565 (16bit) へ変換
RGB
#define RGB565(rgb888) ( ((( (rgb888)&0xf80000)>>8) | (((rgb888)&0xfc00)>>5) | (((rgb888)&0xf8)>>3)) )
GRBG
#define RGB565(rgb888) (( (rgb888) & 0x1c00) << 3)|(( (rgb888) & 0xf8) << 5)|(( (rgb888) & 0xf80000) >> 16)|(((rgb888) & 0xe000) >> 13)
Mojave で clang が stdio.h などを見つけられない場合
stdio.h や math.h などが見つからないと言われる場合
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
で SDK header をインストールしなければならない。
GYSFFMANC(MT3333)が定期的に受信できなくなる
秋月で売っているGYSFFMANC(MT3333) GNSSモジュールがおかしい。
中央下のグラフを見るのがわかりやすいが、定期的に (衛星が見えているにも関わらず) 一切受信できなくなり、しばらくすると回復するという挙動をする。なので全く安定して受信できない。
- 少しずつ SV Used が減少しはじめ、3D Fix を維持できなくなる。SV View はほぼ変化しない
- リセットから3〜4時間経過すると一切受信できなくなる
- そこからしばらくすると、再び受信できるようになる
- 上記の挙動を繰替えす
- 一切受信できなくなったタイミングで手動でリセット・ホットスタートすると即座に 3D Fix される。これよりアンテナの問題ではないと考えられる
- ほぼ同じ位置に別のアンテナをつけ、別の受信機(ublox NEO M8N) をつかって測位しているが、そちらではこのような現象は起きない。衛星の見える環境の問題ではないと考えられる
その他の情報
- バージョンは AXN_5.1.2_3333_17113000
- GPSとGLONASS で測位。SBAS の有効・無効は関係なく再現する。
- GLONASS は表示にはでるが測位に使われている形跡がないように思う。
考察
ゴミなのでは? とりあえず使用に耐えないので買って損してイライラするが、挙動について考えてみる。
- 衛星のエフェメリス情報の有効期限が4時間なので、周期と似ていて怪しい
- 3D Fix した状態だと捕捉している別の衛星の情報を一切処理しないとか?
- 特定の環境でだけ再現する可能性がある?
- 受信環境が悪い、かつ既に 3D Fix 状態だと他の衛星を無視するとか?
- ファームのバグ (メモリリークみたいな?)
- メモリリークとかでスタックするならリセット後にメッセージが出て、それが記録されると思うが、それは観測できない
よくわからんけど、とりあえずこのモジュールはおすすめできない。中国の怪しい GNSS モジュールのほうがはるかに安定している……
74HC04 の出力インピーダンス
10MHz GPSDO (そのうち書く)
OCXO と GPS 1PPS その3 | tech - 氾濫原 というのを3年前に書いてからやる気をうしなって放置してましたが、STM32F103 bluepill と組合せて、10MHz GPSDO をつくってます。今度は完成させたい。前よりは進捗していて、現状では 1mHz 未満ぐらい (0.1ppb) に誤差を抑えることができています。
PWM や DAC の出力範囲を変える
- PWM 信号は普通 0-5V などだが、1.5V-3.5V とかに変換したい
- その際、電源ソースを変更したい。
- PWMソースとは別の安定した電源から 1.5V-3.5V をとりだしたい
このようにMOSFETのレベルシフタと分圧抵抗でオフセットさせる。
出力を計算する
回路シミュレータ使って試行錯誤するのが一番簡単だが、一応自分で計算して、直接抵抗比を求められるようにしておく。
入力電圧 を図のような回路に入力したときの を求める。
テブナンの定理を使って計算していく。 と で分圧されている部分を内部抵抗のある電圧源に置き換える。このため、 を外した状態での の値 と、その内部抵抗 を求める。 は と で分圧された値なので、。内部抵抗を求める場合、既存の電圧源はショートして考えれば良いので、 と の並列合成抵抗 。
ここで は と によって分圧された出力なので、。
以下の通り
出力電圧範囲と中心電圧から抵抗値を求める。
入出力関数 を以下のようにする
入力電圧の最小・最大がそれぞれ のとき、出力電圧範囲 と中心電圧 はそれぞれ以下のようになる。
連立方程式を適当に計算すると、 を決めたときのほかの抵抗の値は以下のようになる。
入力電圧の最小値 が0の場合は
JS
JS のコードにするとこういう感じ
const V_center = 2.5;
const V_range = 1;
const V_SS = -5;
const V_DD = 5;
const V_min = 0;
const V_max = 5;
const R_1 = 11e3;
const R_2 = ((2*R_1*V_SS-2*R_1*V_DD)*V_range)/((V_min+V_max-2*V_SS)*V_range+(2*V_center-2*V_SS)*V_min+(2*V_SS-2*V_center)*V_max);
const R_3 = -((2*R_1*V_SS-2*R_1*V_DD)*V_range)/((V_min+V_max-2*V_DD)*V_range+(2*V_center-2*V_DD)*V_min+(2*V_DD-2*V_center)*V_max);
// re-calculate R_23 V_23 for reference
const R_23 = (R_2 * R_3) / (R_2 + R_3);
const V_23 = (V_DD - V_SS) * (R_3 / (R_2 + R_3)) + V_SS;
console.log({R_1, R_2, R_3, R_23, V_23});
for (let V_in of [0, 2.5, 5]) {
const V_out=(R_2*R_3*V_in+R_1*R_2*V_SS+R_1*R_3*V_DD)/(R_2*R_3+R_1*R_3+R_1*R_2);
console.log({V_in, V_out});
} lombok のシンボルが見つからないと言われ続ける場合
clean しても rebuild しても解決しない場合 inner class を利用していてかつ、inner class を import している可能性が考えられる。
この場合、inner class の import 文を削除し、完全修飾するようにすれば通るようになる。
エラーコードからは lombok が原因かはわからないし、それが innner class 絡みだということもわからない。lombok や inner class が原因か?ということに気付いたところでこの問題の9割は解決している。なのでこのエントリは実際には空虚で無意味な、躓いたということを知らせるだけのエントリである。






_2020-01-14T02-13-23Z.png)
_2020-01-14T02-13-34Z.png)




