非職業的技師の覚え書き

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

Teensy(19)Keiths' SDRのEncoder

Encoderの種類と選定

Keiths' SDRでサポートされるEncoderの種類

自作やKitのTranscieverに使われるEncoderには、大別すると以下の種類があります。

  • (1)光学式 Encoder
  • (2)機械式 Encoder
  • (3)I2C Encoder

(1)光学式Encoderは、サーボモータ等の回転軸に直結して用いる回転センサを流用したものです。デテント(戻り止めのための回転位置保持抵抗)が無く、スムーズに回転します。シャフトも含めて大型であり、1回転当たりのパルス数が多いため、VFO(PLLシンセサイザ)の周波数チューニング用メインダイヤルに好まれて使われる例が多いようです。

(2)機械式Encoderは、小型かつ安価であり、QRP Transciever Kit の多くに採用されています。スラスト方向のプッシュスイッチが付いているものもあります。

(3)I2C Encoderは、(2)機械式Encoderの底部にI2C通信用のインターフェース基板を付けたものです。SDR Transcieverを複数のEncoderを持つ構成にしたとしても、Teensyとの接続が容易になります。また、インターフェース基板に搭載されたマイコンがカウンタ機能を持つため、Teensyの負荷が幾分かは軽減されます。90度位相のずれたA/Bパルスから回転方向を判別してカウントをUp/DownするところまでI2C Encoder側で実行します。

Keiths' SDRは上記の全てのタイプをサポートしますが、(1)も(2)も「Mechanical Encoder」に分類され、プッシュスイッチの有無で区別されます。先日組み立てたBackpackボードには、プッシュスイッチ無しの「Mechanical Encoder」用コネクタが一式、プッシュスイッチ有りの「Mechanical Encoder」用コネクタが二式、「I2C Encoder」用コネクタが一式それぞれ準備されています。

選定したI2C Encoder

K7MDL局Mike OMが採用した(3)I2C Encoderと同じものを選定しました。イタリアDUPPA社の「I2C Encoder V2」です。イタリアから発送と記されていましたが、実際はオランダから発送され、コロナ禍の影響か一時行方不明になりましたが、長旅の末に到着しました。蛇足ですが、DUPPA社のアイコンは日本のアニメキャラクタに類似しています。イタリアのスタートアップの若者は日本のアニメファンなのだろうか・・・?

「I2C Encoder V2」とはI2Cインターフェース基板のことを指し、他にEncoder本体とノブをアクセサリの中から選定して調達する必要があります。Mike OMと同じ構成を選定しました。EncoderはRGB LEDを内蔵した透明シャフトの「RGB Encoder」とし、ノブは専用の透明リングを備えたΦ22.2mmの「Aluminum black knob」を選定しました。選択可能なノブの中では最大径です。マイコン(PIC16F18345)のGPIOを使用してリングを調光し、HMI(Human Machine Interface)の一翼を担わせることができます。

DUPPA I2C Encoder.

Keiths' SDRのEncoder周辺ソフトウェアの調査

割込みとポーリング

EncoderのカウントUp/Downの取りこぼしを防ぐために、当初はパルス発生による割込みを利用していると思い込んでいました。VFO周波数がスムースに変化しないとストレスになるからです。

しかし、ソフトウェアを精査したところ、「I2C Encoder V2」のエッジマイコン(PIC16F18345)は割込みを利用してカウントしていると想定していますが、Teensyは割込みを受け付ける設定ではなく「I2C Encoder V2」からの割込み信号線のH/Lレベルをポーリングしていることが分かりました。信号処理連鎖をサンプリング周波数で正確に起動するDMA割込みが最優先となるため、複雑な多重割込みを避けているものと思われます。

I2C Encoderを使う限りは、エッジマイコンが専業でカウントするため、取りこぼしは発生しないと期待されます。シングルコアのTeensyに対してエッジマイコンがサポートしている格好です。

Block diagram of I2C encoder connection.

Encoder周辺ソフトウェア

Keiths' SDRのEncoderに係わるソフトウェアは以下の3階層から成ります。

  • (1)SDRアプリのメインプログラム{SDR_RA8875.ino}
  • (2)SDRアプリのI2C Encoderモジュール{SDR_I2C_Encoder.cpp}
  • (3)DUPPA提供I2C Encoderファームウェア{i2cEncoderLibV2.cpp}

Keiths' SDR software related to Encoder.

DUPPA社が提供する(3)I2C Encoderファームウェアは、「I2C Encoder V2」ボードを抽象化するi2cEncoderLibV2クラスを提供しています。(1)SDRアプリのメインプログラム{SDR_RA8875.ino}では、このi2cEncoderLibV2クラスのオブジェクトを標準で2つ宣言しています。マルチファンクション用の「MF_ENC」と、サブの「ENC2」です。I2C接続のためEncoderの増設対応は容易であり、最大で「ENC6」までI2Cアドレスが予約され、オブジェクト宣言がコメントアウトされています。

複数のEncoderの役割はUser_Settings構造体変数で初期定義されており、「MF_ENC」の回転に対しては"MFTUNE"(周波数チューニング)を、プッシュボタンに対しては"RATE_BTN"(周波数チューニングステップ切換)を割り付けています。また、「ENC2」の回転に対しては"RFGAIN_BTN"(RFゲイン調整)を、プッシュボタンに対しては"MODE_BTN"(モード切換)を割り付けています。

(1)メインプログラムのsetup()関数でI2C Encoderの初期設定を行い、(2)I2C Encoderモジュール{SDR_I2C_Encoder.cpp}の初期設定関数set_I2CEncoders()をコールしています。呼び出された初期設定関数の中で、EncoderイベントとSDRアプリ側のcallback関数を紐付けています。具体的には、onChange(カウント増減)イベントに対してはencoder_rotated()関数を、onButtonRelease(プッシュボタン押下)イベントに対してはencoder_click()関数をそれぞれ紐付けています。

(1)メインプログラムのloop()関数で逐次に(2)I2C EncoderモジュールのCheck_Encoders()関数をコールして、I2C Encoderの割込線のポーリングを行います。複数のEncoderが同じ割込線を共有しているため、割込イベントを検知すると(3)I2C EncoderファームウェアのupdateStatus()関数をコールしてEncoder個体とイベント内容を調べます。例えば、onChange(カウント増減)イベントであれば初期設定でcallback関数として割り付けたencoder_rotated()アプリケーション関数がファームウェアからコールバックされます。

I2C Encoderの接続

I2C Encoderの組立

RGBエンコーダとXHコネクタ二式を「I2C Encoder V2」基板にはんだ付けするだけで組立は完了です。5x4=20個の端子を圧着する配線材の製作の方が大変でした。

ノブはRGBエンコーダの平目ローレット軸に圧入するだけです。ラジアル方向全周に均一にLED光を配光する透明軸なので、ネジ止め式のノブは付けられない仕様です。RGBエンコーダには専用ノブが必要なため、DUPPA発注時に忘れないようにする必要があります。

I2C Encoders from Corso Sebastopoli, Torino, Italy, with assembly completed.

4方向のエッジのピン配置は点対称(180度回転対称)ではなく線対称(折り返し対称)です。これは対抗する上下(あるいは左右)のコネクタ同士が同じピン配置になるようにする措置です。XHコネクタをはんだ付けすると、シルク印刷の信号名が見えなくなるため、データシートで確認しながら配線を行う必要があります。見えている隣のエッジの信号名を頭の中で90度回転させてはいけません。「DuPPa.net」のコーナー印字が回転方向の目印です。

I2C address setting by jumper pins.

I2Cアドレスは7bitsのジャンパーピンをはんだでショートさせて設定します。ハードウェアの設定とソフトウェアの設定が整合していれば問題ないのですが、Mike OMの設定に倣いました。「MF_ENC」が0x61、「ENC2」が0x62です。

5-wire connection between the Teensy Backpack board and the I2C encoders.

Teensy Backpackボードのコネクタの信号配置は「I2C Encoder V2」のそれとは異なるため注意が必要です。Teensy Backpackボードのコネクタは「G-SCL-SDA-INT-5V」の配置です。他方、「I2C Encoder V2」のコネクタは「INT-SCL-SDA-5V-G」の配置です。線材を色分けした方が安全です。耐熱電子ワイヤAWG24(7色)から5色を用いました。

I2C Encoderのテスト

「I2C Encoder V2」側コネクタの電源電圧確認を行った後、「I2C Encoder V2」を接続してKeiths' SDRを起動しました。

Keith' SDR with I2C Encoders connected starts successfully.

Serialメッセージには、設定したアドレスのI2C Encoderが2式見つかった旨の報告がありました。

In the Serial message, the I2C scanner reports the discovery of two I2C Encoders.

問題なく2式のI2C Encoderが動作していることを確認しました。"MFTUNE"(周波数チューニング)の機能を割り付けた「MF_ENC」の回転に対してVFO周波数が連動して変化することが確認できました。"RATE_BTN"(周波数チューニングステップ切換)の機能を割り付けたプッシュボタンでステップ切換が動作しました。

また、"RFGAIN_BTN"(RFゲイン調整)の機能を割り付けた「ENC2」の回転に対してRFゲインの切換えがSメータに表示されることを確認しました。"MODE_BTN"(モード切換)の機能を割り付けたプッシュボタンでモードが切り変わることも確認できました。Encoderの回転デテント毎にLEDが緑色に発光して自然にフェードします。上下限値に到達すると赤色に発光しフェードします。

パルスの取りこぼしを評価するために、手首のスナップを効かせて一気に「MF_ENC」を回転させてみました。期待に反して、取りこぼしが発生することが分かりました。

「I2C Encoder V2」の特徴として以下の数値がDUPPAのホームページに掲載されています。

Maximum A/B signal frequency: 100Hz (Tested)

24 pulses for rotations

最大パルス周波数100Hz、1回転のパルス数24から、カウント可能な最大回転速度は250rpm(4.2r/s、0.24s/r)になります。いくらスナップを効かせても、これほど高速に回転できているとは思えません。

「I2C Encoder V2」のデータシートによれば、割込み発生後にエッジマイコン(PIC16F18345)の ESTATUS(Encoder Status?)レジスタをTeensyが読まないと、割込線のH/Lレベルがリセットされないとのこと。割込がリセットされないとエッジマイコンのカウントもストップすると考えれば、パルスの取りこぼし発生も妥当です。この仮説が正しければ、結局のところパルスの取りこぼしの有無はTeensyが実行するloop()関数の反復頻度に依存することになります。Encoder専用のエッジマイコンを配置しているのにもったいない気がします。

デテント付きのRGBエンコーダを高速に回転させることはないと思いますが、光学式エンコーダに代えた際にパルスの取りこぼしがどうなるか興味のあるところです。これは将来の課題です。