« 2015年7月 | メイン | 2015年9月 »

2015年8月16日 (日)

細々と改善は続く

カテゴリ:オートアンテナチューナー(ATU)の製作

8月の初めに誘導雷を受けて、自作のATUが動かなくなりました。 チューニングスタートをさせても、すぐにエラーで止まってしまいます。 一応、誘導雷くらいなら、マイコン本体のi/oが壊れる前に、その周辺のパーツが壊れるという設計をしていました。 調べてみると、周波数カウンターが動作せず、RF信号はOKなのに、周波数が範囲外となり、エラーを出しているものでした。 故障個所はカウンター回路の入力にあるチップコンデンサの電極が高電圧の為割れており、コンデンサの役目をしていないのが原因です。 この50V耐圧のチップコンデンサを交換したら直ってしまいました。

Atuk1_2

せっかく、ベランダのBOXから取り外したので、かねてより温めておいた改善事項を盛り込む事にしました。

ひとつは、バリコンの可変範囲が広すぎますので、これを若干狭くする為、以前手配しておいた6000V 390PFというコンデンサをバリコンに直列に挿入する変更です。 3.5MHzでのコイルインダクターを増やすのが面倒なので、入力側のみ追加し、様子を見る事にします。

二つ目は、マイコンのソフトです。 SWR最少位置を探す途中で、次の動作に行くために、数10ミリ秒から数100ミリ秒の待ち時間がありました。 また、プリセット位置にバリコンを移動させるには数秒かかる事もありましたが、これらの待ち時間中は、単純に動作が終わるのを待っているだけで、この待ち時間中にSWRが1.5以下になる事があっても、無視されていました。 今回、この全ての待ち時間中でもSWRを常にチェックし、SWRが3以下ならただちにSWR収束動作へ移るよう変更する事にしました。

ここで、問題が発生です。

LCD表示のアンテナアナライザーを開発する為、PICの開発環境をMPLAB X IDEに変更しましたが、ATUの開発環境は旧MPLABとHi-TECH Cでしたので、この旧MPLABを呼び出しPICKIT3を経由して、プログラムの書き換える事にしました。 ところが、IDが違うとエラーがでます。 困りはてて、色々試しましたが、うまくいきません。  さんざん悩んだ末、MPLAB X IDEでプロジェクトを作り直し、なおかつ、HI-TECH Cで書かれていたソースファイルをXC8用に書き換えると、ちゃんと16F1939を認識して、プログラムの書き換えが出来ました。

さらにプルダウンメニューなどを調べていると、MPLAB XでもHI-TECH Cコンパイラも使えるようです。 結局判った事は、MPLAB Xをインストールした後は旧MPLABは使えないという事でした。

やっと、プログラムの改善ができましたので、21MHzだけですが、オートチューニングを試す事にしました。 以前はバリコンがいったりきたりして、なかなかSWR収束モードにならず、その内、VC maxの位置に収まってしまいSWRが3以下になりませんでした。 やむなく、ハンドでSWRが1.5以下になるようにバリコン角度やコイルのタップ番号を選択した後、収束動作をさせていました。  ところが、今回は1発でSWR1.4くらいまで収束し、再度チューニングさせるとSWR1.05まで収束します。

後日、3.5から28まで全バンド、チューニング出来る事を確認しました。 ただし、28MHzのみですが、SWR1.4以下になるまで、かなり時間がかかるようになりました。 このバンドでチューニング動作を見ていると、1回で送るVCの角度が小さすぎるようです。 ソフトの変更で改善出来そうですが、すでにコンテナBOXに収めてしまいましたので、 次回のチャンスの時、変更する事にします。 この時間のかかる問題は最初のチューニング動作のみで、一度プリセットされてしまうと、次回からは、短時間で整合状態になりますので、実用上の不都合は有りません。

2016年11月3日

LDGのATUのマイコンを改造する為に、このATUのソースコードを調べていましたら、ソフトにバグがある事が判りました。 バグの内容は、ある条件の基ではモーターが反転しないというものです。 これが為に、なかなか整合しないバンドが発生しているようです。 このバグ対策を行った結果、全バンドがかなり早く収束するようになりました。ただし、24MHz以上のバンドでなかなか収束しないのは変わりません。そこで、前回追加しました、バリコンに直列の390PFを廃止しました。

バグ対策を行った後、外付けのSWR計ではSWR1.1以下になるのに、TUNE OKにならない場面が増えてきました。 この原因を調べてみると、モーターにブレーキをかけた後、まだ、バリコンが動いている最中に、SWRをチェックしているというバグが見つかりました。 ここは、50msecのディレー時間を設けて対策しました。 さらに、SWR3以下の時のモーター駆動時間をSWR3以上のときの1/2にし、さらにSWR1.5以下の場合さらに1/2にしていたのですが、SWR1.5から3の期間のモーターON時間が長すぎて、SWRディップポイントを通り過ぎてしまうのが原因でした。 そこで、SWRによりモーターON時間をさらに細分化し、以下のように設定しました。

SWR10以上     200msec

SWR10-5       100msec

SWR5-3        67msec

SWR3-1.5       40msec

SWR1.5以下      33msec

これで、ディップ点を飛び越える確率が大幅に減少した上、収束時間も短くなりました。

最新回路図 ATU-VC11.pdfをダウンロード

バリコン式ではなく、コイルとコンデンサをリレーで切り替えるタイプのATUの例はこちらでPICのソースを含めて公開しています。

2018年1月

プリセットMTUも継時変化が激しく、3.5MHz帯はMTUの調整範囲を超えてしまい、最近はこのATUだけで運用しています。 ただし、他のバンドではATUは使いません。 いくらチューニングを早くしてもプリセットMTUにはかないません。

INDEXに戻る

2015年8月14日 (金)

PIC24FJ128GB106 データメモリー不足

<カテゴリー:PICマイコン

TFT LCDにグラフィックや文字を表示させていますが、メモリー容量を64Kから128Kに替えた為、新たにフォントを追加する事にしました。 フォント作成アプリで大文字、小文字、数字、記号などを作り終え、これをincludeファイルにして、コンパイルすると、エラーになります。  出てくるコメントはリンカーエラーとの事で、メモリーが不足しているような内容です。

これらのエラーコメントを頼りにインターネット内で検索すると、Microchip(USA)のFAQページにメモリーを拡張しなければデータサイズは32Kまでと言う説明が見つかりました。 ただし、どうすれば、32K以上のデータメモリーを使えるのかは、やりとりが英文である事もあって、良くわかりません。

そこで、日本語の情報を探すと、データメモリーが32Kまでで制限されている事。 これを32K以上に拡張する為には、レジスターの設定やアドレッシングなど、変更する必要は判りましたが、肝心なXC16による記述方法が良く判りません。

結局、インターネットから探しだした、以下の記述でコンパイラーがエラーを出さなくなり、ちゃんと文字の表示が可能になりました。

コンパイルエラーになった記述例

const unsigned char Font7_space[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };//ASCII 32
const unsigned char Font7_sharp[] = { 0xb, 0xa, 0xa, 0x3f, 0xa, 0x1a, 0x1a, 0x3f, 0x16, 0x16 };// ASCII 35

・・・・・・

・・・・・・

const unsigned char *Font7_table[] = {
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //ASCII 0-15

・・・・・

・・・・・

コンパイルエラーが無くなった記述例

__eds__ unsigned char Font7_space[] __attribute__((eds)) = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };//ASCII 32
__eds__ unsigned char Font7_sharp[] __attribute__((eds)) = { 0xb, 0xa, 0xa, 0x3f, 0xa, 0x1a, 0x1a, 0x3f, 0x16, 0x16 };// ASCII 35

・・・・・・

・・・・・・

__eds__ unsigned char *Font7_table[] __attribute__((eds)) = {
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //ASCII 0-15

・・・・・

・・・・・

Aafont7

左の[SWR ANALYZER]の文字が今回作成した10x6のフォントです。

文字を書き込むとき、フォントアドレスをポインターで指定しますが、このポインターの型宣言も下記のようにする必要がありました。

__eds__ unsigned char *fontptr;

INDEXに戻る

2015年8月 8日 (土)

アンテナアナライザーの製作(全機能組み込み)

<カテゴリ:アンテナアナライザー>

LCDドライバーのマイコンのROM容量が64Kをオーバーしそうになったので、ROM容量が128K品であるPIC24FJ128GB106に変更し、製作を継続してきましたが、正規の基板を使っていない事もあり、配線引き回しが多く、ノイズによる誤動作で苦労しました。 せめて両面高密度実装基板なら、こんな問題は起こらないのですが、そこは手作りの基板ゆえ、苦労が絶えません。 とりあえず、目標としたアンテナアナライザーの全機能を組み込む事ができました。 これから、実際に使ってみると、問題点も出るでしょうが、 アンテナアナライザーの製作の最終章です。

Aa50normal

Aa50cal

左上がノーマル状態、右上が校正モード時のLCD画面となります。

校正が完了した各ダミー抵抗によるADの出力値は赤色で表示されています。

校正は3.5MHzバンド付近のみで行い、他の周波数では行いません。 これは、センサー部分のブリッジからダミー抵抗まで約50mmあり、これが影響して周波数が高くなるに従い、検出されるRやXはもちろん、Zも変化するためです。

Aa50100dummy

ちなみに、100Ωのダミー抵抗(純抵抗)を接続し、Mコネクターの特性インピーダンスを仮に30Ωと置いて、周波数を可変した時の計算値は左の表のようになり、実際の値も、近い値を示します。 例えば、50MHzで100Ωのダミー抵抗による校正をするという事は、50MHzでZ=100にすることになり、実際値とは異なる数値になるからです。 従い、このアナライザーでは、3.5MHzにてZ=100と定義し、RとXはその時のSWR=2.0との関係より計算させるという方法を取っています。 そして、広帯域発振器の出力レベルを比較し、周波数により変化が有ればこれを補正する事にしました。

Aa5017m

Aa50fc_2

左上が私の18MHz用ループアンテナのSWR特性。 右上が今回追加した周波数カウンターモードの表示例です。

周波数カウンターは、WWVやWWVHで校正された基準周波数を入力して、内臓の周波数カウンターのゲート時間を正確に20m秒に調整する必要があります。 その時の外部基準信号をアンテナを接続するMコネクターから加える事にしましたが、この機能をそのまま、周波数カウンターとして使えるようにしました。 0dBmの信号で最高周波数110MHzくらいまでは100Hz単位で計測できます。 しかし、よくよく眺めると、SWR,ZやR,Xの表示がバラバラです。バラバラになるのは当然なのですが、見てくれは良く有りません。次回、変更のチャンスが有ったら、これらの表示が無効になるような対応を考えたいと思います。

一応、当初の目標としていた機能はすべて組み込み完了しましたが、ひとつだけ気になる問題があります。 18MHzのアンテナのSWR特性カーブの中の、SWR1.1付近で不自然にカーブがずれています。 この原因を詳しく調べると、この不自然な変化周波数を境にして右側はインピーダンスが50Ωより高くなっており、左側は50Ωより低くなっています。 SWRを換算するとき、50Ω以上の時と、50Ω以下の場合のSWRの換算方法が異なる為、この境目でSWRが一致しないという問題でした。 SWRが小さい状態でインピーダンスが50Ωを横切った場合、あまり目立ちませんが、SWRが大きい状態でインピーダンスが50Ωを横切ると、完全に段差が生じます。

このインピーダンスにより、換算値に誤差が出る原因は、SWRメーターとアンテナのリアクタンスの関係 の記事で触れたように、リアクタンスが含まれた時の計測誤差が影響しておりました。

Aa50swr0

Aa50swr1

Aa50swr2

上の画像は28MHzのCW運用バンドに合わせたループアンテナのSWR特性です。 

 左の画像が、インピーダンス50Ωを境に、高い時と、低いときでSWR換算方法を使い分けたものです。 50Ωを横切る周波数が2か所ある為、2か所で段差が生じています。

真ん中の画像は、換算方式を通常のSWR計と同じ方法にしたものです。段差が無くなった代わりに、中心周波数より離れた周波数で、SWRが低く表示されています。

右側の画像は、インピーダンスが全て50Ω以下と想定して、換算させたSWR特性です。

どの、画像も、SWRが1.5を超えたら、それぞれ誤差が大きくなり、特にSWR2以上の場合、いずれも、正確なSWRは表示していません。 アンテナ調整を行う時、悪いSWRが良く出る率が小さい方がましですので、このアナライザーは一番右の特性になる方式でいきたいのですが、SWR2.0の校正を100Ωでやっている関係で、一番右の換算方法では100Ω時のSWRが校正されません。 25Ωの抵抗で校正すれば、OKなのですが、世の中のアンテナアナライザーのほとんどが100Ωで校正されていますので、25Ωで校正した場合、比較したとき誤差が大きくなりそうです。 従い、このアナライザーも一般のアンテナアナライザーやSWR計と同じ校正方法となる真ん中の方式でいく事にします。

また、この製作の発端となったLCD表示のアナログメーターの動きも、大きな違和感なしで共振周波数を探る事が出来ます。  指針の動く速さを改善する手段として新たに、指針移動角度に応じて書き換える範囲を可変する事にしました。 指針が移動するとき、旧指針を消して、新しい位置に指針を書き込む必要がありますが、これを1回の書き換えで実現する為に、新指針のエリアより上下左右の広い範囲に目盛の再書き込みを行い、この操作で旧指針を消していました。 しかし、指針が2度の角度で移動するとき、左右で9ピクセル分の目盛データを上書きする必要がありました。  そこで、指針の移動角度小さいときは、それなりにカバーする範囲を小さくし、最少角の0.25度の時は、左右で3ピクセル分のみカバーさせる事にしました。 さらに、このカバーエリアの拡大は、指針が右へ動く時は、左側だけ、左に動く時は右側のみとして、書き換えるエリアの面積を常に必要最小限とする事により、 クラニシのアンテナアナライザーのメカニカルメーターと同等の速度まで改善する事ができました。

指針が0.25度動いたときの最大移動ピクセルは約0.7です。 0.7ピクセルは実在しませんので、実際は1ピクセル移動します。 従い、進行方向はゼロピクセル、後方は1ピクセルだけ再描画すれば旧指針は消えるのですが、実際は、ADの変換値がチラチラとばらつきますので、そのバラツキをカバーする為に、進行方向は1ピクセル、後方はさらに1ピクセルの2ピクセル分だけ再描画が必要です。さらに、0.5度間隔から0.25度間隔に変更した時点では、0.5度分のピクセルが残っていますので、これを吸収する為、さらに後方に1ピクセル分の再描画エリアを確保する必要がありました。  このアルゴリズムでプログラムを組んで様子を見ていますが、時々旧指針が消えずに残る時があります。 旧指針の範囲を指針が移動するまで残ります。 ただし、この異常現象は、バグ対策を行うほどに頻度が小さくなっていくようです。

各ADの出力値は温度や周波数でわずかに変化します。このわずかな変化を検知して、出力されたADデータ値を補正します。 この補正プログラムも組み込みましたが、過酷な温度試験は実施していません。 たちまちは、気温差が10度くらいで100Ωの指示誤差が+/-1Ω程度になるように、補正係数を調整しました。

今後、実用テストが出来るようにケースに収納した上で、デバッグを継続する事にします。

ROM容量が64Kをオーバーするかも知れないと、マイコンを128K品に交換しましたので、少しでも視認性を上げるべく、フォントを新作して、組み込む事にしました。 ところが、データエリアが32Kを超えたとたん、コンパイラーがエラーを吐きます。 なんとか対策できましたが、完成度はなかなか上がりません。

最新回路図をダウンロード

完成度はあがりませんが、せっかく実現した周波数対SWRのカーブをPCに転送してPCの画面上にグラフを描かせる事にトライする事にしました。 たちまちは予備検討です。

この記事でアンテナアナライザ製作を終了する予定でしたが、色々と問題点や改善テーマが出てきて、終了できませんでした。 しばらくは製作記事が継続します。

SWRグラフをSDカードへセーブ へ続く。

アンテナアナライザーの製作を最初のページから参照したい場合ここからどうぞ。

INDEXに戻る

2015年8月 3日 (月)

PIC24FJシリーズ SPI 誤動作

<カテゴリー:PICマイコン

アンテナアナライザーのLCDドライブ用に使用していたPIC24FJ64GA004のROMエリアがほぼフルになりましたので、128Kに換える事にしました。 選んだマイコンは、将来USB機能やSDカードを組み込むかも知れないとの考えから、PIC24FJ128GB106という品番のICにしました。 

Aa59pic24fj128gb106

左の画像が、128Kの64pin TQPF品に入れ替えた実装基板です。 変換基板の大きさが、44pinのときより小さくなっている関係で、以外とすっきり配線できました。

回路図的には、44pinの時と同じ構成で、一部i/oの割り当てを変更しただけで、さっそく動作確認です。 ところが、LCDの表示は問題なく表示されますが、コントロールマイコンとの通信がうまくいきません。 周波数表示はでたらめで時々暴走します。 UART通信のプログラムが異常なのかと、色々試しましたがうまくいきません。 じたばたしている内に、通信もうまくいかないのに、さらに、26バイトの伝送に15m秒くらいかかっている事が判り、LCDの表示速度も遅くなっている事に気付きました。 ボーレート38.4Kでは不足みたいです。 56K以上にアップする案もありましたが、 キー入力をADに変更して、ラッチアップの対策もできましたので、残りのUP,DOWNのキーもADに変更する事によりi/oポートが2本余ります。 この際、通信方式もi/o 1本のUARTからi/o 3本のSPIへ変更する事にしました。

しかし、これが、またまた、訳の判らない誤動作に悩まされる事になってしまいました。

時々、伝送に成功しますが、一度リセットをかけると、伝送データがでたらめになります。 約2週間悩んだ末、判った結論は、またまた、伝送路のリンギングによるマイコンのラッチアップでした。 ただし、ラッチアップの影響が小さい為、時々まともに動作するのは、プログラムの性ではないかと、ああでもない、こうでもないとやっていたのがいけなかったようです。 ふと、ハードが原因ではないかと、SPIのクロックやデータの波形をチェックしてみました。

Aa59spi0

Aa59spi1

上の画像は左が対策前の、クロック(下)とデータ(上)です。 右の画像は対策後の波形です。 対策前は、クロックにも、データにもリンギングのオーバーシュートやアンダーシュートが発生し、いずれも時々0.5Vを超えています。 これが伝送データがでたらめになる原因でした。 対策内容は、各ラインに1KΩの直列抵抗を挿入し、リンギングの発生をおさえますが、抵抗だけでは不十分でしたので、GNDとの間に68Pのコンデンサも追加しました。 波形がきれいになって暴走の確率はかなり減少しました。 

しかし、時々、電源ON直後に暴走します。 ただ、基板のGNDラインを指でつかむとか、オシロのGND端子へ接続すると完璧に直ります。 このような症状の原因はノイズです。 ふたつのマイコンのうち、どちらで暴走しているか確認したところ、コントロール側の24FV32KA302が暴走しています。 さらに、このマイコンの入力関係をひとつづつ殺して確かめても暴走するときは暴走します。 最後にたどりついたところはMCLR端子でした。 この部分についてデータシートを再確認したところ、推奨回路はMCLR端子にシリーズに100から470Ωを入れろと書かれていますが、8bit時の延長で抵抗は入れてありませんでした。 そこで、470Ωを追加し、10回くらいのPOWER ON/OFFでは暴走が起こらない事を確認できました。 しかし、頻度は少ないですが、たまに誤動作します。 このマイコンのデータシートには、さらに0.1μFでGNDへ落とせと書いてあります。  さっそく0.1μFのコンデンサを追加したところ暴走が起こらなくなりました。 しかし、PICKIT3の説明書では、MCLRラインにコンデンサを接続するなと書いてあります。 試にこのラインに0.1μFを接続したままで、フラッシュメモリーの書き換えを行ってみましたが、問題なく書き換えが出来ました。 もし、書き換えがうまくいかない時は、コンデンサを外し、アナライザーが完成したら、コンデンサを追加する事にして、コンデンサは追加したままにしています。

LCDドライブ用の24FJ128GB106のMCLRラインにはまだシリーズ抵抗は入っていませんので、抵抗だけは追加する事にしました。

対策済回路図をダウンロード

Aa59_spi2

このSPI通信は、PIC24FV32KA302をマスターとして、PIC24FJ128GB106をスレーブとした一方通行のシリアル通信です。 クロックは約156KHzとし、マスター側はワード(16bit)伝送で割込みなし、全17ワードを連続送信し、その間、CEとしてLの信号を送ります。 スレーブ側は、CE信号がLになったらこれを割込みで捉え、受信バッファのインデックスを0にした後、1ワード受信する度に割込みを発生させ、17ワードのデータをバッファにストアさせます。 CE信号を送ったり、CEを受けてインデックスを0にする動作以外、すべて、データシートにかかれた説明通りの設定です。 

上の画像は、下のパルスがSPIのクロック(SCK)で、上のパルスが受信割込みが発生したときのダミー信号です。 1ワード受信する度に割込みが発生し、先頭ワードのインデックスを0番として順次17ワードを受信バッファに格納していきます。

送信側のPIC24FV32KA302のmain内の初期設定と送信ファンクションは以下です。

main () {

・・・・・・・・・

SPI1CON1 = 0b0000011000111100;//マスターモード クロック1/64
SPI1CON2 = 0b0000000000000000;
SPI1STATbits.SPIROV = 0;
SPI1STATbits.SPIEN = 1;//SPI1有効化

・・・・・・・・・・・・・

送信処理

void sendDATA() {
    unsigned char i;
    SPIFlg = 0;//CE信号をL
     __delay_us(20);
    for (i=0;i <17;i++) {
        while(SPI1STATbits.SPITBF);
        SPI1BUF = TXData[i];
        }
     SPIFlg = 1;//CEをH
}

受信側PIC24FJ128GB106の初期設定と受信割込みルーチン

main() {

・・・・・・・・・・・・・・・

RPINR0bits.INT1R = 21;//INT1をRP21に割り当て(RG6)
 RPINR20bits.SCK1R = 26;//SCK1INをRP26に割り当て(RG7)
 RPINR20bits.SDI1R = 19;//SS1INをRP19に割り当て(RG8)
 SPI1BUF = 0x0;//SPIバッファークリアー
 IFS0bits.SPI1IF = 0;//SPI割込みフラグクリアー
 IEC0bits.SPI1IE = 1;//SPI割込み有効
 IPC2bits.SPI1IP = 3;//SPI割込み優先レベル3
 SPI1CON1 = 0b000011000000000;//SDO使用せず。スレーブモード
 SPI1CON2 = 0b000000000000000;//フレーム未使用
 SPI1STATbits.SISEL = 1;
 SPI1STATbits.SPIEN = 1;//SPI1有効化
 INTCON1 = 0b000000000000000;
 INTCON2 = 0b000000000000010;//INT1 ネガティブエッジ
 IFS1bits.INT1IF = 0;// INT1 割込みフラグクリアー
 IEC1bits.INT1IE =1;//INT1割込み許可
 IPC5bits.INT1IP = 3;//INT1割込み優先レベル3

 ・・・・・・・・・・・・・

CE割込み処理

void __attribute__((interrupt, no_auto_psv)) _INT1Interrupt(void) {
    IFS1bits.INT1IF = 0; //割り込みフラグ解除
    RXindex = 0;
}

SPI受信割込み処理

void __attribute__((interrupt, no_auto_psv)) _SPI1Interrupt(void) {
    unsigned int i;
 //    LED=1;
    IEC0bits.SPI1IE = 0;//受信割込み禁止
    IFS0bits.SPI1IF = 0; //受信割り込みフラグ解除
    i = SPI1BUF;
    RXdata[RXindex] = i;
    RXindex++;
    if (RXindex > 16) {
       RXreadyflag = 1;//全データ受信完了フラグ
       RXindex = 0;
       }
   IEC0bits.SPI1IE = 1;//受信割込み許可
//      LED=0;
}

INDEXに戻る