├── 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 | ![Screenshot](pic4.png)
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 | ![Screenshot](pic1.png) 14 | ![Screenshot](pic2.png) 15 | ![Screenshot](pic3.png) 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 --------------------------------------------------------------------------------