Zensunni.org

Arduino - Elecraft T1 Interface

I recently built an Elecraft T1 automatic tuner to use with my Flex-1500 SDR. The manual for the T1 ATU gives information about the protocol that is used to remotely control the ATU allowing the ATU to retune the antenna on band changes. Elecraft only sell a cable to interface with the FT-817 so I began to wonder if I could interface the Flex-1500 with the T1 using an Arduino prototyping board.

Being a software defined radio the “brains” of the Flex-1500 actually run on a PC in the form of PowerSDR. I had a Google and it appeared that most people were using a piece of software called DDUtil to interface between PowerSDR and external hardware. I downloaded DDUtil, installed it and quickly came to the conclusion that I needed to create a device that acted as a “passive listener”.

DDUtil can be configured to send a simple CAT command to a serial port on a repeated basis. I configured some virtual serial ports in Windows to monitor the signal being sent from DDUtil to the external device and found that it simply sends an IF CAT command on a repeating basis. The IF command contains the frequency that the radio is tuned to.

When connected to a PC the Arduino presents itself to the operating system as a serial port so all I needed to do was program the Arduino to decode the IF command, convert the frequency into a band and then send the band information to the Elecraft T1.

The connection to the T1 is made using a 3.5mm stereo plug. The tip carries the data about the band, the ring is used to trigger a retune of the ATU and the sleeve is the ground. The tune is connected to the Arduino using an NPN transistor (I used a generic PN100) in an open-collector configuration. The band is sent to the T1 as a number between 0 and 12 by encoding the four bits and sending them via the tip of the connector. The details are described in the T1 manual on page 8.

A schematic for the interface is shown below. I built this as a daughter board that the Arduino Nano can plug into. This board contains the NPN transistor, a current limiting resistor and a three pin connector that is used to connect the cable that carries the signal to the T1. I made the cable from a good quality shielded twin core microphone cable.

The completed board is shown below. There are a number of header sockets on the board which are there simply to support the Arduino. Only three pins are actually connected between the Arduino and the board (D2, D3 and GND).

The Arduino sketch is as follows:

Elecraft T1 Interface Arduino Sketch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/******************************************************
*  Elecraft T1 Interface                              *
*                                                     *
*  This Arduino sketch allows DDUtil to control       *
*  an Elecraft T1 ATU via the T1's remote control     *
*  interface.                                         *
*                                                     *
*  Copyright (c) Matthew Robinson - VK6MR, 2011       *
*                                                     * 
*  This code is released under a Creative Commons     *
*  Attribution-NonCommercial-ShareAlike 3.0           *
*  Unported (CC BY-NC-SA 3.0) license.                *
*                                                     *
*  http://creativecommons.org/licenses/by-nc-sa/3.0/  *
*                                                     *
******************************************************/


int TUNE = 2;
int DATA = 3;

int prevBand = -1;
int band = 0;

char buffer[64];
int  bufptr = 0;

void setup() {
  Serial.begin(9600);

  pinMode(TUNE, OUTPUT);
  digitalWrite(TUNE, LOW);

  pinMode(DATA, INPUT);
}

void loop() {
  if (Serial.available()) {
    char character = Serial.read();

    if (character != '\n' && character != '\r') {

      buffer[bufptr] = character;
      if (buffer[bufptr] == ';') {

        // Message should always be 14 chars
        if (bufptr == 13) {
          parseBuffer();

          if (band != -1) {
            if (band != prevBand) {
              sendBand();
              prevBand = band;
            }
          }
        }

        bufptr = 0;
      }
      else {
        bufptr++;

        // Don't overrun the buffer, messages should only be 14 chars anyway
        if (bufptr > 60)
          bufptr = 0;
      }
    }
  }
}

// buffer is of form:
// IF00003700000;
// IF00051000000;

void parseBuffer() {
  if (buffer[0] != 'I' || buffer[1] != 'F') {
    band = -1;
    return;
  }

  // We are only interested in the significant figures
  int freq = buffer[6] - 48;
  freq += (buffer[5] - 48) * 10;

  band = 0;

  if (freq >= 1 && freq <= 2) {
    band = 1; // 160
  }
  else if (freq >= 3 && freq <= 4) {
    band = 2; // 80
  }
  else if (freq == 5) {
    band = 3; // 60
  }
  else if (freq == 7) {
    band = 4; // 40
  }
  else if (freq == 10) {
    band = 5; // 30
  }
  else if (freq == 14) {
    band = 6; // 20
  }
  else if (freq == 18) {
    band = 7; // 17
  }
  else if (freq == 21) {
    band = 8; // 15
  }
  else if (freq == 24) {
    band = 9; // 12
  }
  else if (freq >= 28 && freq <= 29) {
    band = 10; // 10
  }
  else if (freq >= 50 && freq <= 54) {
    band = 11; // 6
  }
}

void sendBand() {

  // Pull the TUNE line high for half a second

  digitalWrite(TUNE, HIGH);
  delay(500);
  digitalWrite(TUNE, LOW);

  // The ATU will pull the DATA line HIGH for 50ms
  while(digitalRead(DATA) == LOW) {
  }
  while(digitalRead(DATA) == HIGH) {
  }


  // Wait 10ms
  delay(10);

  // and then send data on the DATA line
  pinMode(DATA, OUTPUT);

  // 1 bits are HIGH for 4ms 
  // 0 bits are HIGH for 1.5ms
  // Gap between digits is 1.5ms LOW

  // 1st bit
  sendBit(band & 8);
  sendBit(band & 4);
  sendBit(band & 2);
  sendBit(band & 1);

  // Leave the line LOW
  digitalWrite(DATA, LOW);

  // and switch it back to an input
  pinMode(DATA, INPUT);
}

void sendBit(int bit) {

  digitalWrite(DATA, HIGH);
  if (bit != 0) {
    delay(4);
  } else {
    delayMicroseconds(1500);
  }

  digitalWrite(DATA, LOW);
  delayMicroseconds(1500);
}