リグエキスパートのAA-30.ZEROグラフ描画

Gnuplotを用いれば、簡単に素敵なグラフを描くことができます。

あなたのAA-30.ZEROからの生データはこんな感じです:

...
2.990000,15.066906,46.652055
3.000000,15.557470,48.099209
3.010000,16.004803,48.884680
...

そして、スクリプトは:

# Gnuplot script for AA-30.ZERO
reset
set terminal aqua enhanced title "AA-30.ZERO" size 1200 900
set datafile separator ","
set grid
unset key
set multiplot layout 2,2 title "My Dipole Antenna"

set title "Impedance (R, X, and Z)"
plot   "mydata.txt" using 1:2 with line linewidth 3, \
"mydata.txt" using 1:3 with line linewidth 3, \
"mydata.txt" using 1:( abs($2+$3*{0,1}) ) with line linewidth 3

set title "Return Loss"
plot "mydata.txt" using 1:( -20.0 * log(abs( ($2+$3*{0,1}-50)/($2+$3*{0,1}+50) )) / log(10) ) with line linewidth 3 linetype 4

set title "VSWR"
plot "mydata.txt" using 1:( (1+abs( ($2+$3*{0,1}-50)/($2+$3*{0,1}+50) )) / (1-abs( ($2+$3*{0,1}-50)/($2+$3*{0,1}+50) )) ) with line linewidth 3 linetype 7

set title "Smith Chart"
set polar
set grid polar
set size square
set xrange [-1:+1]
plot "mydata.txt" using (arg( ($2+$3*{0,1}-50)/($2+$3*{0,1}+50) )) : (abs( ($2+$3*{0,1}-50)/($2+$3*{0,1}+50) )) : (3*$1) with point pointtype 7 lc variable

unset multiplot

ターミナルタイプはあなたのプラットフォームに応じて設定して下さい。スクリプトの3行目を見て下さい。

そして、あなたがすることはこれだけです。

% ./aa30zero fq3500000 sw2000000 frx200 > mydata.txt
% gnuplot aa30zero.plt

リグエキスパートのAA-30.ZEROシリアル通信プログラム

あなたのAA-30.ZEROを制御するための簡単なプログラムです。

/* Rig Expert AA-30.ZERO control via serial port */
/* file name = aa30zero.c */
/* % gcc aa30zero.c -o aa30zero */
/* % ./aa30zero fq7050000 sw100000 frx2 > mydata.txt> mydata.txt  */

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#define BUFFSIZE 256
#define BAUDRATE B38400
#define MODEMDEVICE "/dev/cu.usbmodem1471"

int fd = -1;
char com_ver[BUFFSIZE] = "ver"; /* returns AA-30 ZERO 150 */
char com_fq[BUFFSIZE];          /* returns OK */
char com_sw[BUFFSIZE];          /* returns OK */
char com_frx[BUFFSIZE];         /* returns OK */

void serial_init(int fd) {
  struct termios tio;

  memset(&tio, 0, sizeof(tio));
  tio.c_cflag = CS8 | CLOCAL | CREAD;
  tio.c_cc[VTIME] = 0;
  tio.c_lflag = ICANON;
  tio.c_iflag = IGNPAR | ICRNL;
  cfsetispeed(&tio, BAUDRATE);
  cfsetospeed(&tio, BAUDRATE);
  tcsetattr(fd, TCSANOW, &tio);
}

void receive_process() {
  unsigned char buf[BUFFSIZE];
  int count;
  int writecount = 0;
  int okcount = 0;

  while (1) {
    count = read(fd, &buf, BUFFSIZE);

    if (count <= 0) {
      fprintf(stderr, "error count=%d \n", count);
      exit(1);
    }

    if (count > 1) { // exclude ^M only line
      for (int i = 0; i < count; i++) {
        fprintf(stderr, "%c", buf[i]);
      }
    }

    if (count == 3) { // OK^M
      okcount++;
      if (okcount == 3) {
        return;
      }
    }

    if (count > 15) { // pick only data lines
      for (int i = 0; i < count; i++) {
        fprintf(stdout, "%c", buf[i]);
      }
    }
    fflush(stdout);
  } /* enf of while(1) */
}

void send_command(char *string) {
  char buf[BUFFSIZE];

  fprintf(stderr, "[%s] \n", string);
  int n = strlen(string);
  for (int i = 0; i < n; i++) {
    buf[i] = *string++;
  }
  buf[n] = 0x0a;
  int nout = n + 1;
  int writecount = write(fd, &buf, nout);
}

void send_process() {

  sleep(2); send_command(com_ver);    // 1 sec is NOT enough
  sleep(1); send_command(com_fq);
  sleep(1); send_command(com_sw);
  sleep(1); send_command(com_frx);
}

int main(int argc, char *argv[]) {
  pid_t result_pid;
  struct termios oldtio;

  if (argc != 4) {
    fprintf(stderr, "Usage %s fq7050000 sw100000 frx3 > mydata.txt \n", argv[0]);
    exit(1);
  }

  strcpy(com_fq, argv[1]);
  strcpy(com_sw, argv[2]);
  strcpy(com_frx, argv[3]);

  fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY);
  if (fd < 0) {
    fprintf(stderr, "file [%s] open error. \n", MODEMDEVICE);
    return (-1);
  }

  tcgetattr(fd, &oldtio);
  serial_init(fd);

  result_pid = fork();

  if (result_pid == -1) {
    return (-1);
  } else if (result_pid == 0) {  // child process
    send_process();
    _exit(0);
  } else {                // parent process
    receive_process();
    tcsetattr(fd, TCSANOW, &oldtio);
    exit(0);
  }

  return 0;
}

このプログラムは以下のようにして使います。

% gcc aa30zero.c -o aa30zero

% ./aa30zero fq7050000 sw100000 frx3 > mydata.txt
[ver] 
AA-30 ZERO 150
[fq7050000] 
OK
[sw100000] 
OK
[frx3] 
7.000000,651.849192,-2296.917794
7.033333,520.452206,-2084.028216
7.066666,815.151558,-2043.642265
7.099999,716.516930,-2188.015629
OK

% cat mydata.txt 
7.000000,651.849192,-2296.917794
7.033333,520.452206,-2084.028216
7.066666,815.151558,-2043.642265
7.099999,716.516930,-2188.015629

% cat z.plt
reset
set title "Impedance (R, X, and Z)"
set grid
set datafile separator ","
plot   "mydata.txt" using 1:2 with line linewidth 3
replot "mydata.txt" using 1:3 with line linewidth 3
replot "mydata.txt" using 1:( abs($2+$3*{0,1}) ) with line linewidth 3

% gnuplot
gnuplot> load "z.plt"

リグエキスパートのAA-30.ZERO (4)

ダミーロードでどうなるかを見てみましょう。周波数範囲は、0MHzから30MHzです。

上の図は、インピーダンス・カーブを示します。

これは、リターンロスです。

VSWRが上の図に示されています。

上の2つの図はスミスチャートです。

リグエキスパートのAA-30.ZERO(2)

さて、ATUで7038kHzに同調させた私のダイポールの測定をしてみましょう。

以下のような値が得られました。

...
7.037000 45.16 0.30
7.037500 45.31 0.19
7.038000 45.33 0.09
7.038500 45.29 -0.14
7.039000 45.28 -0.24
7.039500 45.44 -0.30
7.040000 45.31 -0.56
...

gnuplotを用いて、幾つかのグラフを描いてみます。

% gnuplot
gnuplot> plot "ant2.csv" using 1:2 with line linewidth 3, 
          "ant2.csv" using 1:3 with line linewidth 3

周波数範囲は、6.5MHzから7.5MHzで、紫色の線はR [ohm]、緑色の線はX [ohm]です。

もし、|Z|も表示させたいのであれば、描画コマンドはこうなります。

gnuplot> plot "ant2.csv" using 1:2 with line linewidth 3, \
          "ant2.csv" using 1:3 with line linewidth 3, \
          "ant2.csv" using 1:( abs($2+$3*{0,1}) ) with line linewidth 3

AntScopeを用いれば同様のグラフを得ることはできますが、私はあなたが自分でそれをやりたいだろうと信じています。

リターン・ロスは、以下のようにして求められます。

gnuplot> plot "ant2.csv" using 1:( -20.0 * log(abs( ($2+$3*{0,1}-50)/($2+$3*{0,1}+50) )) / log(10) ) with line linewidth 3


最後に、VSWRです。

gnuplot> plot "ant2.csv" using 1:( (1+abs( ($2+$3*{0,1}-50)/($2+$3*{0,1}+50) )) / (1-abs( ($2+$3*{0,1}-50)/($2+$3*{0,1}+50) )) ) with line linewidth 3

リグエキスパートのAA-30.ZERO

AA-30.ZEROは、筐体と液晶ディスプレイとキーパッドとを省いたアンテナアナライザーAA-30です。このボードは、USB/RS232C変換器を介してあなたのPCに接続することができます。

私は、私のArduino Unoを変換のために用いました。簡単なサンプルプログラムがここにあります。

// UART bridge for data exchange between 
// RigExpert AA-30 ZERO antenna & cable analyzer and Arduino Uno
//
// Receives from the Arduino, sends to AA-30 ZERO.
// Receives from AA-30 ZERO, sends to the Arduino.
//
// 26 June 2017, Rig Expert Ukraine Ltd.
//
#include <SoftwareSerial.h>

SoftwareSerial ZERO(4, 7);  // RX, TX

void setup() {
  ZERO.begin(38400);        // init AA side UART
  ZERO.flush();
  Serial.begin(38400);      // init PC side UART
  Serial.flush();
}

void loop() {
  if (ZERO.available()) Serial.write(ZERO.read());    // data stream from AA to PC
  if (Serial.available()) ZERO.write(Serial.read());  // data stream from PC to AA
}

私のMac miniで、ボードはうまく動作しました。どのようなコマンドがあるかは、ここを見て下さい。https://rigexpert.com/products/kits-analyzers/aa-30-zero/getting-started-with-the-zero/

示されている値は、それぞれ周波数[Hz]、R [ohm]、X [ohm]です。この測定はRF出力端子に負荷を何も繋がない状態で行ったので、RやXの値は比較的大きく、また、あまり安定していません。

もし、あなたがそれが好みであれば、Arduino IDEとそのシリアルコンソールを使うことも勿論可能です。

Raspberry PI 3用のADCボード

PCM1808(24-bit 96kHz ステレオ AD変換器)を用いた、ADCボードです。

http://select.marutsu.co.jp/list/detail.php?id=258

pi@raspberrypi:~ $ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: sndrpipcm1808ad [snd_rpi_pcm1808_adc], device 0: PCM1808 ADC HiFi pcm1808-dai-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

pi@raspberrypi:~ $ arecord -vD hw:0,0 -c 2 -d 60 -r 96000 -f S16_LE test96.wav
Recording WAVE 'test96.wav' : Signed 16 bit Little Endian, Rate 96000 Hz, Stereo
Hardware PCM card 0 'snd_rpi_pcm1808_adc' device 0 subdevice 0

LilyPond(2)

あなたは、あなたのソースコードをLilyPondが生成するMIDIファイルを再生することによってデバッグできます。\scoreブロックの中に、\midiブロックを挿入するだけです。

\score {
  \new StaffGroup &lt;&lt;
    \new Staff &lt;&lt; \global \violineOne &gt;&gt;
    \new Staff &lt;&lt; \global \violineTwo &gt;&gt;
  &gt;&gt;
  \layout { }
  \midi {
    \tempo 2 = 90
  }
}