├── README.md
├── main.cpp
├── pic1.png
├── pic2.png
├── pic3.png
└── pic4.png
/README.md:
--------------------------------------------------------------------------------
1 | # T1 interface for ICOM IC-705
2 | Version 2.0 (12.09.2023)
3 |
4 | Update on 5.09.2023: The ESP32 behaves now as a bluetooth master, which makes the bluetooth binding between the IC-705 and the ESP32 more robust.
5 |
6 | Hardware:
7 | As I am operating my IC-705 remotely by means of WFView (www.wfview.org), I was searching for an easy way to switch my Elecraft T1 tuner to the right settings when changing the frequency. The T1 stores its settings for each band which can be recalled via the control lines available on the jack socket of the T1.
8 |
9 | The control lines are connected to an ESP32 D1 mini which fetches the current frequency via bluetooth from the IC-705. When the frequency of the TRX changes, the ESP32 will send the new band number to the T1 forcing it to change its settings. For a few seconds the T1 will wait for a rf carrier. So, if one would like to retune, it would be enough to send a carrier directly after the frequency was changed.
10 |
11 | 
12 | The transistor (npn, e.g. BC547 or similar) and the resistor is soldered directly on the pin bar, the NC pin is just used to connect the collector to the wire.
13 | 
14 | 
15 | 
16 |
17 | Software:
18 | The code is based on the code from
19 | Ondrej Kolonicny (OK1CDJ) https://github.com/ok1cdj/IC705-BT-CIV
20 | for controlling the ic-705 via bluetooth
21 | and
22 | Matthew Robinson (VK6MR) https://zensunni.org/blog/2011/01/19/arduino-elecraft-t1-interface/
23 | for controlling the T1 by means of an ardunio.
24 | I did the compilation of the code with PlatformIO, but it should be possible also with the Arduino IDE
25 |
26 | You have to replace the dummy bluetooth address in main.cpp with that of your IC-705.
27 |
28 | Depending on your country it might be required to adapt the frequency bands in main.c (starting from line 110).
29 |
30 | Pairing:
31 | After flashing the code to the ESP32, the IC-705 and the ESP32 must be paired. In the bluetooth settings of the IC-705 select the menu item "Pairing reception" and then immediately press the reset button at the ESP32 board. On the display of the IC-705 you should see now a message, which expects confirmation of a pass key. Press OK and the bluetooth connection shoud be established.
32 |
33 | After initial pairing of the ESP32 and ic-705, it is required to power-on the ESP32, before the ic-705 is switched on.
34 | The new version sets the ESP32 as bluetooth master. Now in case the ESP32 or the TRX is temporarly switched off and on again, the TRX will be reconnected automatically.
35 |
36 | Optional:
37 | The code for controlling the T1 includes some delay() statements, which block the bluetooth communication for a while. This leads to error messages "esp_spp_cb(): RX Full! Discarding 22 bytes" within the PlatformIO console. To avoid those errors, one can change the rx buffer size in the BluetoothSerial library:
38 |
39 | In BluetoothSerial.cpp change
40 |
41 | #define RX_QUEUE_SIZE 512
42 | to
43 | #define RX_QUEUE_SIZE 2046
44 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | /*************************************************************************
2 | T1 Interface
3 |
4 | V2.0 (12.09.2023)
5 |
6 | Peter Jonas DL5DLA
7 |
8 | This code, running on an ESP32, requests the current frequency
9 | from the ICOM IC-705 via bluetooth connection, and sends the
10 | related band number to the Elecraft T1. Based on the band
11 | number, the T1 applies the stored tuning settings. A re-tuning
12 | is possible directly after changing the frequency. For the next
13 | few seconds the T1 waits for a carrier and will tune again.
14 |
15 | For first use, the ESP32 must be paired to the IC-705. Later on
16 | the ESP32 should be powered already, before the IC-705 is
17 | switched on. If someone knows how the bluetooth connection
18 | can be setup the other way around (switch on the IC-705, then
19 | the esp32), please let me know.
20 |
21 | The code is compiled on PlatformIO, but should also work using
22 | the Arduino IDE.
23 |
24 | This code is based on the code from
25 | Ondrej Kolonicny (ok1cdj) https://github.com/ok1cdj/IC705-BT-CIV
26 | and
27 | Matthew Robinson (VK6MR) https://zensunni.org/blog/2011/01/19/arduino-elecraft-t1-interface/
28 |
29 | Many thanks to both for their example codes giving me the first insight on how
30 | to deal with the communication between the IC-705 and T1.
31 |
32 | In this version the ESP32 device is set as bluetooth master and the IC-705 as client.
33 | Due to this the bluetooth connection is more robust, and the IC-705 is reconnected
34 | no matter if the TRX or the ESP32 is switched off temporarly.
35 |
36 | It is important now to set the "bd_address" in the next lines!
37 | *************************************************************************/
38 |
39 | #include
40 | #include "BluetoothSerial.h"
41 |
42 | // ######################################################################
43 | // Enter the BD_ADDRESS of your IC-705. You can find it in the Bluetooth
44 | // settings in section 'Bluetooth Device Information'
45 |
46 | uint8_t bd_address[6] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
47 | // ######################################################################
48 |
49 |
50 | #define DATA_PIN 18 // GPIO18 input/output
51 | #define TUNE_PIN 26 // GPIO26 (output)
52 |
53 | #define CONTROLLER_ADDRESS 0xE0 //Controller address
54 |
55 | #define START_BYTE 0xFE // Start byte
56 | #define STOP_BYTE 0xFD // Stop byte
57 |
58 | #define CMD_READ_FREQ 0x03 // Read operating frequency data
59 |
60 | // Function prototypes:
61 | void configRadioBaud(uint16_t);
62 | uint8_t readLine(void);
63 | bool searchRadio();
64 | void sendCatRequest(uint8_t);
65 | void printFrequency(void);
66 | void processCatMessages();
67 | void sendBit(int);
68 | void sendBand(byte);
69 |
70 | const uint32_t decMulti[] = {1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
71 |
72 | #define BAUD_RATES_SIZE 4
73 | const uint16_t baudRates[BAUD_RATES_SIZE] = {19200, 9600, 4800, 1200};
74 |
75 | void callback(esp_spp_cb_event_t, esp_spp_cb_param_t *);
76 | uint8_t radio_address; //Transceiver address
77 | uint16_t baud_rate; //Current baud speed
78 | uint32_t readtimeout; //Serial port read timeout
79 | uint8_t read_buffer[12]; //Read buffer
80 | uint32_t frequency; //Current frequency in Hz
81 | uint32_t timer;
82 |
83 | #define NUM_OF_BANDS 13
84 | const uint32_t bands[][2] =
85 | {
86 | { 1810, 2000 }, // 160m
87 | { 3500, 3800 }, // 80m
88 | { 5351, 5367 }, // 60m
89 | { 7000, 7200 }, // 40m
90 | { 10100, 10150 }, // 30m
91 | { 14000, 14350 }, // 20m
92 | { 18068, 18168 }, // 17m
93 | { 21000, 21450 }, // 15m
94 | { 24890, 24990 }, // 12m
95 | { 28000, 29700 }, // 10m
96 | { 50030, 51000 }, // 6m
97 | { 144000,146000 }, // 2m
98 | { 430000,440000 } // UHF
99 | };
100 |
101 | String modes;
102 |
103 | byte prev_band = 0xFF;
104 | boolean btConnected = false;
105 |
106 | BluetoothSerial SerialBT;
107 |
108 |
109 | // ------------------------------------------
110 | // Callback to get info about connection
111 | // ------------------------------------------
112 | void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
113 |
114 | if(event == ESP_SPP_SRV_OPEN_EVT){ // 34
115 | btConnected = true;
116 | Serial.println("Client Connected");
117 | }
118 | else if (event == ESP_SPP_CLOSE_EVT) // 27
119 | {
120 | btConnected = false;
121 | Serial.println("Client disconnected");
122 | }
123 |
124 | }
125 |
126 | // ----------------------------------------
127 | // Initialize bluetooth
128 | // ----------------------------------------
129 | void configRadioBaud(uint16_t baudrate)
130 | {
131 | SerialBT.register_callback(callback);
132 |
133 | // Setup bluetooth as master:
134 | if(!SerialBT.begin("T1-INTERFACE",true)) {
135 | Serial.println("An error occurred initializing Bluetooth");
136 | } else {
137 | Serial.println("Bluetooth initialized");
138 | Serial.println("The device started, now you can pair it with bluetooth!");
139 | }
140 |
141 | // Connect to client:
142 | Serial.print("Connect to bluetooth client ...");
143 |
144 | btConnected = SerialBT.connect(bd_address);
145 |
146 | while (!btConnected) {
147 | btConnected = SerialBT.connect(bd_address);
148 | Serial.println( "Need Pairing" );
149 | }
150 | Serial.println( "Transceiver connected" );
151 | }
152 |
153 | // ----------------------------------------
154 | // Read incoming line from bluetooth
155 | // ----------------------------------------
156 | uint8_t readLine(void)
157 | {
158 | uint8_t byte;
159 | uint8_t counter = 0;
160 | uint32_t ed = readtimeout; // not initialized!
161 |
162 | while (btConnected) {
163 | while (!SerialBT.available()) {
164 | if (--ed == 0 || !btConnected ) return 0; // leave the loop if BT connection is lost
165 | }
166 | ed = readtimeout;
167 | byte = SerialBT.read();
168 | if (byte == 0xFF) continue; //TODO skip to start byte instead
169 |
170 | read_buffer[counter++] = byte;
171 | if (STOP_BYTE == byte) break;
172 |
173 | if (counter >= sizeof(read_buffer)) return 0;
174 | }
175 | return counter;
176 | }
177 |
178 | // ----------------------------------------
179 | // Get address of transceiver
180 | // ----------------------------------------
181 | bool searchRadio()
182 | {
183 | for (uint8_t baud = 0; baud < BAUD_RATES_SIZE; baud++) {
184 | configRadioBaud(baudRates[baud]);
185 | sendCatRequest(CMD_READ_FREQ);
186 |
187 | if (readLine() > 0)
188 | {
189 | if (read_buffer[0] == START_BYTE && read_buffer[1] == START_BYTE) {
190 | radio_address = read_buffer[3];
191 | }
192 | return true;
193 | }
194 |
195 | }
196 |
197 | radio_address = 0xFF;
198 | return false;
199 | }
200 |
201 | // ----------------------------------------
202 | // get band from frequency
203 | // ----------------------------------------
204 | byte getBand(uint32_t freq)
205 | {
206 | for(uint8_t i=0; i= bands[i][0] && freq <= bands[i][1] ) {
208 | if(i==12) return 12; // T1 tuner does not have different settings for 2m and UHF
209 | return i+1;
210 | }
211 | }
212 | return 0xFF; // no band for considered frequency found
213 |
214 | }
215 |
216 |
217 | // ----------------------------------------
218 | // Send CAT Request
219 | // ----------------------------------------
220 | void sendCatRequest(uint8_t requestCode)
221 | {
222 | uint8_t req[] = {START_BYTE, START_BYTE, radio_address, CONTROLLER_ADDRESS, requestCode, STOP_BYTE};
223 |
224 | for (uint8_t i = 0; i < sizeof(req); i++) {
225 | SerialBT.write(req[i]);
226 | }
227 |
228 | }
229 |
230 |
231 | // ----------------------------------------
232 | // Print the received frequency
233 | // ----------------------------------------
234 | void printFrequency(void)
235 | {
236 | frequency = 0;
237 | //FE FE E0 42 03 <00 00 58 45 01> FD ic-820
238 | //FE FE 00 40 00 <00 60 06 14> FD ic-732
239 | for (uint8_t i = 0; i < 5; i++) {
240 | if (read_buffer[9 - i] == 0xFD) continue; //spike
241 | frequency += (read_buffer[9 - i] >> 4) * decMulti[i * 2];
242 | frequency += (read_buffer[9 - i] & 0x0F) * decMulti[i * 2 + 1];
243 | }
244 |
245 | }
246 |
247 |
248 | // --------------------------------------------------
249 | // Process the received messages from transceiver
250 | // --------------------------------------------------
251 | void processCatMessages()
252 | {
253 | /*
254 |
262 | FD - stop byte
263 | */
264 |
265 | while (SerialBT.available()) {
266 | bool knowncommand = true;
267 |
268 | if (readLine() > 0) {
269 |
270 | if (read_buffer[0] == START_BYTE && read_buffer[1] == START_BYTE) {
271 | if (read_buffer[3] == radio_address) {
272 | if (read_buffer[2] == CONTROLLER_ADDRESS) {
273 | switch (read_buffer[4]) {
274 | case CMD_READ_FREQ:
275 | printFrequency();
276 | break;
277 | default:
278 | knowncommand = false;
279 | }
280 | }
281 | }
282 | }
283 | }
284 | }
285 |
286 | }
287 |
288 | // ----------------------------------------
289 | // sendBit
290 | // ----------------------------------------
291 | void sendBit(int bit) {
292 |
293 | digitalWrite(DATA_PIN, HIGH);
294 | if (bit != 0) {
295 | delay(4);
296 | } else {
297 | delayMicroseconds(1500);
298 | }
299 |
300 | digitalWrite(DATA_PIN, LOW);
301 | delayMicroseconds(1500);
302 | }
303 |
304 |
305 | // ----------------------------------------
306 | // sendBand
307 | // ----------------------------------------
308 | void sendBand(byte band) {
309 |
310 | unsigned long previousTime = 0;
311 | const long maxWaitTime = 50;
312 |
313 | // Pull the TUNE_PIN line high for half a second
314 | digitalWrite(TUNE_PIN, HIGH);
315 | delay(500);
316 | digitalWrite(TUNE_PIN, LOW);
317 |
318 | // The ATU will pull the DATA_PIN line HIGH for 50ms
319 |
320 | previousTime = millis();
321 | while(digitalRead(DATA_PIN) == LOW) {
322 | // Measure time the while loop is active, and jump out after maxWaiTime.
323 | // This esnures that the program does not lock in case the communication
324 | // with the ATU is temporarly broken
325 |
326 | unsigned long currentTime = millis();
327 | if (currentTime - previousTime > maxWaitTime) {
328 | Serial.println("Error: No positive pulse from T1 detected!");
329 | return;
330 | }
331 | }
332 |
333 | while(digitalRead(DATA_PIN) == HIGH) {
334 | }
335 | // Wait 10ms
336 | delay(10);
337 |
338 | // and then send data on the DATA line
339 | pinMode(DATA_PIN, OUTPUT);
340 |
341 | // 1 bits are HIGH for 4ms
342 | // 0 bits are HIGH for 1.5ms
343 | // Gap between digits is 1.5ms LOW
344 |
345 | // 1st bit
346 | sendBit(band & 8);
347 | sendBit(band & 4);
348 | sendBit(band & 2);
349 | sendBit(band & 1);
350 |
351 | // Leave the line LOW
352 | digitalWrite(DATA_PIN, LOW);
353 |
354 | // and switch it back to an input
355 | pinMode(DATA_PIN, INPUT);
356 | }
357 |
358 | // ----------------------------------------
359 | // Setup
360 | // ----------------------------------------
361 | void setup()
362 | {
363 | Serial.begin(115200);
364 |
365 | pinMode(DATA_PIN,INPUT);
366 | pinMode(TUNE_PIN, OUTPUT);
367 | digitalWrite(TUNE_PIN,LOW);
368 |
369 | while (radio_address == 0x00) {
370 | if (!searchRadio()) {
371 | Serial.println("Radio not found");
372 | } else {
373 | Serial.print("Radio found at ");
374 | Serial.print(radio_address, HEX);
375 | Serial.println();
376 | }
377 | }
378 |
379 | }
380 |
381 | // ----------------------------------------
382 | // Main loop
383 | // ----------------------------------------
384 | void loop()
385 | {
386 | while (!btConnected) {
387 | Serial.println( "Connecting ..." );
388 | btConnected = SerialBT.connect(bd_address);
389 | if(btConnected)
390 | Serial.println( "Transceiver reconnected" );
391 | }
392 |
393 | sendCatRequest(CMD_READ_FREQ);
394 | processCatMessages();
395 |
396 | byte band = getBand(frequency/1000);
397 |
398 | if( (band != prev_band) && (band != 0xFF) ) {
399 | Serial.print("Frequency: ");
400 | Serial.print(frequency/1000);
401 | Serial.print(" -> band: ");
402 | Serial.println(band);
403 | sendBand(band);
404 | prev_band=band;
405 | }
406 | delay(50); // TEST
407 | }
408 |
--------------------------------------------------------------------------------
/pic1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dl5dla/T1-Interface-for-IC-705/88a2ee59df3f38c06111fd25727f5f62c9ddc844/pic1.png
--------------------------------------------------------------------------------
/pic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dl5dla/T1-Interface-for-IC-705/88a2ee59df3f38c06111fd25727f5f62c9ddc844/pic2.png
--------------------------------------------------------------------------------
/pic3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dl5dla/T1-Interface-for-IC-705/88a2ee59df3f38c06111fd25727f5f62c9ddc844/pic3.png
--------------------------------------------------------------------------------
/pic4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dl5dla/T1-Interface-for-IC-705/88a2ee59df3f38c06111fd25727f5f62c9ddc844/pic4.png
--------------------------------------------------------------------------------