非職業的技師の覚え書き

JK1EJPの技術的検討事項を中心に記録を残します。

RS-HFIQ(8)QuiskのCWモード(1)

CWのあい路

Quiskは低遅延のCWが訴求ポイントの1つとのことでしたので、簡単にCW送信ができると思っていました。しかし、先の改造(RS-HFIQ(6)QuiskのTuneとLOの同期制御 - 非職業的技師の覚え書き)が仇となって試行錯誤に時間を費やしました。
SSBの場合は側波帯が復調の対象になるため、仮想搬送波に対するQuiskの同調周波数(Tune)とRS-HFIQの局部発振周波数(LOあるいはVFO)が一致していても問題ないものと思います。
一方、CW受信の場合は搬送波しかないため、受信信号に対するQuiskのTuneとRS-HFIQのVFOを一致させると直交検波器(QSD)の回路が受信信号を検波できなくなり、復調対象のオーディオIQ信号がQuiskに入力されなくなります。また、CW送信の場合は、TuneとVFOを一致させると、QuiskからRS-HFIQの直交変調器(QSE)に入力するオーディオIQ信号をソフトウェアで生成できなくなる仕様になっていました。
CWモードの場合はTuneに対してトーン周波数(600Hz等)の分だけVFOをオフセットさせれば良いと思われますが、Quiskにはそのような機能は備わっていませんでした。LO固定のハードウェアによっては対応できないからかもしれません。RS-HFIQは対応できると思いますが、Split動作への影響等を調べる必要があるため、TuneとVFOの同期制御を一旦解除して元の非同期制御に戻しました。その調査過程の覚え書きを記します。

電鍵の接続

電鍵接続オプション

Quiskへの電鍵の接続方法としては、多様なSDRハードウェアに合わせて(1)シリアルポート、(2)MIDI、(3)LAN、(4)GPIOと様々なオプションがあるようです。しかし、ドキュメントが無いため、Quiskにどこまで標準実装されていて、どこからハードウェアに合わせて独自にコーディングをする必要があるのかが分かりませんでした。
RS-HFIQ本体のKEYジャックは内部のコントローラのArduino Nanoに結線されていますが、開発元による実装は放棄状態(上手く行かなかった模様)になっているため、RS-HFIQからキーイング信号を取り込む手段はありません。そこで、USBポートをまた一口塞いでしまいますが、電鍵の(1)シリアルポート接続を試みることにしました。
それにしても、PCソフトウェアのSDRはUSB喰らいであることが分かりました。CAT通信、IQ信号、マイク、電鍵と4口も占有します。USBハブを増設しましたが、USB3.0USB2.0を同居させることができないため、完全に集約するには至っていません。また、RF信号モニタ用のSDRplay / SDRuno用のUSBポートを確保しても、接続すると「デバイスが使用中です」の独占競合が発生して調停するのに難渋しました。不親切な警告ダイアログの競合「デバイス」が何かは後述します。

電鍵シリアル接続のConfig設定

Quiskへの電鍵シリアル接続に必要なConfig設定画面を下記に示します。

Configuration settings for serial connection of CW keyer.

以下の手順で設定しました。

  1. *RS-HF-IQ* タグを開く。
  2. Timing and CW タグを開く。
  3. 好みのトーン周波数を設定する。
  4. 電鍵を接続したシリアルポートを設定する。
  5. 接続信号端子(CTSもしくはDSR)を選択し、信号電圧レベルを選択する。

つぎに、Sound設定画面を下記に示します。

Sound setting screen to set the in-phase channel in IQ.

IQへのin-phaseチャネルの割り当ては試行錯誤で探索するしかありませんでした。受信はディフォルトのQチャネルをin-phaseに割り当てましたが、送信は入れ替えてIチャネルをin-phaseに割り当てる必要がありました。入れ替えないとLOを挟んでTuneの逆サイドに送信してしまいます。

電鍵シリアル接続の仮組

手持ちにFT231X(USB to FULL HANDSHAKE UART IC)を用いた「FTDI USBシリアル変換アダプター Rev.2 」(スイッチサイエンス)があったため、電鍵シリアル接続テストのための仮組を行いました。下図写真が変換アダプター、上左がFT231Xチップの応用例、下右がアダプターの回路図です。

Temporary assembly for serial connection test of CW keyer.

変換アダプターが搭載するUART(Universal Asynchronous Receiver/Transmitter)LSIのFT231Xは、RS-232C通信規格のハンドシェイク通信を行う信号線を全て備えています。シリアル通信におけるDATAはプロトコルに則ったビット列になるため、電鍵の開閉を検知するにはハンドシェイク信号を応用します。
ただし、変換アダプターの電気的仕様は、15mの距離を接続するRS-232Cとは異なり、ロジックレベル(3.3V)になっています。上図の上左のRS-232C応用例から分かる通り、電気的仕様を充足するためにはレベルコンバータ(★)が必要になります。上図の下右の回路図から、変換アダプターはロジックレベルのI/Oになっていることが分かります。また、変換アダプターを小型化するためか、あるいは目的の用途(プログラムライターとの通信等)に必要なかったのか、ハンドシェイク信号線はDTRとCTSの2本になっています。よって、QuiskではCTS信号端子を電鍵接続に使用しました。ちなみに、Quiskはエレキーのプログラムは備えていないため、信号端子は1本で足ります。
RS-232Cの信号線と電鍵への割付を下表に示します。Quisk PCはDTE(Data Terminal Equipment:端末装置)の役回りになり、電鍵はDCE(Data Communication Equipment:終端装置)になります。

Assignment of RS-232C signals to CW keyer.

シリアル通信の準備が整うと、Quisk PCはDTR(Data Terminal Ready:データ端末準備完)の信号レベルをHighに設定します。電鍵を挟んでDTR信号端子をCTS(Clear To Send:送信可能)信号端子に接続します。これにより、電鍵を押下する毎にCTS信号がHighレベルになります。
RS-232Cのハンドシェイクの方法は複数あり、プログラムで柔軟に対応できるようになっているようです。そのため、Pythonのシリアル通信ライブラリではハンドシェイク信号のセットやモニタが個別に可能になっています。これにより、QuiskはCTS信号のレベルを監視して電鍵の押下を検出しています。ここまでは、Quiskに実装済みでした。

電鍵接続テスト

QuiskのGUI表示

DTR信号ピンとCTS信号ピンを接続すると、QuiskボタンパネルのTxインジケータのフェイスカラーが赤色に変化しました。このTxインジケータは左隣のPTTボタンによって赤色に変化しますが、電鍵押下時にも赤色に変化することが分かりました。これで、Quiskが設定どおりにCTS信号を監視して、電鍵押下に反応していることが確認できました。

Tx indicator on Quisk button panel that changes face color to red when transmitting.

しかし、RS-HFIQに視線を転じると、PTTボタンでは点灯するTX LEDが電鍵押下では点灯していません。送信モードへの切換えがQuisk内で止まり、RS-HFIQまで届いていないようです。

RS-HFIQ TX LED点灯(送信切換)のためのコードの解析

ハードウェアファイル(hardware_rshfiq.py)には、RS-HFIQを送信状態にする関数としてOnButtonPTT関数しか実装されていません。したがって、電鍵押下の検知からOnButtonPTT関数をコールするまでがコードでつながっていないと、永久にRS-HFIQが送信状態に遷移することはありません。そもそも、OnButtonPTT関数はPTTボタンのコールバックイベント関数なので、つながっていない可能性が濃厚です。そこで、コードの追跡に着手しました。
quisk.pyファイルにSoundThreadクラスが実装されています。GUIのイベントポーリングとは並列に実行されるオーディオIQ信号のサンプリング信号処理の実装ではないかと推測しました。SoundThreadクラスが持つメンバ関数は、コンストラクタ、run関数、stop関数の3つだけです。
run関数の処理内容を下表にまとめます。

Processing details of the run function of the SoundThread class.

信号処理開始の初期化をした後は、終了指示まで永久反復処理を行っています。話題が逸れますが、反復処理の中でwdspライブラリの制御関数をコールしていることに気付きました。NR0V局Warren C. Pratt OMがSDRのために開発したopen-source Digital Signal Processing libraryのWDSPを、他の多くのSDRと同様にQuiskも利用していることが判明しました。
それはさておき、反復処理の中で「CW」のキーワードが入った関数はHardware.PollCwKey関数のみになります。名称からは「CWキーを監視してハードウェアの処理を実行する」と読めました。そこで、ハードウェアファイル(hardware_rshfiq.py)にPollCwKey関数を実装し、OnButtonPTT関数と同様にRS-HFIQを送信状態に切り換えるようにしました。結果は、電鍵を押下しても送信状態に切り換わることはありませんでした。PollCwKey関数は「ハードウェアを介してCWキーを監視する」関数のようです。RS-HFIQには電鍵を接続せず、シリアル通信に接続しているため、今回は関係が無かったようです。
つぎに、着目したのはオーディオIQ信号を読み込んだ後に実行しているapplication.OnReadSound関数です。これは行数が多い関数ですが、途中に以下のコードを発見しました。

    if QS.is_key_down():	# Tx indicator
      if not self.tx_indicator:
        self.tx_indicator = True
        self.pttButton.Tx.TurnOn(True)
    else:
      if self.tx_indicator:
        self.tx_indicator = False
        self.pttButton.Tx.TurnOn(False)

電鍵が押下されていた場合に送信インジケータをTrueに設定しています。ここをコメントアウトすると、上記のQuiskボタンパネルのTxインジケータが反応しなくなりました。このコードがTxインジケータを制御していることが分かりました。しかし、他にやっていることはpttButton.Tx.TurnOn関数にTrueを設定することだけです。詳細は不明ですが、ボタンの属性のようなものを切り換えているだけと判断しました。このコードの中にハードウェアを制御している部分はありません。
さらに読み進めると、次のコードを発見しました。

    if self.want_RxTx:
      x = QS.is_key_down()	# Must be 0 or 1
      if self.old_RxTx != x:
        self.old_RxTx = x
        Hardware.OnChangeRxTx(x)

別のコードにあるwant_RxTxフラグの設定箇所を調べると、Hardware.OnChangeRxTx関数が実装されているかどうかを判定するフラグであることが分かりました。電鍵の押下状態が切り換わったら、電鍵の押下状態を引数にしてHardware.OnChangeRxTx関数をコールしています。この関数がハードウェアの送受を切り換える関数に違いないと推測し、ハードウェアファイル(hardware_rshfiq.py)に以下のコードを実装しました。RS-HFIQのコントローラであるAruduino Nanoに送受切換の「x」コマンドをシリアル送信します。

    def OnChangeRxTx(self, is_tx):
        if is_tx:			# Turn the software key bit on or off
            cmdstr='*x1\r'
        else:
            cmdstr='*x0\r'
        if serialport.isOpen():
            if DEBUG == 1:
                print("Setting Rx/Tx for is_key_down(), cmdstring:  ", cmdstr)
            serialport.write(cmdstr.encode())

これで、電鍵押下に反応してRS-HFIQが送信モードに切り換わるようになりました。後は、IQ信号が適切に出力されていれば、QSE(直交変調器)でRF搬送波信号が生成され、終段アンプから送信されるはずです。
ここまでのCW送信に向けたコード解析およびコーディング結果をまとめると以下となります。

Block diagram of CW transmission with Quisk and RS-HFIQ.

受信トーンを探して

CWモードにおいて、Quiskが同調周波数(Tune)と局発周波数(LO)の関係を制御しているかどうかを、まず受信状態で確認しました。先に導入したTuneとLOの同期制御は切った状態にしました。

Looking for CW receiving tone.

RS-HFIQのLOを7,020,000Hzに設定しました(①)。RS-HFIQのBIT機能を用いて、1,400Hz下方の7,018,600Hzに模擬受信信号を発生させました(②)。QuiskのモードをLSBからCWLに切り換えると(③)、自動的に設定トーン周波数600Hzに応じたRIT(Receive Incremental Tuning)が設定され(④)、TuneをLOより600Hzだけ低域側にシフトさせます(⑤)。これにより、600Hzのサイドトーンを発生させているように見えます(⑥)。

Looking for CW receiving tone (continued).

しかし上図に示す通り、BIT周波数をさらに低域側7,018,600Hzにずらして(⑦)、Tuneで追跡すると(⑧)、TuneとLOの間隔は1,400Hzに広がりますが、サイドトーンは600Hzのまま維持されます。Quisk内部のソフトウェア処理は解析できていませんが、仮想的なVirtual_LOを設定して(⑨)、サイドトーンを発生しているように見えます(⑩)。RS-HFIQのLOとは無関係にサイドトーンを発生していることだけは確かです。

送信トーンを探して

次に、BITをOFFにし、電鍵を押下して送信状態にしました。この時、サウンドカードのHeadphone出力信号(オーディオIQ出力信号)をスピーカアンプに接続して、発生音色をモニタしながらTuneを連続して変更しました。

Looking for CW transmission tone.

受信テストと同様に、RS-HFIQのLOを7,020,000Hzに設定し(①)、QuiskのモードをLSBからCWLに切り換えると(③)、自動的に設定トーン周波数600Hzに応じたRITが設定され(④)、Tuneは7,019,400Hzに設定されます(②)。両者の乖離を600Hzにした状態から送信テストを開始しました。
電鍵を押下して送信状態にすると(⑤)、PCのスピーカからは受信時と同じ600Hzのサイドトーンが発生し、オーディオIQ出力をモニタするスピーカからも600Hzのトーンを聴くことができました(⑥)。Tuneを低い周波数に変えて行くと、オーディオIQ出力のモニタ音は高い音色に遷移して行きましたが、PCのスピーカからは600Hzのサイドトーンが発生したままでした(⑧)。
送信時のサイドトーンはQuisk内部のソフトウェアで処理されているため、RS-HFIQのLOとQuiskのTuneの間の関係変化からは影響を受けないことが分かりました。逆に、送信周波数はRS-HFIQのLOとQuiskのTuneの間の関係だけで決まり、そのオフセット周波数のオーディオIQ信号がQuiskからRS-HFIQに送出されることが分かりました。
モードをLSBからCWLに切り換えることによってQuiskがTuneをシフトさせている理由は、受信時にはLOと一致した受信CW信号からオーディオIQ信号をQSDが出力できないからであり、送信時にはLOと一致した送信CW信号を0HzのオーディオIQ信号(ON/OFF信号)からQSEが出力できないからです。Tuneのシフト量はトーン周波数の600Hzである必然性はなく、サンプリング定理が許す帯域内であれば任意です。これによって、LOを固定したままTuneをサンプリング定理の帯域内で自由に可変することができます。LOと言う名の特異点付きですが・・・。

次に、以下のSDRplay(RSP1A)とSDRunoを用いた次の実験構成で送信周波数を確認しました。RS-HFIQ内部のQSEブロックでオーディオIQ信号(600Hz)がLO(7,020,000Hz)と混合されてRF送信信号(7,019,400Hz)が生成され、BPF、PA、LPFを通過して送信されるはずです(⑦)。

Configuration of the experimental system using SDRplay (RSP1A) and SDRuno to check the transmitted frequency from RS-HFIQ controlled by Quisk.

なお、SDRunoとQuiskを同時に起動しようと試みると、「デバイスが使用中です」と表示されて起動できませんでした。何のデバイスか直ぐには分からなかったのですが、SDRunoもQuiskも復調音をPCから再生するためにスピーカが競合していることが分かりました。Quiskはスピーカのデバイス設定を外しても起動できるため、臨時的にQuiskの復調音を切断しました。

LOを7,020,000Hzに固定し、Tuneのオフセットを低周波数側に-600Hz、-1,200Hz、-1,800Hzと変更し、転じて0Hz、600Hzと変更しました。下記にその結果を示します。上段にQuiskのTune設定を、下段にSDRunoによるRS-HFIQ送信スペクトルの測定結果を示します。

Quisk Tune setting and RS-HFIQ transmit spectrum; (1) Tune = LO - 600Hz.
Quisk Tune setting and RS-HFIQ transmit spectrum; (2) Tune = LO - 1,200Hz.
Quisk Tune setting and RS-HFIQ transmit spectrum; (3) Tune = LO - 1,800Hz.
Quisk Tune setting and RS-HFIQ transmit spectrum; (4) Tune = LO.
Quisk Tune setting and RS-HFIQ transmit spectrum; (5) Tune = LO + 600Hz.

QuiskのTune設定とSDRunoの測定スペクトルの間には30Hzのオフセットがありました。ハードウェアのRS-HFIQとSDRplay(RSP1A)の間のオフセットです。それを考慮すれば、「送信周波数はRS-HFIQのLOとQuiskのTuneの間の関係だけで決まる」ことが確認できました。また、IQ CW方式では、Tune = LO ± 100Hz程度が送信不可の特異点になることも確認できました。
特異点を避けるために、CWモードではTuneとLOのオフセット同期方式を実装することが望ましいと思います。Split操作への影響等を調査して判断したいと思います。