SD330の自動チューニング ― 2015年08月23日 11:23
はじめにお読みください。→当サイトのリンクと免責事項
HAM、BCL用に第一電波のSD330を導入しました。ブロードバンドアンテナと違って同調型なので多少でも感度がいいかなと考え購入しました。以前からΔLoopXを使っていましたが私のベランダでは断然同調型のほうが感度、雑音など優れていました。狭いベランダに多くのアンテナは立てられないのでこの際、整理しHFはSD3301本で行くことになりました。
夜の31mbを聞こうとしますが一体どこで同調しているか良くわかりません。一番強く聞こえるところが同調点さと割り切ればいいのですが、長年システムを触ってくると何かしっくりきません。ハムバンドはSWR計で分かりますが私のRigは最低5Wです。いくらなんでもCQを出している周波数でSWRを測るのは気が引けます。みなさんどうされいるのでしょうか。
そんなことなでWebサイトを調べるとアンテナアナライザで共振点を探し出して、その後切り替えて運用しているようです。SD330専用の自動同調器もありましたが現在販売されていません。自作サイトもありましたが結構お金がかかりそうです。
ATAS-120でも良かったのですがRigをCATでコントロールしている都合上、同調ボタンに該当するCATコマンドがないためSD330との2択となりました。
そこで簡単に、リモートで自動同調できないか検討した結果、アンテナアナライザほどの機能は必要ないのでディップ点のみ検出しモータを停止できれば良い回路としました。ほとんど手持ち部品で済ませましたが一番高い部品は中華DDSでした。とりあえずハードが完成です。
回路図です。目的はアンテナのディップ点さえ分かれば良いので精度や大きさなど度外視しました。
信号源に中華DDS9850を使用、検出には50ΩのブリッジからAD8307でdB化します。モーター制御はMPUのPWM制御を利用しています。またアンテナ切り替えリレーを付け同調時Rigからこちらに切り替えます。
中華DDSはAmazonで1500円くらいでした。フィルターは取り外し外付けにします。その代わりにAD9851のデータシートに載っていた差動DAC出力を取り出すトランスを乗せます。ただしフィルターを2重に終端しています。
MPUは使い慣れたR8CシリーズからRAMの一番大きいものを選びました。R8C/38はRAMが10K ありますので8000点くらいのデータは保存できます。PCとの通信はいつもの通りシリアル非同期通信です。秋月電子で扱っているAE-FT234Xが3Mまでの通信速度をサポートしています。そこでWindows側で簡単に最速通信ができることを考えボーレートは 921600としました。クロックはその16倍の14.7456MHzです。本当はUSBでパケットを直接コントロールしバルクIN転送でPC画面上に表示できれば最高なのですが、体力、気力がありません。おそらくVB.NETでSerialportクラスを使ってごまかすこととなるでしょう。せめてWin32APIでも使えば気がきいたソフトになるとは思いますが。
モータ制御はR8C/38のRGタイマーを使っています。出力が1CHであること、制御が簡単であることからRGとします。ただし方向制御(CW/CCW)は別に行う必要があり簡単なロジックを付加しています。
アナログ基盤にはアンプを載せていましたがAD9850の出力が大きいので取り外しました。
DDSの出力にLPFを入れますが30MHzで設計しほぼ期待通りのカーブとなりました。27MHzからは少しレベルが下がりますがソフトで補正します。
50Ωの抵抗はヤオフクの1206 size100 ohm 1%を使用しました。DUT端子はSMAの基盤タイプを秋月電子より購入し足を切ってSMD化します。アンテナ切り替えリレーは手持ちのオムロンG2R-2-Sに銅はくを巻いて使用しています。MAX30MHzなので問題ないと考えます。ソフトで切り替え完了を確認するため余った接点をMPUに入れています。
AD8307はSOP-8、1.27mmピッチなので1.27ピッチのユニバーサル基盤(片面)を使用し、半田面に部品を乗せ配線します。裏面は銅はくを張り付けます。そのためボルテージフォロワーもSOP-8、1.27mmピッチのNJM2732を採用します。このOPアンプの入出力に104が入っていますがこれが悪さしていてレスポンスに影響していると思われます。
電源部は手持ちのトランスがありましたので組み込みました。すべての電源のマイナスを共通にしたためモータードライバの出力はアンテナまで浮かす必要があります。コネクタは絶縁型のRCAコネクタを使用しました。うっかりモーターへの線をグランドに落とすと、方向(CW/CCW)によっては短絡状態となりTB6642の安全機能によって出力ゼロとなります。(DDSの出力をオシロで見ていて、PWMも同時に見たいと接続したのですが片側だけとんでもない波形でした。これに気付くのに半日かかりました。)
まず全体の絵です。部品はほとんど手持ちの物を使い回ししています。



フィルターはこちらのサイトにお世話になりました。
フィルターの測定結果です。
ブリッジの入力をオシロでみてプロットしてみました。
簡単なソフトで全体の特性を出しました。アンテナ端子がオープンのブリッジの出力です。
高い周波数のレベルの落ち込みはソフトで補正します。補正後です。
DDSの出力です。(ブリッジの入力) P-Pで0.495Vあります。上が5MHz下が10MHzです。
PWMの出力です。上がCW、下がCCWです。ともに20%です。
アンテナ端子に50オームのダミー抵抗を付けたときのブリッジの出力です。
期待していたほど良くないですね。リレーも影響しているかもしれません。一応ディップを見るには支障なさそうなので良しとします。
仮のアンテナで特性を取ってみました。アンテナはUHV-6で7MHz、14MHz、21MHZ、28MHzのエレメントが付いています。アースをしっかり取ってないのでこんなもんです。7Mhz付近の2つはゴースト?かもしれません。
このデータは100μSごとに周波数を変えています。AD変換の時間は6.7μSで前後のルーチンを入れても倍の14μSもあれば変換が完了します。周波数データの時間を10mS、1mS、500μS、100μS、でどう変わるか検証します。
10mS
1mS
500uS
100uS
時間をかけるとディップ点が深くなるのが分かります。使用環境で決めればよいでしょう。
次にデータのばらつきです。上がー8dB付近の時のばらつき、下がディップ点付近のばらつきです。
縦軸はAD変換値です。横軸は周波数です。上の図は1KHzごとにデータを取得しています。デジタルですので1bitは誤差です。これを踏まえてどう平均化するか、またはどう最低点を検出するかソフトを考えなければなりません。
またSD330の取り扱い説明書には同調位置目安表なるものが付いています。これは長さと周波数の関係をプロットしたものです。何センチ動くと周波数はどのくらい変わるのか把握できないと不都合が生じます。それは同調点を検出できないとき最長端または最下端まで移動しさらに移動しようとします。最下端はリミットスイッチがあるので実害は少ないですが最長端はいつまでも回り続けます。これを防ぐにはタイマーで監視し一定の時間内に検出できないときは強制停止させます。このタイマー値を決めるのに先出の値が必要になります。いろいろやった結果長さと周波数の関数が出来上がりました。
y = 1E-06x6 - 0.0001x5 + 0.0058x4 - 0.1408x3 + 1.8991x2 - 13.637x + 44.541
xはMHz、yはcmです。ただし最低でも小数点以下10桁以上ないと誤差が大きくなります。MPUでは負担が大きすぎて実行できませんがPCなら可能です。PCで計算しMPUに答えだけを送る方法なら何とかなりそうです。またモーターの速度も必要ですがそれは実測して決めます。
ここまでのデータはAD変換8bitで周波数は100uSごとに更新しています。またMPUのAD変換用の基準電圧はNJM1431Aを使用しました。これにより2.465VがAD値255です。またAD8307のデータシートの電圧対dBmのグラフから
dBm = ((AD値/2.683) - 0.87 )-80
となります。( AD値は 0~255)
DDSの周波数の決め方はAD9850、AD9851のデータシートに詳しく記述されていますがMPUでは浮動小数点演算をきらいLong Integerで計算します。
fdata = freq(Mhz) * 34359738.36 at clock=125Mhz *34.35973836 =Hz (データシートより)
この式から小数部をなくし下記のように整数のみで算出します。今回の使用では十分です。
const unsigned long f100 = 3436; // 100Hzのかけ数 ex 400Hz = 4*f100
const unsigned long f1k = 34360; // 1kHzのかけ数 誤差+0.2652
const unsigned long f2k = 68719; // 2kHzのかけ数 誤差-0.4768
const unsigned long f5k = 171799; // 5kHzのかけ数 誤差+0.308
const unsigned long f10k = 343597; // 10kHzのかけ数
const unsigned long f100k = 3435974; // 100kHzのかけ数
const unsigned long f500k = 17179869; // 500kHzのかけ数
const unsigned long f1M = 34359738; // 1MHzのかけ数
const unsigned long f10M = 343597384; // 10MHzのかけ数
const unsigned long f1k = 34360; // 1kHzのかけ数 誤差+0.2652
const unsigned long f2k = 68719; // 2kHzのかけ数 誤差-0.4768
const unsigned long f5k = 171799; // 5kHzのかけ数 誤差+0.308
const unsigned long f10k = 343597; // 10kHzのかけ数
const unsigned long f100k = 3435974; // 100kHzのかけ数
const unsigned long f500k = 17179869; // 500kHzのかけ数
const unsigned long f1M = 34359738; // 1MHzのかけ数
const unsigned long f10M = 343597384; // 10MHzのかけ数
簡単にはkHzの値に34360を掛ければOKです。周波数のインクリメントも34360を足していきます。
今回は8bitパラレルにてデータを書き込みます。下記のfreq_dは上記の式で求めた32bitの周波数データです。
void DDS_DATA_PUTS(unsigned long freq_d)
{
// unsigned long lp;
DDS_DATA = 0x00;
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_DATA = freq_d >> 24;
{
// unsigned long lp;
DDS_DATA = 0x00;
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_DATA = freq_d >> 24;
////
asm("nop");
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_DATA = freq_d >> 16;
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_DATA = freq_d >> 8;
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_DATA = freq_d ;
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_FQUD = 1;
asm("nop");
DDS_FQUD = 0;
}
#define DDS_FQUD p0_5
#define DDS_RESET p0_6
#define DDS_WCLK p0_4
#define DDS_DATA p8
asm("nop");
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_DATA = freq_d >> 16;
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_DATA = freq_d >> 8;
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_DATA = freq_d ;
DDS_WCLK = 1;
asm("nop");
DDS_WCLK = 0;
DDS_FQUD = 1;
asm("nop");
DDS_FQUD = 0;
}
#define DDS_FQUD p0_5
#define DDS_RESET p0_6
#define DDS_WCLK p0_4
#define DDS_DATA p8
ただしリセット後の1回目だけはこのルーティンでは動きませんでした。上のルーティンの中の////のところに
for(lp=0;lp<1150;lp++){ asm("NOP");} を必要とします。
---------------------つづく予定-----------------------------------