トランスバータ用CI-V周波数変換
自作工程のメモとして
02.May.2018
2018/11/23:更新
最初のもの(改善前)
次項に有る回路の内、抵抗とダイオードをそれぞれ1本使うだけで、その他は組込み先の回路を流用しています。
STM32F103で改善したもの
2018/11/23:Arduino NanoからSTM32F103に変更しました。
Edit by bluegriffon3.0.1
1.回路図 |
2.スケッチ(ソースプログラム) |
// 2018/04/30 /* IC-7600+144M トランスバータ(TRV)対応用のCI-V(周波数データ)変換 例)ハムログ等では、TRV使用を前提とした周波数加減算用の設定は有るが、 MMVARIでは、その変換が無い。 そのため、PCが受信する周波数データのみ+116MHz加算したCI-Vデータに変換する。 参考:Arduino 日本語リファレンス の ソフトウェアシリアルのサンプルコード */ #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); // SoftRX Pin, SoftTX Pin int state = 0; byte rxchar; int trvON = 0; void setup() { Serial.begin(19200); // ハードウェアシリアルを準備 mySerial.begin(9600); // ソフトウェアシリアルの初期化 } void loop() { // if (mySerial.available()) Serial.write(mySerial.read()); // この行を以下のように変更する。 if (mySerial.available()) { rxchar = mySerial.read(); switch (state) { case 10: state = 0; break; case 9: if ((trvON == 1) && (rxchar == 0x00)) rxchar = 0x01; state++; break; case 8: if ((rxchar >= 0x28) && (rxchar <= 0x29)) { rxchar = rxchar + 28; trvON = 1; } else { trvON = 0; } state++; break; case 7: case 6: case 5: case 3: case 2: state++; break; case 4: if ((rxchar == 0x00) || (rxchar == 0x03)) // 5Byte目のコマンド00 or 03 のみ // stateをカウントUP { state++; } else { state = 0; } break; case 1: case 0: if (rxchar == 0xfe) { state++; } else { state = 0; } break; } if (rxchar == 0xfd) state = 0; Serial.write(rxchar ); } if (Serial.available()) mySerial.write(Serial.read()); } |
3.ケースへの実装 |
9.その他気づいたこと |
99.STM32F103による改善(2018/11/23) |
上記のArduino Nanoを使ったCI-V信号の変換では、RIGからの周波数データを受け取るだけなら問題が無いようでしたが、PC側から送出中のCI-V信号の受信がSoftwareSerialではできず、大幅な文字化け・欠落が起きていました。
また、USBケーブルを外しているときにCI-Vの信号ラインが1.3V程度に引き落とされていることが分かりました。
そこで、ほとんど使わないような機能かも知れませんが、2ch以上のUSARTを持つCPUを探して作り直すことにしました。
(1)CPU検討
Arduino系ではUSARTを2ch持っているのはDUE・MEGAしか思い当たりません。
しかし、簡単な処理にそこまでの物を使うことも大げさですし、Arduino Nanoを使った収納サイズの制約が有りますので、同程度のサイズであるSTM32F103を採用することにしました。
/* * 2018/10/04 * STM32F103C8T6 ARM Cortex-M3 CPU 72MH 用 * Arduino IDE のボード設定 * =========================================== * ボード:"Generic STM32F103C series" * Variant:"STM32F103C((20k RAM,64k flash" * CPU Speed(MHz):72MHz(Normal * Upload method:STM32duino bootloader" * Optimize:"Smallest(default)" * シリアルポート:"COM10(Maple Mini)" * ============================================ */ #define LED_PIN PC13 // PC13 or 32 or D32 int RDposi = 0; int PCposi = 0; byte RDchar, PCchar; int RDtrvON = 0; int RDfreqDATA = 0; int PCtrvON = 0; int PCfreqDATA = 0; const byte RealRadio = 0x7A; // ◆◆実際のCI-Vアドレス IC-7600 const byte VirtRadio = 0x60; // ◆◆仮想のCI-Vアドレス IC-910 void setup() { pinMode(LED_PIN, OUTPUT); Serial1.begin(19200); // ハードウェアシリアル1(PC側) // while (!Serial) delay(50); // STM32 USB-シリアル用 書込み後のUSBシリアルの解放を待つ。 Serial3.begin(9600); // ハードウェアシリアル3(Radio側) digitalWrite(LED_PIN, LOW); delay(50); digitalWrite(LED_PIN, HIGH); } void loop() { if (Serial3.available()) { // ■■■■Radio(RD)からPCに向かってのCI-V信号処理■■■■ RDchar = Serial3.read(); if (RDchar == 0xfd) { RDtrvON = 0; RDfreqDATA = 0; RDposi = 0; } else { switch (RDposi) { case 9: if ((RDtrvON == 1) && (RDchar == 0x00)) RDchar = 0x01; RDposi++; break; case 8: if ((RDfreqDATA == 1) && (RDchar >= 0x28) && (RDchar <= 0x29)) { RDchar = RDchar + 28; // (0x28=40) + 28 = (68=0x44) RDtrvON = 1; } else { RDtrvON = 0; } RDposi++; break; case 4: if ((RDchar == 0x00) || (RDchar == 0x03) || (RDchar == 0x05) ) // 5Byte目のコマンド00 or 03 のみ RDfreqDATA = 1; else RDfreqDATA = 0; RDposi++; break; case 3: if (RDchar == RealRadio) // IC-7600からの信号なら { RDchar = VirtRadio; // 仮想の機種に変換 } RDposi++; break; case 2: if (RDchar == RealRadio) // PCから送出した信号のエコーバック(CI-V折り返し信号) { RDchar = VirtRadio; // 仮想の機種に変換 } RDposi++; break; case 1: case 0: if (RDchar == 0xfe) { RDposi++; } else { RDposi = 0; } break; default: RDposi++; break; } } Serial1.write(RDchar ); } if (Serial1.available()) { // ■■■■パソコン(PC)からRADIOに向かってのCI-V信号処理■■■■ PCchar = Serial1.read(); if (PCchar == 0xfd) { PCtrvON = 0; PCfreqDATA = 0; PCposi = 0; } else { switch (PCposi) { case 9: if ((PCtrvON == 1) && (PCchar == 0x01)) PCchar = 0x00; PCposi++; break; case 8: if ((PCfreqDATA == 1) && (PCchar >= 0x44) && (PCchar <= 0x45)) { PCchar = PCchar - 28; // (0x44=68) - 28 = (40=0x28) PCtrvON = 1; } else { PCtrvON = 0; } PCposi++; break; case 4: if ((PCchar == 0x00) || (PCchar == 0x03) || (PCchar == 0x05) ) // 5Byte目のコマンド00 or 03 のみ PCfreqDATA = 1; else PCfreqDATA = 0; PCposi++; break; case 2: if (PCchar == VirtRadio) // 仮想の機種向けの信号なら { PCchar = RealRadio; // IC-7600へ変換してRADIO側へ送信する } PCposi++; break; case 1: case 0: if (PCchar == 0xfe) { PCposi++; } else { PCposi = 0; } break; default: PCposi++; break; } } Serial3.write(PCchar ); } } |