psn

6月の第3日曜日は父の日だそうだ。母の日と均等を取るために設けられたらしい。 アメリカが発祥とか言うけど、どこかのデパートの戦略だろう。

すっかり通販メーカーも便乗してて、あのアプルからも販促メールが届いていたぞ。 おとーさんのグレードアップとか言って、ipad proはいかがですか? アプルテレビは いかがですか? 時計も有りますよってね。

でもね、考えちゃうんだ。今使ってる ipadも早いもので丸3年。この所、女房がAV系に 目覚めちゃって、何とかいうバンドのライブだとか、ドローンで撮った空撮とか、 電池を酷使するようなものばかり見てる。

そろそろ電池の寿命が尽きるのではと心配。電池交換するか? それとも、電池のへたりが 縁の切れ目とばかり、広い画面に移行するか?

iPad Pro 12.9

dマガジン

こういうあおりを見ると、ぐぐってくるものがあるなあ。キーボードを外付けに すれば、そこそこ使えそうだし。。。

最近、ipadに入っているpythonが、ついに2圏内を脱出して、3.5になった。グラフィックが 得意らしい。そうなると、速いipadは魅力。

アプルのWWDC 6月の部が開催されてたみたいで、iOS 10 が出たり、OS Xから macOS Sierraに変更に なるらしい。とすると、WWDC 秋の部では、ハードが一新される可能性があるな。

父の日はオイラーに関係無かったけど、敬老の日は大いに関係がありそうな予感がする。 暫くは、様子見でいきますか。

前回、不思議がった、循環小数の話、 応用代数学研究室を見たら 更に不思議が隠れていたよ。どこまで面白いんだ、数字の話。

配線に色を付ける

前回、実体配線図を描くために、spiceのネットリストをdot語に変換するPython3用の コードを書いた。そして足りない機能をTODOとして挙げておいた。

一番簡単そうな、電源とグランド線を目立つようにしてみる。変更部分を挙げる。

def vp(a):
    for v in a:
        if v[0] == 'V' or v[0] == 'v':
            return True
    return False

def wire():
    for k in wl.keys():
        opt = ''
        if vp(wl[k]):
            opt = '[color=red,style=bold]'
        if k == '0':
            opt = '[color=blue,style=bold]'
        for i,v in enumerate(wl[k]):
            if i == 0:
                bv = v
            else:
                print('   ', bv, ':', k, ' -- ', v, ':', k, end = '')
                print(opt, ';')
                bv = v
        if k == '0':
            print('   ', bv, ':', k, ' -- gnd [color=blue,style=bold];')

電源ラインは赤の太線、グランドは青の太線で書いてくれる。本当は、電源を正電源と して使ってるか、負電源用か、あるいは信号源かで、色分けしたかったけど、それを やろうとすると、根本を変更する必要があるので断念。上記は3分間のhackです。

そのうちの1分間は、改行無しのprintってどうやるんか、右往左往してました。 結局、ipython3が詳しい事を例示してくれたよ。

In [8]: print?
Type:        builtin_function_or_method
String form: <built-in function print>
Namespace:   Python builtin
Docstring:
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file:  a file-like object (stream); defaults to the current sys.stdout.
sep:   string inserted between values, default a space.
end:   string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.

PSN with OPAMP

積み残していた、演算増幅器を使ったPSNをやってみる。再掲になるかも知れないけど、 リンクを挙げておく。

PSN SSBゼネレータ は、球にPSN用のブリッジを組み合わせたもの。懐かしいのでメモした。

PSN/SSBジェネレータ

8段70dBのAF-PSN設計する

オペアンプの復習。 オペアンプで始めるアナログ回路 にある、引き算器が基本。 そして、アマチュア無線家の方が、いろいろ考察されている。 All pass filter

まずは基礎実験。オペアンプは、前々回だったかに見つけた、理想アンプです。

PSN with OPAMP
.inc opamp.sub

.subckt SHIFT vin out cp=0.01u rp=16k
  rin    vin     inv     10k
  rf     inv     out     10k
  rpx    inp     0       rp
  cpx    vin     inp     cp
  Xop    inp     inv     out    OPAMP
.ends SHIFT

Vsig vin 0 ac 1v dc 0v

Xop1   vin   out1   SHIFT cp=0.02u rp=32k
Xop2   out1  out2   SHIFT cp=0.02u rp=16k

.ac dec 10 10 90k
.end

孫ボードを作って、メイン基盤の配線を簡素化。CR類や配線が見えなくなりすっきり。 移相器へのパラメータは、孫側に伝達される。

ngspice 276 -> run
ngspice 277 -> set units=degrees
ngspice 278 -> plot vdb(out) ph(out)

思い出したように、ngspiceの使い方を復習。ゲインは周波数によらず一定。位相だけが ずれる。位相角の表示を度にした。毎回設定するのが面倒なので、.spiceinitに書いて おこう。

バラック実験も終って、いよいよ本式です。以下、メイン部のみを掲載。 キーボード叩いて、回路を組み立てるって、なかなか快感。

Vsig vin 0 ac 1v dc 0v

Xu1   vin    uout1  SHIFT rp=114.8k  cp=10e4p
Xu2   uout1  uout2  SHIFT rp=86.3k   cp=22e3p
Xu3   uout2  uout3  SHIFT rp=71.8k   cp=10e3p
Xu4   uout3  uout4  SHIFT rp=63.26k  cp=47e2p
Xu5   uout4  uout5  SHIFT rp=54.60k  cp=22e2p
Xu6   uout5  uout6  SHIFT rp=17.37k  cp=22e2p

Xl1   vin    lout1  SHIFT rp=76.25k  cp=47e3p
Xl2   lout1  lout2  SHIFT rp=51.84k  cp=22e3p
Xl3   lout2  lout3  SHIFT rp=46.68k  cp=10e3p
Xl4   lout3  lout4  SHIFT rp=60.6k   cp=47e2p
Xl5   lout4  lout5  SHIFT rp=32.8k   cp=22e2p
Xl6   lout5  lout6  SHIFT rp=5.523k  cp=22e2p

.ac dec 12 10 90k

6段2列のAF-PSN回路。上の段と下の段の位相差を、下記にて確認。

ngspice 2 -> plot ph(lout6,uout6)

60Hzから5KHzぐらいまで、位相差90度をキープしてるように見える。ただ、 500Hzから1.2kHzぐらいの間、位相が180度シフトしてる。これは、多分ngspiceの 演算の癖から来るものだろう。

JFETで、反転・非反転

上の無線家が解説された資料の中に、接合型FETを使った、反転・非反転信号を 取り出せる回路が出てきた。この反転・非反転は、PSNをやった時にも利用されてた。 あの時は、石を2つ使っていたが、こちらの方は1石構成でより倹約家向け。

どんな塩梅か、ngspiceで適当にやってみる。

JFET amp

J1 d g s NJF
.model NJF NJF

vdd vdd 0 10v
rd vdd d 2.2k
rs s   0 2.2k
rg g   0 500k
ci in  g 10u

vsig in 0 sin(0v 1v 1khz 0 0)
.tran 50us 5ms

何も考えずに、適当なCRを設定した。1KHzの振幅1Vのサイン波をゲートに突っ込み、 ドレインとソースの波形を観測しましょってやつ。

で、どうも適当過ぎて、波形が歪んで見えるんだけど、それはオイラーの老人性眼球 ゆがみかな? そういう時は、数値で検証するんだ。

ngspice 2 -> fourier 1k s
Fourier analysis for s:
  No. Harmonics: 10, THD: 6.18756 %, Gridsize: 200, Interpolation Degree: 1

Harmonic Frequency   Magnitude   Phase       Norm. Mag   Norm. Phase
-------- ---------   ---------   -----       ---------   -----------
 0       0           0.521451    0           0           0
 1       1000        0.388761    0.00289977  1           0
 2       2000        0.0239791   -89.884     0.0616808   -89.887
 3       3000        0.00189941  -1.413      0.0048858   -1.4159
 4       4000        0.00015169  80.8074     0.000390187 80.8045
 5       5000        3.76434e-05 -91.094     9.6829e-05  -91.097
 6       6000        4.19733e-05 -50.55      0.000107967 -50.553
 7       7000        3.4305e-05  -50.685     8.82418e-05 -50.688
 8       8000        3.71978e-05 -45.147     9.5683e-05  -45.15
 9       9000        3.2205e-05  -36.699     8.28399e-05 -36.702

ngspice 2 -> fourier 1k d
Fourier analysis for d:
  No. Harmonics: 10, THD: 6.18756 %, Gridsize: 200, Interpolation Degree: 1

Harmonic Frequency   Magnitude   Phase       Norm. Mag   Norm. Phase
-------- ---------   ---------   -----       ---------   -----------
 0       0           9.47855     0           0           0
 1       1000        0.388761    -180        1           0
 2       2000        0.0239791   90.1157     0.0616808   270.113
 3       3000        0.00189941  178.587     0.0048858   358.584
 4       4000        0.00015169  -99.193     0.000390188 80.8045
 5       5000        3.76434e-05 88.9061     9.6829e-05  268.903
 6       6000        4.19733e-05 129.45      0.000107967 309.447
 7       7000        3.43049e-05 129.315     8.82416e-05 309.312
 8       8000        3.71978e-05 134.853     9.56829e-05 314.85
 9       9000        3.2205e-05  143.301     8.284e-05   323.298

フーリエ変換してみましょコマンドが用意されてる。直流から始まって、基本波、2次 高調波、、、9次高調波まで、振幅と位相に分けて表示してくれる。右側は、それを 正規化した結果だ。オーディオ屋さんはこういう現実を突きつけられると、ビビリます。 歪み率が6%って、どういうアンプを作ってんねん。

ソース側の出力は同相、ドレイン側は逆相。そして、ソース、ドレインの直流電位も FFT野郎が暴いてくれていますよ。こういう解析結果が出てくるなら、オシロの波形を 眺めて、歪んでいるのは被観測波形か、観測者の眼か悩む必要は全くありません。

ちなみに、信号源の純度、ピュリティーも確認しておかねばね。

ngspice 2 -> fourier 1k in
Fourier analysis for in:
  No. Harmonics: 10, THD: 0.00388824 %, Gridsize: 200, Interpolation Degree: 1

Harmonic Frequency   Magnitude   Phase       Norm. Mag   Norm. Phase
-------- ---------   ---------   -----       ---------   -----------
 0       0           -7.1096e-06 0           0           0
 1       1000        0.991807    -0.00084581 1           0
 2       2000        1.4151e-05  -80.106     1.42679e-05 -80.105
 3       3000        1.4066e-05  -75.169     1.41822e-05 -75.168
 4       4000        1.39477e-05 -70.245     1.4063e-05  -70.244
 5       5000        1.37969e-05 -65.338     1.39108e-05 -65.337
 6       6000        1.36143e-05 -60.453     1.37267e-05 -60.452
 7       7000        1.3401e-05  -55.594     1.35117e-05 -55.593
 8       8000        1.31583e-05 -50.767     1.3267e-05  -50.766
 9       9000        1.28877e-05 -45.977     1.29942e-05 -45.976

高調波は基本波の-96dBぐらい。総合歪み率も、優秀な成績でした。

歪みを改善

それにしても、酷すぎる歪みだな。どうして歪む? ヒントは、runした直後に 報告してくる

Initial Transient Solution
--------------------------

Node                                   Voltage
----                                   -------
d                                      9.50301
g                                  5.00999e-06
s                                     0.496991
vdd                                         10
in                                           0
vsig#branch                                  0
vdd#branch                        -0.000225905

ここの、ソースの電圧。やけに低す過ぎないか? この回路自身は、ソースフォロワーと 看做せるから、ゲートに入ってきた電圧が、ほぼそのままソースに出てくるはず。

振幅が 1V入力に対して、裕度が0.5Vじゃ、波形が潰れるわな。解決方法は、ゲート電圧を 持ち上げてやれば良いかな。1megの抵抗でVddにプルアップしてみた。

結果、ゲート電圧は、1.9V、ソース電圧は1.4Vになった。これでいいかなと思ったら、 歪み率が先ほどより更に悪化して、13.4%にもなってしまったぞ。

その2-1 まずはゲテモノ? FETシングルアンプ なんかを見ると、必然的に歪みを生む回路っぽい。石のモデルは無視定なんだけど、

ngspice 2 -> show j1
 JFET: Junction Field effect transistor
     device                    j1
      model                   njf
        vgs               0.49398
        vgd              -6.76491
         ig           1.97053e-06
         id           0.000621993
         is          -0.000623964
        igd          -6.77491e-12
         gm           0.000498796
        gds                     0
        ggs           7.61877e-05
        ggd                 1e-12

こんな動作点で動いている。ソース及びドレインに入っている抵抗値を大きくすると 歪み率はやや改善するけど、褒められたものでは無い。

ちなみに、入力振幅をずっと小さく、0.1Vにすると、歪み率は1桁向上し、0.6%となった。 ここで、ちょっと歪み について、知見を得ておく。人間相手だと、0.3%が検知限界とな。

以前にやったPSNの回路で、差動増幅器が使われていた。あれなら歪みもちゃんと 考慮してると思うので、検証してみると、、

0.1V入力での歪み率は、なんと25%となった。まだ過大入力でサチッていると思い、10mV入力と 絞ってみた。そしたら、同相出力側が0.05%、反転出力側が0.08%となった。 10mV入れて、出力が0.45V得られているので、増幅度は33dB。

更に入力を1mVの小入力にすると、歪み率は0.01%と、メーカー並みのものになった。 半導体って、いかに非線形な回路か、よく分かる事例でした。いえね、歪みなんて、 今まで深く考えた事無かったですから。

いや、無線の世界だと、わざと歪ませて高調波を作り、その高調波の例えば2倍の部分 だけを取り出す同調回路をいれる。逓倍回路には、さんざんお世話になったくせに。

そもそも、アマチュア無線家が、電波を自由に使う事を許されるようになった発端は、 大陸間をまたぐ通信に短波を利用出来る事を発見・実証したから。その功績を讃えての 事だった。

使えた周波数は、3.5MHz、7MHz、14MHz、21MHz、28MHzだった。周波数帯によって電波の 飛び方に特徴があるので、色々な周波数が開放されたんだ。

この周波数関係は、3.5MHzの倍数になっている。安定な周波数を発生させるには、水晶の 物理的形状によって決まる固有周波数共振を利用するのが一番。一つの水晶片があれば、 それを使って発振させ、その波形を歪ませて、高調波を取りだすのが、周波数変動を 防ぐには有利。そんな訳で、逓倍技術は、昔の無銭家には必須の技術だった。

そのうちに、上記の周波数以外も開放されるようになった。電波は国を跨いで飛んで行くので、 国際的な利用の取り決めが必須。そうでないと、混信しちゃうからね。

自国に都合の悪いニュースが流れると、妨害電波を出して、国民が受信出来なくしちゃう、 野蛮な国はいまだに存在するけどね。

で、その国際管理機構に、世界のアマチュア無線連合が請願(圧力)をかけて、使える 周波数帯を増やした。使えるようになったのは、8MHzとか10MHzとか。。従来の、3.5MHz帯の 倍数以外のもの。

電波の足し算とか引き算で、必要な周波数を容易に得る事が出来るようになった。 いわゆるミキサーってやつ。数学的には、2種のsin波を掛け算すると、和と差の 周波数が出て来るって所に根拠が有るんだけどね。

そう、ハードは、数学的な原理に則って動いています。今やってるspiceって、 ハード(トランジスタとか抵抗やコンデンサ類)を組み立てて、その回路に 入力を与え、出力の応答を見るって事を、仮想的にやってる。

言い方を変えれば、ハードで組み立てた関数の、入出力を見てるって事。 y = f(x) の確認に過ぎない。ソフト屋さんとの違いは、xの発生に信号源を 使う事。yの確認にオシロスコープや場合によっては、FFTして歪みを観測 するとかね。豊穣な世界が拡がっている訳ですよ。

半田付けの煙も発生せず、感電や火災の心配もせずに、自由奔放に無料で 楽しめるって、とっても愉快。長生きしてて良かったとつくづく思いますね。

B&W PSN

JFET amp and BW-PSN

J1 d g s NJF
.model NJF NJF

vdd vdd 0 10v
rd vdd d 2.2k
rs s   0 2.2k
rg g   0 500k
ci in  g 10u

r1 d   a  125k
c1 a   ao 680p
r2 ao  s  198k
c2 ao  s  430p

r3 d   b  487k
c3 b   bo 680p
r4 bo  s  770k
c4 bo  s  430p

* for spot freq. +45 - (-45) = 90
r5 in  r  487k
c5 r   0  680p
r6 t   0  487k
c6 in  t  680p
*  plot ph(r) ph(t) ph(s,t)

*vsig in 0 sin(0v 100mv 1khz 0 0)
*.tran 20us 5ms

vsig  in  0 AC 0.1v
.ac dec 12 10 90k

.end

B&W型と称するPSNが出てたので、JFETの回路に組み込んでみた。同時に、RF部で90度の 位相差を得るために使われている回路を、定数変更してAF帯にし、実験出切る ようにしておいた。45度進ませた点と45度遅らせた点の差を取れば、90度。

位相って、時差だな。2点間の差を位相は度で表現、時差は時間で表現。上でいきなり 45度って出てきたけど、基準は勿論、入力信号。

時刻表記で出て来る、日本時間 JST ってのは、ロンドン時間(正確には冬季時間) からの差を言っている。 当たり前なんで、わざわざロンドンとの時差とは言わないのが普通。

折角なので、時差のお勉強。Unixは時差と言うか、現地時間がロンドンとどれぐらい 離れているかのデータベースを持っている。置いてある所は、通常は/usr/share/zoneinfoの 中。ここに大陸別なdirがあり、その中に個別のデータファイル(但しbinary)がある。 例えば、Asia/Tokyoって具合。強引に開いてみると、ファイルの一番最後の部分が ASCII文字になってる。

$ tail -1 Asia/Tokyo
JST-9

もう一例で、ハワイはどうだ? 行政区分ではアメリカの仲間もしくは、日本国ハワイ 県ぽいけど、太平洋ってのがあって、そこにグアムとかと同列に置いてあった。

$ tail -1 Pacific/Honolulu
HST10

ロンドンからロンドンどんどんと東へ行くと、黄金の国ジパングへ行ける。その工程時間は 9時間。一方、ロンドンどんどんと西へ行くと、楽園の島ハワイはホノルルへ行ける。 工程時間は10時間。

だったら、日本からハワイ行く、工程時間は? 9時間かかってロンドン到着、そこから 10時間かかって、ようやくハワイに到着。

地球が丸い事を知ってたら、日本から取りあえず東へ行け。そしたら、途中にある日付境界線を 突破して、5時間でハワイへ着くぞ。

日本からハワイへ行くと、1日分得をした気分になる。逆にハワイから帰国すると 1日分、未来へ行ったような気分になるな。

昔ヨーロッパに駐留してた時、各地を旅して、国境を跨ぎ、体の左はドイツで右はオランダ とかやって喜んでいた。死ぬまでに、体の左は今日、体の右は明日ってやってみたいんだけど、 そんな事が出来る場所有るのかしらん?

日付変更線に近いと思われるところは

Enderbury
PHOT-13
Fakaofo
TKT-13
Tarawa
GILT-12
Tongatapu
TOT-13
Wake
WAKT-12
Wallis
WFT-12

こういう所か。で、Wallisってどんな所?

$ grep Wallis zone.tab
WF      -1318-17610     Pacific/Wallis
$ grep Tokyo zone.tab
JP      +353916+1394441 Asia/Tokyo

WFってのが国名だな。次の数値は、北緯・南緯のデータと東経・西経の地理情報か。 ほぼ赤道直下、ロンドンの真裏って表現で合ってるかしら。以上は、FreeBSD調べ。

OpenBSDのソースを調べたら、iso3166.tabって言う国名のDBに

WF      Wallis & Futuna
JP      Japan
US      United States

こんな具合の載ってた。

リナちゃんだと、構成がちょっと違っていたり、JPってのの国名を引くファイルが 付属してたりする。ああ、また、横道に逸れてしまったわい。軌道修正。

位相差45度ってのは、基準信号から45度分進んでいるって事。勿論、この考えは 同じ周期の波形でしか意味は無い。

aoとboの位相差を 調べてみたけど、前にやったのと同じような結果となった。根本的にオイラーの 解釈が間違っている? ngspiceから、生データが得られるので、自前で計算してみるか。

ngspice 2 -> print ao bo > LOG

これをやると、2組の複素数データが得られる。ただ、こうすると、得られる結果が

Index   frequency       ao                              bo        
------------------------------------------------------------------------------------
0       1.000000e+01    3.979554e-02,   -5.55594e-04    3.961990e-02,   -2.48868e-03
1       1.211528e+01    3.978943e-02,   -7.21902e-04    3.952935e-02,   -3.05648e-03
:

のようになって、これを素直にPythonへ取り込むには、カンマがちょっと邪魔になると 思う。(sedで除去するのが定番)送り出し側で、ちょいと手がかかるけど

ngspice 2 -> ngspice 2 -> print real(ao) imag(ao) real(bo) imag(bo) >LOG

して、Python側で扱い易いようにした方が良いかと

Index   frequency       real(ao)        imag(ao)        real(bo)        imag(bo)  
--------------------------------------------------------------------------------------
0       1.000000e+01    3.979554e-02    -5.55594e-04    3.961990e-02    -2.48868e-03
1       1.211528e+01    3.978943e-02    -7.21902e-04    3.952935e-02    -3.05648e-03
:
46      6.812921e+04    3.845586e-02    3.281470e-03    3.875912e-02    8.046724e-04
47      8.254042e+04    3.855693e-02    2.715990e-03    3.876409e-02    6.641636e-04

それから、Pythonの複素数の扱いは、 9.3. cmath - 複素数のための数学関数 に有った。なんでPythonまで持ち出すか? ngspiceで偏角を直接求めると

ngspice 2 -> print ph(ao) ph(bo)
 :
23      8.254042e+02    -8.81143e-01    9.041150e-01
24      1.000000e+03    -9.17804e-01    8.879602e-01
25      1.211528e+03    -8.97054e-01    8.337474e-01
26      1.467799e+03    -7.36934e-01    7.602402e-01
27      1.778279e+03    -2.18254e-01    6.776738e-01
28      2.154435e+03    5.090729e-01    5.928589e-01
29      2.610157e+03    8.234978e-01    5.106247e-01
 :

こんな具合に、時計方向、反時計方向に廻るのはいいんだけど、一周しても更に 回ってますよって結果になっていたから。

まてまて、ひょっとして、仮数部だけ見て 大小を判別してないか? 指数部も同時に見て、大小比較、暗算せいよ。

そんなの無理です。人間技じゃありません。だったらipython3だな。例えば、気になる ao[24]の位相。先のLOGから、realとimgaを拾いあげて

In [4]: cmath.phase(complex(8.796712e-03  ,  -1.14999e-02))
Out[4]: -0.9178031629023237

In [5]: cmath.phase(complex(8.796712e-03  ,  -1.14999e-02)) * 57.1
Out[5]: -52.40656060172268

In [6]: z = complex(8.796712e-03  ,  -1.14999e-02)
 
In [8]: cmath.polar(z)
Out[8]: (0.014478599449565003, -0.9178031629023237)

位相(偏角)を求めて、それを度に変換。複素数にしておくと、振幅と位相も セットで得られるのね。

オイラーの大いなる勘違いが是正されました。E形式の目視による暗算は、人間(オイラー)を 惑わすばかり。そういう汚れ仕事は、コンピュータに任せる事。

まてよ、昔はE形式の数値の計算もスイスイとやっていたではないか。仮数の計算は、 尺とカーソルに任せて、指数部分は暗算でやってた。これでも、計算尺2級の腕前 だったんだぞ。仮数の計算を多少間違っても、指数すなわち桁は絶対に間違えるな。 これ、計算尺の指導をしてくれた先生が、口を酸っぱくして言っていたな。

大いに反省すべし。