├── bd2.jpg ├── README.md └── band_decoder_2.ino /bd2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ok1hra/band_decoder_2/HEAD/bd2.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Band decoder MK2 2 | 3 | Wiki [web page](https://remoteqth.com/wiki/index.php?page=Band+decoder+MK2) 4 | 5 | ![Hardware](bd2.jpg) 6 | -------------------------------------------------------------------------------- /band_decoder_2.ino: -------------------------------------------------------------------------------- 1 | #include 2 | const char* REV = "20210527"; 3 | /* 4 | 5 | Band decoder MK2 with TRX control output for Arduino 6 | ----------------------------------------------------------- 7 | https://remoteqth.com/wiki/index.php?page=Band+decoder+MK2 8 | 9 | ___ _ ___ _____ _ _ 10 | | _ \___ _ __ ___| |_ ___ / _ \_ _| || | __ ___ _ __ 11 | | / -_) ' \/ _ \ _/ -_) (_) || | | __ |_/ _/ _ \ ' \ 12 | |_|_\___|_|_|_\___/\__\___|\__\_\|_| |_||_(_)__\___/_|_|_| 13 | 14 | 15 | This program is free software: you can redistribute it and/or modify 16 | it under the terms of the GNU General Public License as published by 17 | the Free Software Foundation, either version 2 of the License, or 18 | (at your option) any later version. 19 | This program is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU General Public License for more details. 23 | You should have received a copy of the GNU General Public License 24 | along with this program. If not, see . 25 | 26 | Features: 27 | Support inputs 28 | * PTT detector - if PTT on, outputs not change 29 | * SERIAL terminal (ASCII) 30 | * ICOM CI-V 31 | * KENWOOD - CAT 32 | * FLEX 6000 CAT series 33 | * YAESU / ELECRAFT BCD 34 | * ICOM ACC voltage 35 | * YAESU CAT - TRX since 2008 ascii format 36 | * YAESU CAT old binary format (tested on FT-817) 37 | * IP relay with automatic pair by rotary encoder ID https://remoteqth.com/wiki/index.php?page=IP+Switch+with+ESP32-GATEWAY 38 | 39 | Outputs 40 | * 14 local relay 41 | * 14 remote relay 42 | * Yaesu BCD 43 | * Serial echo 44 | * Icom CIV 45 | * Kenwood CAT 46 | * YAESU CAT - TRX since 2008 ascii format 47 | * IP relay with automatic pair by rotary encoder ID 48 | * PTT by band - distributed PTT to output, dependency by frequency - TNX Tim W4YN 49 | * Analog (PWM) output by preset table 50 | 51 | Major changes 52 | ------------- 53 | - LCD support 54 | - Icom with request mode 55 | - PTT input block changes during transmit 56 | - own board with all smd parts including arduino nano module 57 | - without relays, only control driver outputs 58 | - optional ethernet module 59 | 60 | Changelog 61 | --------- 62 | 2021-05 Lock char bug fix, add Icom 70MHz support 63 | 2021-02 add 23cm (IC9700) Icom state machine 64 | 2020-10 PWM (analog) output 65 | 2020-07 PTT by band 66 | 2020-02 fix out set 67 | 2019-11 YAESU / ELECRAFT input BCD format 68 | 2018-03 manual switch between four output on same band by BCD input - TNX ZS1LS behind inspiration 69 | 2018-12 PTT bug fix 70 | LCD PCF8574 support 71 | copy YAESU CAT from old code 72 | added YAESU FT-100 support 73 | 2018-11 support FLEX 6000 CAT series 74 | 2018-06 support IP relay 75 | 2018-05 mk2 initial release 76 | 77 | */ 78 | //=====[ Inputs ]============================================================================================= 79 | 80 | // #define INPUT_BCD // TTL BCD in A 81 | int BcdInputFormat = 0; // if enable INPUT_BCD, set format 0 - YAESU, 1 ELECRAFT 82 | // #define ICOM_ACC // voltage 0-8V on pin4 ACC(2) connector - need calibrate table 83 | // #define INPUT_SERIAL // telnet ascii input - cvs format [band],[freq]\n 84 | #define ICOM_CIV // read frequency from CIV 85 | // #define KENWOOD_PC // RS232 CAT 86 | // #define FLEX_6000 // RS232 CAT 87 | // #define YAESU_CAT // RS232 CAT YAESU CAT since 2015 ascii format 88 | // #define YAESU_CAT_OLD // Old binary format RS232 CAT ** tested on FT-817 ** 89 | // #define YAESU_CAT_FT100 // RS232 CAT YAESU for FT100(D) 90 | // #define MULTI_OUTPUT_BY_BCD // manual switch between four output on same band by BCD input 91 | // - INPUT_BCD input must be disable 92 | // - BCD output will be disble 93 | // - it must always be select (grounded) one of BCD input 94 | //=====[ Outputs ]============================================================================================ 95 | // If enable: 96 | // - baudrate is same as selected Inputs 97 | // - Inputs work only in 'sniff mode' 98 | // - for operation must disable REQUEST 99 | // 100 | // #define ICOM_CIV_OUT // send frequency to CIV ** you must set TRX CIV_ADRESS ** 101 | // #define KENWOOD_PC_OUT // send frequency to RS232 CAT 102 | // #define YAESU_CAT_OUT // send frequency to RS232 CAT ** for operation must disable REQUEST ** 103 | // #define SERIAL_echo // Feedback on serial line in same baudrate, CVS format <[band],[freq]>\n 104 | // #define PTT_BY_BAND // distributed PTT dependency to band (disable band decoder outputs) TNX Tim W4YN for idea 105 | // #define PWM_OUT // PWM on D5 with rc filter (10k/10u) represent analog output J2.12 106 | 107 | //=====[ Hardware ]============================================================================================= 108 | 109 | #define LCD // Uncoment to Enable I2C LCD 110 | const byte LcdI2Caddress = 0x27; // 0x27 0x3F - may be find with I2C scanner https://playground.arduino.cc/Main/I2cScanner 111 | // #define LCD_PCF8574 // If LCD uses PCF8574 chip 112 | // #define LCD_PCF8574T // If LCD uses PCF8574T chip 113 | #define LCD_PCF8574AT // If LCD uses PCF8574AT chip 114 | 115 | // #define EthModule // enable Ethernet module if installed 116 | // #define __USE_DHCP__ // enable DHCP 117 | byte NET_ID = 0x00; // NetID [hex] MUST BE UNIQUE IN NETWORK - replace by P6 board encoder 118 | // #define BcdIpRelay // control IP relay in BCD format 119 | 120 | //=====[ Settings ]=========================================================================================== 121 | 122 | #define SERBAUD 9600 // [baud] Serial port in/out baudrate 123 | #define WATCHDOG 20 // [sec] determines the time, after which the all relay OFF, if missed next input data - uncomment for the enabled 124 | #define REQUEST 500 // [ms] use TXD output for sending frequency request 125 | #define CIV_ADRESS 0x56 // CIV input HEX Icom adress (0x is prefix) 126 | #define CIV_ADR_OUT 0x56 // CIV output HEX Icom adress (0x is prefix) 127 | // #define DISABLE_DIVIDER // for lowest voltage D-SUB pin 13 inputs up to 5V only - need open JP9 128 | // #define DEBUG // enable some debugging 129 | //=====[ FREQUEN RULES ]=========================================================================================== 130 | 131 | const long Freq2Band[16][2] = {/* 132 | Freq Hz from to Band number 133 | */ {1810000, 2000000}, // #1 [160m] 134 | {3500000, 3800000}, // #2 [80m] 135 | {5298000, 5403000}, // #3 [60m] 136 | {7000000, 7200000}, // #4 [40m] 137 | {10100000, 10150000}, // #5 [30m] 138 | {14000000, 14350000}, // #6 [20m] 139 | {18068000, 18168000}, // #7 [17m] 140 | {21000000, 21450000}, // #8 [15m] 141 | {24890000, 24990000}, // #9 [12m] 142 | {28000000, 29700000}, // #10 [10m] 143 | {50000000, 52000000}, // #11 [6m] 144 | {70000000, 72000000}, // #12 [4m] 145 | {144000000, 146000000}, // #13 [2m] 146 | {430000000, 440000000}, // #14 [70cm] 147 | {1240000000, 1300000000}, // #15 [23cm] 148 | {2300000000, 2450000000}, // #16 [13cm] 149 | // {3300000000, 3500000000}, // #17 [9cm] 150 | // {5650000000, 5850000000}, // #18 [6cm] 151 | }; 152 | //=====[ Sets band --> to output in MATRIX table ]=========================================================== 153 | 154 | const byte matrix[17][40] = { /* band out 155 | 156 | If enable #define MULTI_OUTPUT_BY_BCD 157 | you can select outputs manually to ground one from BCD inputs 158 | to select between four output on same band 159 | represent by bit in this table 160 | 0x01 = B00000001 = bit 1 161 | 0x02 = B00000010 = bit 2 162 | 0x04 = B00000100 = bit 3 163 | 0x08 = B00001000 = bit 4 164 | For example record 165 | Band 1 --> { 0x01, 0x02, 0x04, 0, 0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 166 | is the same as record 167 | Band 1 --> { B00000001, B00000010, B00000100, 0, B00001000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 168 | 169 | 0x0F = this output enable for any BCD input (enable all bit) 170 | 171 | Band 0 --> */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* first eight shift register board 172 | \ Band 1 --> */ { 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 173 | \ Band 2 --> */ { 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 174 | \ Band 3 --> */ { 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 175 | \ Band 4 --> */ { 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 176 | \ Band 5 --> */ { 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 177 | \ Band 6 --> */ { 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 178 | IN ) Band 7 --> */ { 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 179 | / Band 8 --> */ { 0, 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 180 | 181 | / Band 9 --> */ { 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* second eight shift register board 182 | / Band 10 -> */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* (optional) 183 | / Band 11 -> */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 184 | / Band 12 -> */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 185 | / Band 13 -> */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 186 | Band 14 -> */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 187 | Band 15 -> */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 188 | Band 16 -> */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* 189 | | | | | | | | | | | | | | | | | 190 | V V V V V V V V V V V V V V V V 191 | ---------------------------------- --------------------------------- 192 | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 193 | ---------------------------------- --------------------------------- 194 | OUTPUTS 195 | (for second eight need aditional board)*/ 196 | }; 197 | const int NumberOfBoards = 1; // number of eight byte shift register 0-x 198 | 199 | //=====[ BCD OUT ]=========================================================================================== 200 | 201 | const boolean BCDmatrixOUT[4][16] = { /* 202 | -------------------------------------------------------------------- 203 | Band # to output relay 0 1 2 3 4 5 6 7 8 9 10 204 | (Yaesu BCD) 160 80 40 30 20 17 15 12 10 6m 205 | -------------------------------------------------------------------- 206 | | | | | | | | | | | | 207 | V V V V V V V V V V V 208 | */ { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }, /* --> DB25 Pin 11 209 | */ { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, /* --> DB25 Pin 24 210 | */ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1 }, /* --> DB25 Pin 12 211 | */ { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, /* --> DB25 Pin 25 212 | */}; 213 | //=====[ PWM OUT ]=========================================================================================== 214 | #if defined(PWM_OUT) 215 | const long PwmByBand[17] = {/* 216 | PWM 0-255 217 | */ 0, // #0 OUT of band 218 | 11, // #1 [160m] 0,23V 219 | 24, // #2 [80m] 0,46V 220 | 36, // #3 [60m] 0,69V 221 | 49, // #4 [40m] 0,92V 222 | 62, // #5 [30m] 1,15V 223 | 74, // #6 [20m] 1,38V 224 | 87, // #7 [17m] 1,61V 225 | 99, // #8 [15m] 1,84V 226 | 111, // #9 [12m] 2,07V 227 | 124, // #10 [10m] 2,3V 228 | 137, // #11 [6m] 2,53V 229 | 180, // #12 [4m] 230 | 195, // #13 [2m] 231 | 210, // #14 [70cm] 232 | 225, // #15 [23cm] 233 | 240, // #16 [13cm] 234 | }; 235 | #endif 236 | //============================================================================================================ 237 | 238 | // #define SERIAL_debug 239 | // #define UdpBroadcastDebug_debug 240 | 241 | #if defined(LCD) 242 | #include 243 | 244 | #if defined(LCD_PCF8574T) || defined(LCD_PCF8574) 245 | #include 246 | LiquidCrystal_PCF8574 lcd(LcdI2Caddress); 247 | #endif 248 | #if defined(LCD_PCF8574AT) 249 | #include 250 | LiquidCrystal_I2C lcd(LcdI2Caddress,16,2); 251 | #endif 252 | 253 | 254 | long LcdRefresh[2]{0,500}; 255 | const char* ANTname[17][4] = { 256 | 257 | /* 258 | - If enable #define PTT_BY_BAND output name represent diffrent devices (TRX) 259 | 260 | - If enable #define MULTI_OUTPUT_BY_BCD 261 | you can fill name for another antennas on the same band 262 | dependency to select BCD input 263 | 264 | Default or BCD-1 BCD-2 BCD-3 BCD-4 265 | | | | | 266 | */ {"Out of band", "Out of band", "Out of band", "Out of band"}, // Band 0 (no data) 267 | {"Dipole", "BCD-2", "BCD-3", "BCD-4"}, // Band 1 268 | {"Vertical", "BCD-2", "BCD-3", "BCD-4"}, // Band 2 269 | {"3el Yagi", "BCD-2", "BCD-3", "BCD-4"}, // Band 3 270 | {"Windom", "BCD-2", "BCD-3", "BCD-4"}, // Band 4 271 | {"DeltaLoop", "BCD-2", "BCD-3", "BCD-4"}, // Band 5 272 | {"20m Stack", "BCD-2", "BCD-3", "BCD-4"}, // Band 6 273 | {"DeltaLoop", "BCD-2", "BCD-3", "BCD-4"}, // Band 7 274 | {"HB9", "BCD-2", "BCD-3", "BCD-4"}, // Band 8 275 | {"Dipole", "BCD-2", "BCD-3", "BCD-4"}, // Band 9 276 | {"5el Yagi", "BCD-2", "BCD-3", "BCD-4"}, // Band 10 277 | {"7el Yagi", "BCD-2", "BCD-3", "BCD-4"}, // Band 11 278 | {"24el", "BCD-2", "BCD-3", "BCD-4"}, // Band 12 279 | {"20el quad", "BCD-2", "BCD-3", "BCD-4"}, // Band 13 280 | {"Dish 1.2m", "BCD-2", "BCD-3", "BCD-4"}, // Band 14 281 | {"Dish 1.2m", "BCD-2", "BCD-3", "BCD-4"}, // Band 15 282 | {"Dish 1m", "BCD-2", "BCD-3", "BCD-4"}, // Band 16 283 | }; 284 | // byte LockChar[8] = {0b00100, 0b01010, 0b01010, 0b11111, 0b11011, 0b11011, 0b11111, 0b00000}; 285 | uint8_t LockChar[8] = {0x4,0xa,0xa,0x1f,0x1b,0x1b,0x1f,0x0}; 286 | bool LcdNeedRefresh = false; 287 | #endif 288 | 289 | #if defined(EthModule) 290 | const byte RemoteDevice = 's'; 291 | const byte ThisDevice = 'r'; 292 | bool EnableEthernet = 1; 293 | bool EnableDHCP = 1; 294 | long GetNetIdTimer[2]{0,2000}; 295 | // #include 296 | #include 297 | #include 298 | // #include 299 | // #include 300 | #include 301 | byte LastMac = 0x00 + NET_ID; 302 | 303 | byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, LastMac}; 304 | IPAddress ip(192, 168, 1, 222); // IP 305 | IPAddress gateway(192, 168, 1, 200); // GATE 306 | IPAddress subnet(255, 255, 255, 0); // MASK 307 | IPAddress myDns(8, 8, 8, 8); // DNS (google pub) 308 | EthernetServer server(80); // Web server PORT 309 | String HTTP_req; 310 | 311 | unsigned int UdpCommandPort = 88; // local UDP port listen to command 312 | // #define UDP_TX_PACKET_MAX_SIZE 30 // MIN 30 313 | // unsigned char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet, 314 | unsigned char packetBuffer[30]; //buffer to hold incoming packet, 315 | int UDPpacketSize; 316 | EthernetUDP UdpCommand; // An EthernetUDP instance to let us send and receive packets over UDP 317 | IPAddress BroadcastIP(0, 0, 0, 0); // Broadcast IP address 318 | int BroadcastPort = 88; // destination broadcast packet port 319 | IPAddress RemoteSwIP(0, 0, 0, 0); // remote UDP IP switch - set from UDP DetectRemote array 320 | int RemoteSwPort = 0; // remote UDP IP switch port 321 | byte DetectedRemoteSw[16][5]; // detect by RX broadcast packet - storage by ID (ID=rows) 322 | int BandDecoderChange = 0; // If band change, send query packet to Remote IP switch 323 | long RemoteSwLatency[2]; // start, stop mark 324 | byte RemoteSwLatencyAnsw = 0; // answer (offline) detect 325 | byte TxUdpBuffer[10]; 326 | long IpTimeout[1][2] = {0, 60000}; // UDP Broadcast packet [8][0-timer/1-timeout] 327 | 328 | bool EthLinkStatus = 0; 329 | long EthLinkStatusTimer[2]{1500,1000}; 330 | uint8_t EthChar[8] = {0x0,0x0,0x1f,0x11,0x11,0x1b,0x1f,0x0}; 331 | #endif 332 | 333 | // PINOUTS 334 | const int VoltagePin = A0; // measure input voltage 335 | const int EncBPin = A0; // Encoder B 336 | const int Id1Pin = A1; // ID switch 337 | const int BcdIn1Pin = A2; // BCD-1 in/out 338 | const int ShiftInClockPin = A2; // [ShiftIn] 339 | const int ADPin = A3; // [BD/ROT] 340 | const int SequencerPin = A3; // [IPsw/BD] 341 | // const int SdaPin = A4; // [LCD] 342 | const int Id4Pin = A4; // 343 | // const int SclPin = A5; // [LCD] 344 | const int Id2Pin = A6; // 345 | const int Id3Pin = A7; // 346 | const int PttDetectorPin = 2; // PTT in - [interrupt] 347 | const int BcdIn4Pin = 3; // BCD-4 in/out 348 | const int EncAShiftInPin = 3; // Encoder+Keyboard - [interrupt] 349 | const int BcdIn3Pin = 4; // BCD-3 in/out 350 | const int ShiftInDataPin = 4; // [ShiftIn] 351 | const int BcdIn2Pin = 5; // BCD-2 in/out 352 | const int ShiftInLatchPin = 5; // [ShiftIn] 353 | const int PwmOutPin = 5; // [PWM] 354 | const int PttOffPin = 6; // PTT out OFF switch 355 | const int ShiftOutDataPin = 7; // DATA 356 | const int ShiftOutLatchPin = 8; // LATCH 357 | const int ShiftOutClockPin = 9; // CLOCK 358 | 359 | int BAND = 0; 360 | int previousBAND = -1; 361 | long freq = 0; 362 | bool PTT = false; 363 | long PttTiming[2]={0, 10}; // debouncing time and also minimal PTT on time in ms 364 | float DCinVoltage; 365 | #if defined(DISABLE_DIVIDER) 366 | float ResistorCoeficient = 1.0; 367 | #else 368 | float ResistorCoeficient = 6.0; 369 | #endif 370 | 371 | long VoltageRefresh[2] = {0, 3000}; // refresh in ms 372 | float ArefVoltage = 4.303; // Measure on Aref pin 20 for calibrate 373 | float Divider = 1; 374 | 375 | byte ShiftByte[NumberOfBoards]; 376 | 377 | // int SelectOut = 0; 378 | // int x; 379 | long RequestTimeout[2]={0, 380 | #if defined(REQUEST) 381 | REQUEST 382 | #else 383 | 0 384 | #endif 385 | }; 386 | 387 | int watchdog2 = 500; // REQUEST refresh time [ms] 388 | int previous2; 389 | int timeout2; 390 | 391 | #if defined(WATCHDOG) 392 | int previous; 393 | int timeout; 394 | long WatchdogTimeout[2] = {-WATCHDOG*1000, WATCHDOG*1000}; 395 | #endif 396 | #if defined(ICOM_ACC) 397 | float AccVoltage = 0; 398 | float prevAccVoltage=0; 399 | int band = 0; 400 | int counter = 0; 401 | #endif 402 | #if defined(INPUT_BCD) 403 | long BcdInRefresh[2] = {0, 1000}; // refresh in ms 404 | #endif 405 | #if defined(KENWOOD_PC) || defined(YAESU_CAT) || defined(FLEX_6000) 406 | int lf = 59; // 59 = ; 407 | #endif 408 | #if defined(KENWOOD_PC) || defined(FLEX_6000) 409 | char rdK[37]; //read data kenwood 410 | String rdKS; //read data kenwood string 411 | #endif 412 | #if defined(YAESU_CAT) 413 | char rdY[37]; //read data yaesu 414 | String rdYS; //read data yaesu string 415 | #endif 416 | #if defined(YAESU_CAT_OLD) || defined(YAESU_CAT_FT100) 417 | byte rdYO[37]; //read data yaesu 418 | String rdYOS; //read data yaesu string 419 | #endif 420 | #if defined(ICOM_CIV) || defined(ICOM_CIV_OUT) 421 | int fromAdress = 0xE0; // 0E 422 | byte rdI[10]; //read data icom 423 | String rdIS; //read data icom string 424 | long freqPrev1; 425 | byte incomingByte = 0; 426 | int state = 1; // state machine 427 | bool StateMachineEnd = false; 428 | #endif 429 | #if defined(KENWOOD_PC_OUT) || defined(YAESU_CAT_OUT) 430 | long freqPrev2; 431 | #endif 432 | #if defined(BCD_OUT) 433 | char BCDout; 434 | #endif 435 | #if defined(MULTI_OUTPUT_BY_BCD) 436 | byte SelectBank; 437 | byte SelectBankPrev; 438 | #endif 439 | //--------------------------------------------------------------------------------------------------------- 440 | 441 | void setup() { 442 | #if defined(YAESU_CAT_OLD) || defined(YAESU_CAT_FT100) 443 | Serial.begin(SERBAUD, SERIAL_8N2); 444 | Serial.setTimeout(10); 445 | #else 446 | Serial.begin(SERBAUD); 447 | Serial.setTimeout(10); 448 | #endif 449 | 450 | #if defined(KENWOOD_PC) || defined(YAESU_CAT) 451 | // CATdata.reserve(200); // reserve bytes for the CATdata 452 | #endif 453 | 454 | pinMode(VoltagePin, INPUT); 455 | 456 | #if defined(ICOM_ACC) 457 | pinMode(ADPin, INPUT); 458 | #else 459 | pinMode(SequencerPin, OUTPUT); 460 | #endif 461 | 462 | pinMode(PttDetectorPin, INPUT); 463 | digitalWrite(PttDetectorPin, HIGH); 464 | 465 | pinMode(PttOffPin, OUTPUT); 466 | #if ( defined(INPUT_BCD) || defined(MULTI_OUTPUT_BY_BCD) ) && !defined(PWM_OUT) 467 | pinMode(BcdIn1Pin, INPUT); 468 | // digitalWrite(Id3Pin, INPUT_PULLUP); 469 | digitalWrite(BcdIn1Pin, HIGH); 470 | pinMode(BcdIn2Pin, INPUT); 471 | digitalWrite(BcdIn2Pin, HIGH); 472 | pinMode(BcdIn3Pin, INPUT); 473 | digitalWrite(BcdIn3Pin, HIGH); 474 | pinMode(BcdIn4Pin, INPUT); 475 | digitalWrite(BcdIn4Pin, HIGH); 476 | #else 477 | pinMode(BcdIn1Pin, OUTPUT); 478 | pinMode(BcdIn2Pin, OUTPUT); 479 | pinMode(PwmOutPin, OUTPUT); 480 | pinMode(BcdIn3Pin, OUTPUT); 481 | pinMode(BcdIn4Pin, OUTPUT); 482 | #endif 483 | pinMode(ShiftOutDataPin, OUTPUT); 484 | pinMode(ShiftOutLatchPin, OUTPUT); 485 | pinMode(ShiftOutClockPin, OUTPUT); 486 | 487 | analogReference(EXTERNAL); 488 | 489 | #if defined(LCD) 490 | 491 | #if defined(LCD_PCF8574T) || defined(LCD_PCF8574) 492 | lcd.begin(16, 2); // initialize the lcd PFC8574 493 | lcd.setBacklight(1); 494 | #else 495 | //------------------------------------------------------ 496 | // Enable begin or init in dependence on the GUI version 497 | // lcd.begin(); 498 | lcd.init(); 499 | lcd.backlight(); 500 | //------------------------------------------------------ 501 | #endif 502 | 503 | lcd.createChar(0, LockChar); 504 | #if defined(EthModule) 505 | // lcd.createChar(1, EthChar); 506 | #endif 507 | lcd.clear(); 508 | lcd.setCursor(0,0); 509 | lcd.print(F("Version:")); 510 | lcd.setCursor(7,1); 511 | lcd.print(REV); 512 | delay(1000); 513 | lcd.clear(); 514 | lcd.setCursor(0,0); 515 | #if defined(INPUT_SERIAL) 516 | lcd.print(F("SERIAL ")); 517 | #endif 518 | #if defined(ICOM_CIV) 519 | lcd.print(F("ICOM ")); 520 | lcd.print(CIV_ADRESS, HEX); 521 | lcd.print(F("h")); 522 | #endif 523 | #if defined(ICOM_ACC) 524 | lcd.print(F("ICOM ACC ")); 525 | #endif 526 | #if defined(KENWOOD_PC) 527 | lcd.print(F("KENWOOD ")); 528 | #endif 529 | #if defined(FLEX_6000) 530 | lcd.print(F("FLEX-6000 ")); 531 | #endif 532 | #if defined(YAESU_CAT) || defined(YAESU_CAT_OLD) || defined(YAESU_CAT_FT100) 533 | lcd.print(F("YAESU ")); 534 | #endif 535 | #if defined(INPUT_BCD) 536 | lcd.print(F("INPUT BCD ")); 537 | #endif 538 | #if !defined(INPUT_BCD) && !defined(ICOM_ACC) 539 | lcd.setCursor(10,0); 540 | lcd.print(SERBAUD); 541 | #endif 542 | lcd.setCursor(0,1); 543 | lcd.print(F("DC input ")); 544 | lcd.print(volt(analogRead(VoltagePin), ResistorCoeficient)); 545 | lcd.print(F("V")); 546 | delay(3000); 547 | lcd.clear(); 548 | #endif 549 | 550 | #if defined(EthModule) 551 | pinMode(Id1Pin, INPUT_PULLUP); 552 | pinMode(Id2Pin, INPUT_PULLUP); 553 | pinMode(Id3Pin, INPUT_PULLUP); 554 | NET_ID=GetBoardId(); 555 | LastMac = 0x00 + NET_ID; 556 | mac[5] = LastMac; 557 | EthernetCheck(); 558 | #endif 559 | InterruptON(1,1); // ptt, enc 560 | } 561 | //--------------------------------------------------------------------------------------------------------- 562 | 563 | void loop() { 564 | BandDecoderInput(); 565 | BandDecoderOutput(); 566 | LcdDisplay(); 567 | watchDog(); 568 | FrequencyRequest(); 569 | PttOff(); 570 | #if defined(EthModule) 571 | // RX_UDP(RemoteDevice, ThisDevice); 572 | EthernetCheck(); 573 | // WebServer(); 574 | #endif 575 | } 576 | 577 | // SUBROUTINES --------------------------------------------------------------------------------------------------------- 578 | 579 | /* 580 | ID FROM TO : BRO ; 581 | ID FROM TO : A B C ; 582 | 583 | TX 0rs:b; 584 | TX 0rs:123; 585 | */ 586 | 587 | void TxUDP(byte FROM, byte TO, byte A, byte B, byte C){ 588 | #if defined(EthModule) 589 | InterruptON(0,0); // ptt, enc 590 | RemoteSwLatencyAnsw = 0; // send command, wait to answer 591 | 592 | TxUdpBuffer[0] = NET_ID; 593 | TxUdpBuffer[1] = FROM; 594 | TxUdpBuffer[2] = TO; 595 | TxUdpBuffer[3] = B00111010; // : 596 | TxUdpBuffer[4] = A; 597 | TxUdpBuffer[5] = B; 598 | TxUdpBuffer[6] = C; 599 | TxUdpBuffer[7] = B00111011; // ; 600 | 601 | // BROADCAST 602 | if(A=='b' && B=='r' && C=='o'){ // b r o 603 | // if(A==B01100010 && B==B01110010 && C==B01101111){ // b r o 604 | // direct 605 | for (int i=0; i<15; i++){ 606 | if(DetectedRemoteSw[i][4]!=0){ 607 | RemoteSwIP = DetectedRemoteSw[i]; 608 | RemoteSwPort = DetectedRemoteSw[i][4]; 609 | UdpCommand.beginPacket(RemoteSwIP, RemoteSwPort); 610 | UdpCommand.write(TxUdpBuffer, sizeof(TxUdpBuffer)); // send buffer 611 | UdpCommand.endPacket(); 612 | // RemoteSwLatency[0] = millis(); // set START time mark UDP command latency 613 | 614 | #if defined(SERIAL_debug) 615 | Serial.print(F("TX direct ID-")); 616 | Serial.print(i); 617 | Serial.print(F(" ")); 618 | Serial.print(RemoteSwIP); 619 | Serial.print(F(":")); 620 | Serial.print(RemoteSwPort); 621 | Serial.print(F(" [")); 622 | Serial.print(TxUdpBuffer[0], HEX); 623 | for (int i=1; i<8; i++){ 624 | Serial.print(char(TxUdpBuffer[i])); 625 | // Serial.print(F(" ")); 626 | } 627 | Serial.println(F("]")); 628 | #endif 629 | } 630 | } 631 | 632 | // broadcast 633 | BroadcastIP = ~Ethernet.subnetMask() | Ethernet.gatewayIP(); 634 | UdpCommand.beginPacket(BroadcastIP, BroadcastPort); // Send to IP and port from recived UDP command 635 | UdpCommand.write(TxUdpBuffer, sizeof(TxUdpBuffer)); // send buffer 636 | UdpCommand.endPacket(); 637 | IpTimeout[0][0] = millis(); // set time mark 638 | 639 | #if defined(SERIAL_debug) 640 | Serial.print(F("TX broadcast ")); 641 | Serial.print(BroadcastIP); 642 | Serial.print(F(":")); 643 | Serial.print(BroadcastPort); 644 | Serial.print(F(" [")); 645 | Serial.print(TxUdpBuffer[0], HEX); 646 | for (int i=1; i<8; i++){ 647 | Serial.print(char(TxUdpBuffer[i])); 648 | // Serial.print(F(" ")); 649 | } 650 | Serial.println(F("]")); 651 | #endif 652 | 653 | // DATA 654 | }else{ 655 | if(DetectedRemoteSw[NET_ID][4]!=0 && PTT==false){ 656 | RemoteSwIP = DetectedRemoteSw[NET_ID]; 657 | RemoteSwPort = DetectedRemoteSw[NET_ID][4]; 658 | UdpCommand.beginPacket(RemoteSwIP, RemoteSwPort); 659 | UdpCommand.write(TxUdpBuffer, sizeof(TxUdpBuffer)); // send buffer 660 | UdpCommand.endPacket(); 661 | RemoteSwLatency[0] = millis(); // set START time mark UDP command latency 662 | 663 | #if defined(SERIAL_debug) 664 | Serial.println(); 665 | Serial.print(F("TX [")); 666 | Serial.print(TxUdpBuffer[0], HEX); 667 | for (int i=1; i<4; i++){ 668 | Serial.print(char(TxUdpBuffer[i])); 669 | } 670 | Serial.print(TxUdpBuffer[4], BIN); 671 | Serial.print(F("|")); 672 | Serial.print(TxUdpBuffer[5], BIN); 673 | Serial.print(F("|")); 674 | Serial.print(TxUdpBuffer[6], BIN); 675 | Serial.print(char(TxUdpBuffer[7])); 676 | Serial.print(F("] ")); 677 | Serial.print(RemoteSwIP); 678 | Serial.print(F(":")); 679 | Serial.println(RemoteSwPort); 680 | #endif 681 | } 682 | } 683 | InterruptON(1,1); // ptt, enc 684 | #endif 685 | } 686 | //------------------------------------------------------------------------------------------------------- 687 | /* 688 | ID FROM TO : CFM ; 689 | ID FROM TO : A B C ; 690 | 691 | RX 0sr:c; 692 | RX 0sr:123; 693 | */ 694 | 695 | void RX_UDP(char FROM, char TO){ 696 | #if defined(EthModule) 697 | InterruptON(0,0); // ptt, enc 698 | UDPpacketSize = UdpCommand.parsePacket(); // if there's data available, read a packet 699 | if (UDPpacketSize){ 700 | // UdpCommand.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); // read the packet into packetBufffer 701 | UdpCommand.read(packetBuffer, 30); // read the packet into packetBufffer 702 | // Print RAW 703 | // #if defined(SERIAL_debug) 704 | // Serial.print(F("RXraw ")); 705 | // for (int i = 0; i < 8; i++) { 706 | // Serial.print(packetBuffer[i]); 707 | // } 708 | // Serial.print(F(" ")); 709 | // Serial.print(UdpCommand.remoteIP()); 710 | // Serial.print(":"); 711 | // Serial.print(UdpCommand.remotePort()); 712 | // Serial.println(); 713 | // #endif 714 | // ID-FROM-TO filter 715 | if(String(packetBuffer[0], DEC).toInt()==NET_ID 716 | && packetBuffer[1]== FROM 717 | && packetBuffer[2]== TO 718 | && packetBuffer[3]== ':' 719 | && packetBuffer[7]== ';' 720 | ){ 721 | RemoteSwLatency[1] = (millis()-RemoteSwLatency[0])/2; // set latency (half path in ms us/2/1000) 722 | RemoteSwLatencyAnsw = 1; // answer packet received 723 | 724 | // RX Broadcast / CFM 725 | if((packetBuffer[4]== 'b' && packetBuffer[5]== 'r' && packetBuffer[6]== 'o') 726 | || (packetBuffer[4]== 'c' && packetBuffer[5]== 'f' && packetBuffer[6]== 'm') 727 | ){ 728 | IPAddress TmpAddr = UdpCommand.remoteIP(); 729 | DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [0]=TmpAddr[0]; // Switch IP addres storage to array 730 | DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [1]=TmpAddr[1]; 731 | DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [2]=TmpAddr[2]; 732 | DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [3]=TmpAddr[3]; 733 | DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [4]=UdpCommand.remotePort(); 734 | 735 | #if defined(LCD) 736 | lcd.clear(); 737 | lcd.setCursor(0, 0); 738 | lcd.print(F("Detect SW #")); 739 | lcd.print(packetBuffer[0], HEX); 740 | lcd.setCursor(0, 1); 741 | lcd.print(DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [0]); 742 | lcd.print(F(".")); 743 | lcd.print(DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [1]); 744 | lcd.print(F(".")); 745 | lcd.print(DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [2]); 746 | lcd.print(F(".")); 747 | lcd.print(DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [3]); 748 | lcd.print(F(":")); 749 | lcd.print(DetectedRemoteSw [hexToDecBy4bit(packetBuffer[0])] [4]); 750 | delay(4000); 751 | LcdNeedRefresh = true; 752 | lcd.clear(); 753 | #endif 754 | 755 | #if defined(SERIAL_debug) 756 | Serial.print(F("RX [")); 757 | Serial.print(packetBuffer[0], HEX); 758 | for(int i=1; i<8; i++){ 759 | Serial.print(char(packetBuffer[i])); 760 | } 761 | Serial.print(F("] ")); 762 | Serial.print(UdpCommand.remoteIP()); 763 | Serial.print(F(":")); 764 | Serial.println(UdpCommand.remotePort()); 765 | for (int i = 0; i < 16; i++) { 766 | Serial.print(i); 767 | Serial.print(F(" ")); 768 | Serial.print(DetectedRemoteSw [i] [0]); 769 | Serial.print(F(".")); 770 | Serial.print(DetectedRemoteSw [i] [1]); 771 | Serial.print(F(".")); 772 | Serial.print(DetectedRemoteSw [i] [2]); 773 | Serial.print(F(".")); 774 | Serial.print(DetectedRemoteSw [i] [3]); 775 | Serial.print(F(":")); 776 | Serial.println(DetectedRemoteSw [i] [4]); 777 | } 778 | #endif 779 | 780 | // RX DATA 781 | }else{ 782 | byte ButtonSequence = 0; 783 | // 4bit shift left OR 4bit shift right = 4bit shift rotate 784 | ButtonSequence = (byte)packetBuffer[4] >> 4 | (byte)packetBuffer[4] << 4; 785 | digitalWrite(ShiftOutLatchPin, LOW); // ready for receive data 786 | shiftOut(ShiftOutDataPin, ShiftOutClockPin, LSBFIRST, ButtonSequence); // buttons 787 | shiftOut(ShiftOutDataPin, ShiftOutClockPin, LSBFIRST, ButtonSequence); // buttons 788 | digitalWrite(ShiftOutLatchPin, HIGH); // switch to output pin 789 | 790 | #if defined(SERIAL_debug) 791 | Serial.print(F("RX [")); 792 | Serial.print(packetBuffer[0], HEX); 793 | for(int i=1; i<4; i++){ 794 | Serial.print(char(packetBuffer[i])); 795 | } 796 | Serial.print((byte)packetBuffer[4], BIN); 797 | Serial.print(F("|")); 798 | Serial.print((byte)packetBuffer[5], BIN); 799 | Serial.print(F("|")); 800 | Serial.print((byte)packetBuffer[6], BIN); 801 | Serial.print(F(";] ")); 802 | Serial.print(UdpCommand.remoteIP()); 803 | Serial.print(F(":")); 804 | Serial.print(UdpCommand.remotePort()); 805 | Serial.print(F(" Latency: ")); 806 | Serial.println(RemoteSwLatency[1]); 807 | #endif 808 | #if defined(LCD) 809 | LcdNeedRefresh = true; 810 | #endif 811 | } 812 | } // filtered end 813 | else{ 814 | #if defined(SERIAL_debug) 815 | Serial.println(F(" Different NET-ID, or bad packet format")); 816 | #endif 817 | } 818 | memset(packetBuffer, 0, sizeof(packetBuffer)); // Clear contents of Buffer 819 | } //end IfUdpPacketSice 820 | InterruptON(1,1); // ptt, enc 821 | #endif 822 | } 823 | //------------------------------------------------------------------------------------------------------- 824 | 825 | void EthernetCheck(){ 826 | #if defined(EthModule) 827 | if(millis()-EthLinkStatusTimer[0]>EthLinkStatusTimer[1] && EnableEthernet==1){ 828 | if ((Ethernet.linkStatus() == Unknown || Ethernet.linkStatus() == LinkOFF) && EthLinkStatus==1) { 829 | EthLinkStatus=0; 830 | #if defined(SERIAL_debug) 831 | Serial.println(F("Ethernet DISCONNECTED")); 832 | #endif 833 | }else if (Ethernet.linkStatus() == LinkON && EthLinkStatus==0) { 834 | EthLinkStatus=1; 835 | #if defined(SERIAL_debug) 836 | Serial.println(F("Ethernet CONNECTED")); 837 | #endif 838 | 839 | #if defined(LCD) 840 | lcd.clear(); 841 | lcd.setCursor(1, 0); 842 | lcd.print(F("Net-ID: ")); 843 | lcd.print(NET_ID); 844 | lcd.setCursor(1, 1); 845 | lcd.print(F("[DHCP-")); 846 | #endif 847 | if(EnableDHCP==1){ 848 | #if defined(LCD) 849 | lcd.print(F("ON]...")); 850 | #endif 851 | Ethernet.begin(mac); 852 | IPAddress CheckIP = Ethernet.localIP(); 853 | if( CheckIP[0]==0 && CheckIP[1]==0 && CheckIP[2]==0 && CheckIP[3]==0 ){ 854 | #if defined(LCD) 855 | lcd.clear(); 856 | lcd.setCursor(1, 0); 857 | lcd.print(F("DHCP FAIL")); 858 | lcd.setCursor(1, 1); 859 | lcd.print(F("please restart")); 860 | #endif 861 | while(1) { 862 | // infinite loop 863 | } 864 | } 865 | }else{ 866 | #if defined(LCD) 867 | lcd.print(F("OFF]")); 868 | #endif 869 | Ethernet.begin(mac, ip, myDns, gateway, subnet); 870 | } 871 | delay(2000); 872 | #if defined(LCD) 873 | lcd.clear(); 874 | lcd.setCursor(1, 0); 875 | lcd.print(F("IP address:")); 876 | lcd.setCursor(1, 1); 877 | lcd.print(Ethernet.localIP()); 878 | delay(2500); 879 | lcd.clear(); 880 | #endif 881 | 882 | server.begin(); // Web 883 | UdpCommand.begin(UdpCommandPort); // UDP 884 | TxUDP(ThisDevice, RemoteDevice, 'b', 'r', 'o'); 885 | 886 | } 887 | EthLinkStatusTimer[0]=millis(); 888 | } 889 | #endif 890 | } 891 | 892 | //--------------------------------------------------------------------------------------------------------- 893 | 894 | void TxBroadcastUdp(String MSG){ 895 | #if defined(EthModule) 896 | InterruptON(0,0); // ptt, enc 897 | BroadcastIP = ~Ethernet.subnetMask() | Ethernet.gatewayIP(); 898 | 899 | UdpCommand.beginPacket(BroadcastIP, BroadcastPort); // Send to IP and port from recived UDP command 900 | UdpCommand.print(MSG); 901 | UdpCommand.endPacket(); 902 | 903 | InterruptON(1,1); // ptt, enc 904 | #endif 905 | } 906 | 907 | //------------------------------------------------------------------------------------------------------- 908 | 909 | unsigned char hexToDecBy4bit(unsigned char hex) 910 | // convert a character representation of a hexidecimal digit into the actual hexidecimal value 911 | { 912 | if(hex > 0x39) hex -= 7; // adjust for hex letters upper or lower case 913 | return(hex & 0xf); 914 | } 915 | //------------------------------------------------------------------------------------------------------- 916 | 917 | void InterruptON(int ptt, int enc){ 918 | if(ptt==0){ 919 | detachInterrupt(digitalPinToInterrupt(PttDetectorPin)); 920 | }else if(ptt==1){ 921 | attachInterrupt(digitalPinToInterrupt(PttDetectorPin), PttDetector, FALLING); // need detachInterrupt in IncomingUDP() subroutine 922 | } 923 | } 924 | //--------------------------------------------------------------------------------------------------------- 925 | 926 | void PttDetector(){ // call from interupt 927 | // digitalWrite(PttOffPin, HIGH); 928 | PTT = true; 929 | #if defined(PTT_BY_BAND) 930 | FreqToBandRules(); 931 | bandSET(); 932 | #endif 933 | #if defined(LCD) 934 | LcdNeedRefresh = true; 935 | #endif 936 | PttTiming[0]=millis(); 937 | } 938 | //--------------------------------------------------------------------------------------------------------- 939 | 940 | void PttOff(){ 941 | if(PTT==true && millis()-PttTiming[0] > PttTiming[1] && digitalRead(PttDetectorPin)==HIGH && BAND!=0){ 942 | 943 | #if defined(EthModule) 944 | if(DetectedRemoteSw[NET_ID][4]!=0 && RemoteSwLatencyAnsw==1){ 945 | #endif 946 | 947 | // digitalWrite(PttOffPin, LOW); 948 | #if defined(EthModule) && defined(UdpBroadcastDebug_debug) 949 | TxBroadcastUdp("PttOff-" + String(DetectedRemoteSw[NET_ID][4]) + "-" + String(RemoteSwLatencyAnsw) ); 950 | #endif 951 | #if defined(PTT_BY_BAND) 952 | BAND=0; 953 | bandSET(); 954 | #endif 955 | PTT = false; 956 | #if defined(LCD) 957 | LcdNeedRefresh = true; 958 | #endif 959 | 960 | #if defined(EthModule) 961 | } 962 | #endif 963 | 964 | } 965 | } 966 | //--------------------------------------------------------------------------------------------------------- 967 | 968 | void FrequencyRequest(){ 969 | #if defined(REQUEST) 970 | if(REQUEST > 0 && (millis() - RequestTimeout[0] > RequestTimeout[1])){ 971 | 972 | #if defined(ICOM_CIV) 973 | txCIV(3, 0, CIV_ADRESS); // ([command], [freq]) 3=read 974 | #endif 975 | 976 | #if defined(KENWOOD_PC) || defined(YAESU_CAT) 977 | Serial.print(F("IF;")); 978 | Serial.flush(); // Waits for the transmission of outgoing serial data to complete 979 | #endif 980 | 981 | #if defined(FLEX_6000) 982 | Serial.print(F("FA;")); 983 | Serial.flush(); // Waits for the transmission of outgoing serial data to complete 984 | #endif 985 | 986 | #if defined(YAESU_CAT_OLD) 987 | Serial.write(0); // byte 1 988 | Serial.write(0); // byte 2 989 | Serial.write(0); // byte 3 990 | Serial.write(0); // byte 4 991 | Serial.write(3); // read freq 992 | Serial.flush(); 993 | #endif 994 | 995 | #if defined(YAESU_CAT_FT100) 996 | byte readStatusCMD[] = {0x00,0x00,0x00,0x00,0x10}; 997 | Serial.write(readStatusCMD,5); 998 | Serial.flush(); 999 | #endif 1000 | 1001 | RequestTimeout[0]=millis(); 1002 | } 1003 | #endif 1004 | } 1005 | //--------------------------------------------------------------------------------------------------------- 1006 | 1007 | #if defined(LCD) 1008 | void Space(int MAX, int LENGHT, char CHARACTER){ 1009 | int NumberOfSpace = MAX-LENGHT; 1010 | if(NumberOfSpace>0){ 1011 | for (int i=0; iLcdRefresh[1] || LcdNeedRefresh == true){ 1022 | 1023 | #if defined(EthModule) 1024 | if(EthLinkStatus==0){ 1025 | lcd.setCursor(0, 0); 1026 | lcd.print((char)1); // EthChar 1027 | lcd.print(F(" Please connect")); 1028 | lcd.setCursor(0, 1); 1029 | lcd.print(F(" ethernet ")); 1030 | }else{ 1031 | #endif 1032 | 1033 | lcd.setCursor(0,0); 1034 | int NameByBcd=0; 1035 | #if defined(MULTI_OUTPUT_BY_BCD) 1036 | if(SelectBank==2){ 1037 | NameByBcd=1; 1038 | }else if(SelectBank==4){ 1039 | NameByBcd=2; 1040 | }else if(SelectBank==8){ 1041 | NameByBcd=3; 1042 | } 1043 | #endif 1044 | #if defined(WATCHDOG) 1045 | if((millis() - WatchdogTimeout[0]) > WatchdogTimeout[1]) { 1046 | lcd.print("CAT timeout"); 1047 | }else{ 1048 | #endif 1049 | lcd.print(String(ANTname[BAND][NameByBcd]).substring(0, 11)); // crop up to 7 char 1050 | Space(11, String(ANTname[BAND][NameByBcd]).length(), ' '); 1051 | #if defined(WATCHDOG) 1052 | } 1053 | #endif 1054 | 1055 | #if defined(EthModule) 1056 | lcd.setCursor(0,0); 1057 | // if(RemoteSwLatencyAnsw==1 || (RemoteSwLatencyAnsw==0 && millis() < RemoteSwLatency[0]+RemoteSwLatency[1]*5)){ // if answer ok, or latency measure nod end 1058 | if(RemoteSwLatencyAnsw==1 || (RemoteSwLatencyAnsw==0 && millis() < RemoteSwLatency[0]+500) ){ // if answer ok, or latency measure nod end 1059 | lcd.print(String(ANTname[BAND][NameByBcd]).substring(0, 11)); // crop up to 7 char 1060 | Space(11, String(ANTname[BAND][NameByBcd]).length(), ' '); 1061 | }else{ 1062 | lcd.print(F("NetID-")); 1063 | lcd.print(NET_ID, HEX); 1064 | lcd.print(F(" n/a")); 1065 | } 1066 | #endif 1067 | 1068 | lcd.setCursor(11,0); 1069 | lcd.print(F(" ")); 1070 | #if defined(MULTI_OUTPUT_BY_BCD) 1071 | lcd.print(F("Ant")); 1072 | if(SelectBank==0){ 1073 | lcd.print(F("-")); 1074 | }else if(SelectBank==1){ 1075 | lcd.print(F("1")); 1076 | }else if(SelectBank==2){ 1077 | lcd.print(F("2")); 1078 | }else if(SelectBank==4){ 1079 | lcd.print(F("3")); 1080 | }else if(SelectBank==8){ 1081 | lcd.print(F("4")); 1082 | } 1083 | #endif 1084 | 1085 | #if defined(PWM_OUT) 1086 | lcd.print(PwmByBand[BAND]); 1087 | lcd.print(F(" ")); 1088 | #endif 1089 | #if !defined(PWM_OUT) 1090 | lcd.print(BCDmatrixOUT[3][BAND]); 1091 | lcd.print(BCDmatrixOUT[2][BAND]); 1092 | lcd.print(BCDmatrixOUT[1][BAND]); 1093 | lcd.print(BCDmatrixOUT[0][BAND]); 1094 | #endif 1095 | 1096 | lcd.setCursor(0,1); 1097 | #if defined(EthModule) 1098 | if(RemoteSwLatencyAnsw==1 || (RemoteSwLatencyAnsw==0 && millis() < RemoteSwLatency[0]+RemoteSwLatency[1]*5)){ // if answer ok, or latency measure nod end 1099 | // if(DetectedRemoteSw[NET_ID][4]!=0 && (RemoteSwLatencyAnsw==1 && millis() > RemoteSwLatency[0]+RemoteSwLatency[1]*5)){ 1100 | lcd.print(F("N")); 1101 | }else{ 1102 | lcd.print(F("!")); 1103 | } 1104 | #else 1105 | lcd.print(F("B")); 1106 | #endif 1107 | Space(2, String(BAND).length(), '-'); 1108 | lcd.print(BAND); 1109 | lcd.print(F(" ")); 1110 | 1111 | #if !defined(INPUT_BCD) && !defined(ICOM_ACC) 1112 | Space(7, String(freq/1000).length(), ' '); 1113 | PrintFreq(); 1114 | #endif 1115 | if(freq<100000000){ 1116 | lcd.setCursor(4, 1); 1117 | }else{ 1118 | lcd.setCursor(3, 1); 1119 | } 1120 | if(PTT==true){ 1121 | // lcd.write(byte(0)); // Lock icon 1122 | lcd.print((char)0); 1123 | // lcd.write(0); 1124 | }else{ 1125 | lcd.print(F(" ")); // Lock icon 1126 | } 1127 | #if !defined(INPUT_BCD) && !defined(ICOM_ACC) 1128 | lcd.setCursor(12,1); 1129 | lcd.print(F(" kHz")); 1130 | #endif 1131 | #if defined(ICOM_ACC) 1132 | lcd.setCursor(10,1); 1133 | lcd.print(AccVoltage); 1134 | lcd.print(F(" V")); 1135 | #endif 1136 | 1137 | LcdRefresh[0]=millis(); 1138 | LcdNeedRefresh = false; 1139 | 1140 | #if defined(EthModule) 1141 | } 1142 | #endif 1143 | } 1144 | #endif 1145 | } 1146 | //--------------------------------------------------------------------------------------------------------- 1147 | 1148 | #if defined(LCD) 1149 | void PrintFreq(){ 1150 | int longer=String(freq/1000).length(); 1151 | if(longer<4){ 1152 | lcd.print(F(" ")); 1153 | lcd.print(freq); 1154 | }else{ 1155 | lcd.print(String(freq/1000).substring(0, longer-3)); 1156 | lcd.print(F(".")); 1157 | lcd.print(String(freq/1000).substring(longer-3, longer)); 1158 | } 1159 | } 1160 | #endif 1161 | //--------------------------------------------------------------------------------------------------------- 1162 | 1163 | void WebServer(){ 1164 | #if defined(EthModuleXXX) 1165 | EthernetClient client = server.available(); 1166 | if (client) { 1167 | boolean currentLineIsBlank = true; 1168 | while (client.connected()) { 1169 | if (client.available()) { 1170 | char c = client.read(); 1171 | HTTP_req += c; 1172 | if (c == '\n' && currentLineIsBlank) { 1173 | client.println(F("HTTP/1.1 200 OK")); 1174 | client.println(F("Content-Type: text/html")); 1175 | client.println(F("Connection: close")); 1176 | client.println(); 1177 | client.println(F("")); 1178 | client.println(F("")); 1179 | client.println(F("")); 1180 | client.print(F("")); 1181 | client.println(F("Band Decoder")); 1182 | client.print(F("")); 1185 | client.println(F("")); 1186 | client.println(F("")); 1187 | client.println(F("")); 1188 | client.println(F("

Input TRX ")); 1201 | #if defined(INPUT_SERIAL) 1202 | client.print(F("Input serial")); 1203 | #endif 1204 | #if defined(ICOM_CIV) 1205 | client.print(F("ICOM CI-V
CI-V address ")); 1206 | client.print(CIV_ADRESS); 1207 | client.print(F("h")); 1208 | #endif 1209 | #if defined(KENWOOD_PC) 1210 | client.print(F("KENWOOD")); 1211 | #endif 1212 | #if defined(FLEX_6000) 1213 | client.print(F("FLEX-6000")); 1214 | #endif 1215 | #if defined(YAESU_CAT) 1216 | client.print(F("YAESU")); 1217 | #endif 1218 | #if defined(YAESU_CAT_OLD) 1219 | client.print(F("YAESU [Old]")); 1220 | #endif 1221 | #if defined(YAESU_CAT_FT100) 1222 | client.print(F("YAESU [FT100]")); 1223 | #endif 1224 | #if defined(INPUT_BCD) 1225 | client.print(F("BCD")); 1226 | #endif 1227 | #if defined(ICOM_ACC) 1228 | client.print(F("ICOM ACC voltage")); 1229 | #endif 1230 | client.print(F("
Baudrate ")); 1231 | client.print(SERBAUD); 1232 | client.print(F("
Watchdog second ")); 1233 | #if defined(WATCHDOG) 1234 | client.print(WATCHDOG); 1235 | client.print(F("
Request ")); 1236 | #endif 1237 | client.print(REQUEST); 1238 | client.print(F("ms
Band ")); 1239 | client.print(BAND); 1240 | client.print(F("
Frequency ")); 1241 | client.print(freq); 1242 | client.print(F("Hz
Power voltage: ")); 1243 | client.print(volt(analogRead(VoltagePin),ResistorCoeficient)); 1244 | client.println(F(" V

")); 1245 | client.println(F("

split↗

")); 1246 | client.println(F("")); 1247 | 1248 | // Serial.print(HTTP_req); 1249 | HTTP_req = ""; 1250 | break; 1251 | } 1252 | if (c == '\n') { 1253 | currentLineIsBlank = true; 1254 | } 1255 | else if (c != '\r') { 1256 | currentLineIsBlank = false; 1257 | } 1258 | } 1259 | } 1260 | delay(1); 1261 | client.stop(); 1262 | } 1263 | #endif 1264 | } 1265 | //--------------------------------------------------------------------------------------------------------- 1266 | 1267 | void NetId(){ 1268 | #if defined(EthModule) 1269 | if(millis()-GetNetIdTimer[0]>GetNetIdTimer[1]){ 1270 | if(NET_ID != GetBoardId()){ 1271 | NET_ID = GetBoardId(); 1272 | TxUDP(ThisDevice, RemoteDevice, 'b', 'r', 'o'); 1273 | } 1274 | } 1275 | #endif 1276 | } 1277 | //--------------------------------------------------------------------------------------------------------- 1278 | 1279 | #if defined(EthModule) 1280 | byte GetBoardId(){ 1281 | byte GetBcd = 0; 1282 | if(analogRead(Id1Pin)<50){ // 17 1023 1283 | GetBcd = GetBcd | (1<<0); // Set the n-th bit 1284 | } 1285 | if(analogRead(Id2Pin)<50){ // 0 170-970 1286 | GetBcd = GetBcd | (1<<1); // Set the n-th bit 1287 | } 1288 | if(analogRead(Id3Pin)<50){ // 0 290-830 1289 | GetBcd = GetBcd | (1<<2); // Set the n-th bit 1290 | } 1291 | return(GetBcd); 1292 | // if(digitalRead(Id4Pin)==0){ 1293 | // NET_ID = NET_ID | (1<<3); // Set the n-th bit 1294 | // } 1295 | } 1296 | #endif 1297 | //--------------------------------------------------------------------------------------------------------- 1298 | 1299 | float volt(int raw, float divider) { 1300 | // float voltage = (raw * 5.0) / 1024.0 * ResistorCoeficient; 1301 | float voltage = float(raw) * ArefVoltage * divider / 1023.0; 1302 | #if defined(SERIAL_debug) 1303 | Serial.print(F("Voltage ")); 1304 | Serial.println(voltage); 1305 | #endif 1306 | return voltage; 1307 | } 1308 | //------------------------------------------------------------------------------------------------------- 1309 | 1310 | void DCinMeasure(){ 1311 | if (millis() - VoltageRefresh[0] > VoltageRefresh[1]){ 1312 | DCinVoltage = volt(analogRead(VoltagePin), ResistorCoeficient); 1313 | #if defined(LCD) 1314 | if (DCinVoltage<7){ 1315 | lcd.setCursor(3, 0); 1316 | lcd.print(F(" Power LOW!")); 1317 | }else if (DCinVoltage>15){ 1318 | lcd.setCursor(2, 0); 1319 | lcd.print(F("Power HIGH!")); 1320 | } 1321 | #endif 1322 | VoltageRefresh[0] = millis(); // set time mark 1323 | } 1324 | } 1325 | //--------------------------------------------------------------------------------------------------------- 1326 | 1327 | void BandDecoderInput(){ 1328 | #if !defined(INPUT_BCD) 1329 | InterruptON(0,0); // ptt, enc 1330 | #endif 1331 | 1332 | //----------------------------------- Select Bank 1333 | #if defined(MULTI_OUTPUT_BY_BCD) && !defined(PWM_OUT) 1334 | SelectBank=B00000000; 1335 | if(digitalRead(BcdIn1Pin)==0){ 1336 | bitSet(SelectBank, 0); 1337 | }else if(digitalRead(BcdIn2Pin)==0){ 1338 | bitSet(SelectBank, 1); 1339 | }else if(digitalRead(BcdIn3Pin)==0){ 1340 | bitSet(SelectBank, 2); 1341 | }else if(digitalRead(BcdIn4Pin)==0){ 1342 | bitSet(SelectBank, 3); 1343 | } 1344 | // if BCD not selected, use first 1345 | if(SelectBank==B00000000){ 1346 | SelectBank=B00000001; 1347 | } 1348 | if(SelectBank!=SelectBankPrev){ 1349 | bandSET(); 1350 | SelectBankPrev=SelectBank; 1351 | LcdNeedRefresh=true; 1352 | } 1353 | #endif 1354 | 1355 | //----------------------------------- Input Serial 1356 | #if defined(INPUT_SERIAL) 1357 | while (Serial.available() > 0) { 1358 | BAND = Serial.parseInt(); 1359 | freq = Serial.parseInt(); 1360 | if (Serial.read() == '\n') { 1361 | bandSET(); 1362 | #if defined(SERIAL_echo) 1363 | serialEcho(); 1364 | #endif 1365 | } 1366 | } 1367 | #endif 1368 | 1369 | //----------------------------------- Icom ACC 1370 | #if defined(ICOM_ACC) 1371 | AccVoltage = volt(analogRead(ADPin), ResistorCoeficient); 1372 | if (counter == 5) { 1373 | // AccVoltage = float(AccVoltage) * ArefVoltage * Divider / 1023.0; 1374 | 1375 | //=====[ Icom ACC voltage range ]=========================================================== 1376 | 1377 | if (AccVoltage > 0.73 && AccVoltage < 1.00 ) {BAND=10;} // 6m * * * * * * * * * * * * * * * * 1378 | if (AccVoltage > 1.00 && AccVoltage < 1.09 ) {BAND=9;} // 10m * Need * 1379 | if (AccVoltage > 1.09 && AccVoltage < 1.32 ) {BAND=8;} // 12m * calibrated to your * 1380 | if (AccVoltage > 1.32 && AccVoltage < 1.55 ) {BAND=7;} // 15m * own ICOM * 1381 | if (AccVoltage > 1.55 && AccVoltage < 1.77 ) {BAND=6;} // 17m * ---------------- * 1382 | if (AccVoltage > 1.77 && AccVoltage < 2.24 ) {BAND=5;} // 20m * (These values have * 1383 | if (AccVoltage > 0.10 && AccVoltage < 0.50 ) {BAND=4;} // 30m * been measured by any) * 1384 | if (AccVoltage > 2.24 && AccVoltage < 2.73 ) {BAND=3;} // 40m * ic-746 * 1385 | if (AccVoltage > 2.73 && AccVoltage < 2.99 ) {BAND=2;} // 80m * * 1386 | if (AccVoltage > 2.99 && AccVoltage < 4.00 ) {BAND=1;} // 160m * * * * * * * * * * * * * * * * 1387 | if (AccVoltage > 0.00 && AccVoltage < 0.10 ) {BAND=0;} // parking 1388 | 1389 | //========================================================================================== 1390 | 1391 | bandSET(); // set outputs 1392 | delay (20); 1393 | }else{ 1394 | if (abs(prevAccVoltage-AccVoltage)>10) { // average 1395 | //means change or spurious number 1396 | prevAccVoltage=AccVoltage; 1397 | }else { 1398 | counter++; 1399 | prevAccVoltage=AccVoltage; 1400 | } 1401 | } 1402 | #if defined(SERIAL_echo) 1403 | serialEcho(); 1404 | Serial.print(AccVoltage); 1405 | Serial.println(F(" V")); 1406 | Serial.flush(); 1407 | #endif 1408 | 1409 | delay(500); // refresh time 1410 | #endif 1411 | 1412 | //----------------------------------- Icom CIV 1413 | #if defined(ICOM_CIV) 1414 | if (Serial.available() > 0) { 1415 | incomingByte = Serial.read(); 1416 | #if defined(DEBUG) 1417 | Serial.print(incomingByte); 1418 | Serial.print(F("|")); 1419 | Serial.println(incomingByte, HEX); 1420 | #endif 1421 | icomSM(incomingByte); 1422 | rdIS=""; 1423 | // if(rdI[10]==0xFD){ // state machine end 1424 | if(StateMachineEnd == true){ // state machine end 1425 | StateMachineEnd = false; 1426 | for (int i=9; i>=5; i-- ){ 1427 | if (rdI[i] < 10) { // leading zero 1428 | rdIS = rdIS + 0; 1429 | } 1430 | rdIS = rdIS + String(rdI[i], HEX); // append BCD digit from HEX variable to string 1431 | } 1432 | freq = rdIS.toInt(); 1433 | // Serial.println(freq); 1434 | // Serial.println("-------"); 1435 | FreqToBandRules(); 1436 | bandSET(); 1437 | 1438 | #if defined(SERIAL_echo) 1439 | serialEcho(); 1440 | #endif 1441 | RequestTimeout[0]=millis(); 1442 | } 1443 | } 1444 | #endif 1445 | 1446 | //----------------------------------- Yaesu BCD 1447 | #if defined(INPUT_BCD) && !defined(PWM_OUT) 1448 | if (millis() - BcdInRefresh[0] > BcdInRefresh[1]){ 1449 | BAND = 0; 1450 | if(digitalRead(BcdIn1Pin)==BcdInputFormat){ 1451 | BAND = BAND | (1<<3); // Set the n-th bit 1452 | } 1453 | if(digitalRead(BcdIn2Pin)==BcdInputFormat){ 1454 | BAND = BAND | (1<<2); 1455 | } 1456 | if(digitalRead(BcdIn3Pin)==BcdInputFormat){ 1457 | BAND = BAND | (1<<1); 1458 | } 1459 | if(digitalRead(BcdIn4Pin)==BcdInputFormat){ 1460 | BAND = BAND | (1<<0); 1461 | } 1462 | bandSET(); 1463 | #if defined(SERIAL_echo) 1464 | serialEcho(); 1465 | #endif 1466 | BcdInRefresh[0]=millis(); 1467 | } 1468 | #endif 1469 | 1470 | //----------------------------------- Kenwood 1471 | #if defined(KENWOOD_PC) 1472 | // Data exapmple 1473 | // IF00007151074 000000000030000080; 1474 | // IF00007032327 000000000030000080; 1475 | while (Serial.available()) { 1476 | rdKS=""; 1477 | #if defined(DEBUG) 1478 | byte incomingByte = Serial.read(); 1479 | Serial.write(incomingByte); 1480 | #else 1481 | Serial.readBytesUntil(lf, rdK, 38); // fill array from serial 1482 | if (rdK[0] == 73 && rdK[1] == 70){ // filter 1483 | for (int i=2; i<=12; i++){ // 3-13 position to freq 1484 | rdKS = rdKS + String(rdK[i]); // append variable to string 1485 | } 1486 | freq = rdKS.toInt(); 1487 | FreqToBandRules(); 1488 | bandSET(); // set outputs relay 1489 | 1490 | #if defined(SERIAL_echo) 1491 | serialEcho(); 1492 | #endif 1493 | } 1494 | memset(rdK, 0, sizeof(rdK)); // Clear contents of Buffer 1495 | #endif 1496 | } 1497 | #endif 1498 | 1499 | //----------------------------------- FLEX-6700 1500 | #if defined(FLEX_6000) 1501 | // http://www.flexradio.com/downloads/smartsdr-cat-user-guide-pdf/# 1502 | // Data exapmple FA 1503 | // FA00007167500; 1504 | // FA00014150000; 1505 | // Data exapmple IF 1506 | // IF00007151074 000000000030000080; 1507 | // IF000035730000100+0000000000090000000; when 3.573 MHz 1508 | while (Serial.available()) { 1509 | rdKS=""; 1510 | #if defined(DEBUG) 1511 | byte incomingByte = Serial.read(); 1512 | Serial.write(incomingByte); 1513 | #else 1514 | Serial.readBytesUntil(lf, rdK, 14); // fill array from serial 1515 | if (rdK[0] == 70 && rdK[1] == 65){ // filter 1516 | for (int i=2; i<=12; i++){ // 3-13 position to freq 1517 | rdKS = rdKS + String(rdK[i]); // append variable to string 1518 | } 1519 | freq = rdKS.toInt(); 1520 | FreqToBandRules(); 1521 | bandSET(); // set outputs relay 1522 | 1523 | #if defined(SERIAL_echo) 1524 | serialEcho(); 1525 | #endif 1526 | } 1527 | memset(rdK, 0, sizeof(rdK)); // Clear contents of Buffer 1528 | #endif 1529 | } 1530 | #endif 1531 | 1532 | //----------------------------------- Yaesu CAT 1533 | #if defined(YAESU_CAT) 1534 | while (Serial.available()) { 1535 | rdYS=""; 1536 | #if defined(DEBUG) 1537 | byte incomingByte = Serial.read(); 1538 | Serial.write(incomingByte); 1539 | #else 1540 | Serial.readBytesUntil(lf, rdY, 38); // fill array from serial 1541 | if (rdY[0] == 73 && rdY[1] == 70){ // filter 1542 | for (int i=5; i<=12; i++){ // 6-13 position to freq 1543 | rdYS = rdYS + String(rdY[i]); // append variable to string 1544 | } 1545 | freq = rdYS.toInt(); 1546 | FreqToBandRules(); 1547 | bandSET(); // set outputs relay 1548 | 1549 | #if defined(SERIAL_echo) 1550 | serialEcho(); 1551 | #endif 1552 | } 1553 | memset(rdY, 0, sizeof(rdY)); // Clear contents of Buffer 1554 | #endif 1555 | } 1556 | #endif 1557 | //----------------------------------- Yaesu CAT OLD 1558 | #if defined(YAESU_CAT_OLD) 1559 | while (Serial.available()) { 1560 | rdYOS=""; 1561 | #if defined(DEBUG) 1562 | byte incomingByte = Serial.read(); 1563 | Serial.write(incomingByte); 1564 | Serial.print(F(" ")); 1565 | #else 1566 | Serial.readBytesUntil('240', rdYO, 5); // fill array from serial (240 = 0xF0) 1567 | if (rdYO[0] != 0xF0 && rdYO[1] != 0xF0 && rdYO[2] != 0xF0 && rdYO[3] != 0xF0 && rdYO[4] != 0xF0 && rdYO[5] != 0xF0){ // filter 1568 | for (int i=0; i<4; i++ ){ 1569 | if (rdYO[i] < 10) { // leading zero 1570 | rdYOS = rdYOS + 0; 1571 | } 1572 | rdYOS = rdYOS + String(rdYO[i], HEX); // append BCD digit from HEX variable to string 1573 | } 1574 | rdYOS = rdYOS + 0; // append Hz 1575 | freq = rdYOS.toInt(); 1576 | FreqToBandRules(); 1577 | bandSET(); // set outputs relay 1578 | 1579 | #if defined(SERIAL_echo) 1580 | serialEcho(); 1581 | #endif 1582 | } 1583 | memset(rdYO, 0, sizeof(rdYO)); // Clear contents of Buffer 1584 | #endif 1585 | } 1586 | #endif 1587 | 1588 | //----------------------------------- Yaesu CAT FT100 1589 | #if defined(YAESU_CAT_FT100) 1590 | union ArrayToInteger { 1591 | byte array[5]; 1592 | uint32_t integer; 1593 | }; 1594 | ArrayToInteger convert; 1595 | while (Serial.available()) { 1596 | #if defined(DEBUG) 1597 | byte incomingByte = Serial.read(); 1598 | Serial.write(incomingByte); 1599 | #else 1600 | int numberOfBytes = Serial.readBytes(rdYO, 32); 1601 | if(numberOfBytes == 32){ 1602 | convert.array[4] = 0; 1603 | convert.array[3] = rdYO[1]; 1604 | convert.array[2] = rdYO[2]; 1605 | convert.array[1] = rdYO[3]; 1606 | convert.array[0] = rdYO[4]; 1607 | freq = convert.integer * 1.25; //fq data read back from FT-100 is the number of steps in 1.25Hz 1608 | 1609 | FreqToBandRules(); // map fq to band 1610 | bandSET(); // set outputs relay 1611 | } 1612 | memset(rdYO, 0, sizeof(rdYO)); // Clear contents of Buffer 1613 | #endif 1614 | } 1615 | #endif 1616 | 1617 | #if !defined(INPUT_BCD) 1618 | InterruptON(1,1); // ptt, enc 1619 | #endif 1620 | } 1621 | 1622 | //--------------------------------------------------------------------------------------------------------- 1623 | 1624 | void BandDecoderOutput(){ 1625 | 1626 | //=====[ Output Icom CIV ]======================= 1627 | #if defined(ICOM_CIV_OUT) 1628 | if(freq!= freqPrev1){ // if change 1629 | txCIV(0, freq, CIV_ADR_OUT); // 0 - set freq 1630 | freqPrev1 = freq; 1631 | } 1632 | #endif 1633 | //=====[ Output Kenwood PC ]===================== 1634 | #if !defined(REQUEST) && defined(KENWOOD_PC_OUT) 1635 | if(freq != freqPrev2){ // if change 1636 | String freqPCtx = String(freq); // to string 1637 | freqPCtx.reserve(12); 1638 | while (freqPCtx.length() < 11) { // leding zeros 1639 | freqPCtx = 0 + freqPCtx; 1640 | } 1641 | Serial.print("FA" + freqPCtx + ";"); // sets both VFO 1642 | Serial.print("FB" + freqPCtx + ";"); 1643 | // Serial.print("FA" + freqPCtx + ";"); // first packet not read every time 1644 | Serial.flush(); 1645 | freqPrev2 = freq; 1646 | } 1647 | #endif 1648 | //=====[ Output Yaesu CAT ]===================== 1649 | #if !defined(REQUEST) && defined(YAESU_CAT_OUT) 1650 | if(freq != freqPrev2){ // if change 1651 | String freqPCtx = String(freq); // to string 1652 | while (freqPCtx.length() < 8) { // leding zeros 1653 | freqPCtx = 0 + freqPCtx; 1654 | } 1655 | Serial.print("FA" + freqPCtx + ";"); // sets both VFO 1656 | Serial.print("FB" + freqPCtx + ";"); 1657 | Serial.flush(); 1658 | freqPrev2 = freq; 1659 | } 1660 | #endif 1661 | //=====[ Output Yaesu CAT OLD ]================= 1662 | #if !defined(REQUEST) && defined(YAESU_CAT_OUT_OLD) 1663 | if(freq != freqPrev2){ // if change 1664 | String freqPCtx = String(freq); // to string 1665 | while (freqPCtx.length() < 8) { // leding zeros 1666 | freqPCtx = 0 + freqPCtx; 1667 | } 1668 | Serial.write(1); // set freq 1669 | Serial.flush(); 1670 | freqPrev2 = freq; 1671 | } 1672 | #endif 1673 | 1674 | } 1675 | //--------------------------------------------------------------------------------------------------------- 1676 | 1677 | void bandSET() { // set outputs by BAND variable 1678 | 1679 | if(BAND==0 && previousBAND != 0){ // deactivate PTT 1680 | digitalWrite(PttOffPin, HIGH); 1681 | PTT = true; 1682 | #if defined(LCD) 1683 | LcdNeedRefresh = true; 1684 | #endif 1685 | }else if(BAND!=0 && previousBAND == 0){ // deactivate PTT 1686 | digitalWrite(PttOffPin, LOW); 1687 | } 1688 | 1689 | #if !defined(PTT_BY_BAND) 1690 | if((PTT==false && previousBAND != 0 ) || (PTT==true && previousBAND == 0)){ 1691 | #endif 1692 | for (int i = 0; i < NumberOfBoards; i++) { 1693 | ShiftByte[i] = B00000000; 1694 | } 1695 | 1696 | #if defined(MULTI_OUTPUT_BY_BCD) 1697 | for (int i = 0; i < 17; i++) { // outputs 1-8 1698 | for (int y = 0; y < 4; y++) { // bcd bit 1699 | if(bitRead(SelectBank,y)==1 && bitRead(matrix[BAND][i],y)==1){ 1700 | if(i<8){ 1701 | bitSet(ShiftByte[0], i); 1702 | }else{ 1703 | bitSet(ShiftByte[1], i-8); 1704 | } 1705 | } 1706 | } 1707 | } 1708 | #else 1709 | for (int i = 0; i < 8; i++) { // outputs 1-8 1710 | if(matrix[BAND][i]>0){ 1711 | ShiftByte[0] = ShiftByte[0] | (1<0){ 1716 | ShiftByte[1] = ShiftByte[1] | (1<0){ 1721 | ShiftByte[2] = ShiftByte[2] | (1<0){ 1726 | ShiftByte[3] = ShiftByte[3] | (1<0){ 1731 | ShiftByte[4] = ShiftByte[4] | (1<0; i--) { // outputs 9-16 1738 | shiftOut(ShiftOutDataPin, ShiftOutClockPin, LSBFIRST, ShiftByte[i-1]); 1739 | } 1740 | digitalWrite(ShiftOutLatchPin, HIGH); // switch to output pin 1741 | 1742 | #if !defined(INPUT_BCD) && !defined(MULTI_OUTPUT_BY_BCD) && !defined(PWM_OUT) 1743 | bcdOut(); 1744 | #endif 1745 | 1746 | #if defined(EthModule) 1747 | TxUDP(ThisDevice, RemoteDevice, ShiftByte[1], ShiftByte[0], 0x00); 1748 | #endif 1749 | 1750 | #if defined(LCD) 1751 | LcdNeedRefresh = true; 1752 | #endif 1753 | #if !defined(PTT_BY_BAND) 1754 | } 1755 | #endif 1756 | 1757 | #if defined(PWM_OUT) 1758 | analogWrite(PwmOutPin, PwmByBand[BAND]); 1759 | #endif 1760 | 1761 | // #if defined(EthModule) 1762 | // if(DetectedRemoteSw[NET_ID][4]==0 || RemoteSwLatencyAnsw==0){ 1763 | // // && millis() < RemoteSwLatency[0]+RemoteSwLatency[1]*5) ){ 1764 | // digitalWrite(PttOffPin, HIGH); 1765 | // #if defined(UdpBroadcastDebug_debug) 1766 | // TxBroadcastUdp("BandSet-" + String(DetectedRemoteSw[NET_ID][4]) + "-" + String(RemoteSwLatencyAnsw) ); 1767 | // #endif 1768 | // PTT = true; 1769 | // #if defined(LCD) 1770 | // LcdNeedRefresh = true; 1771 | // #endif 1772 | // } 1773 | // #endif 1774 | #if defined(EthModule_XXX) 1775 | #if defined(BcdIpRelay) 1776 | TxUDP(ThisDevice, RemoteDevice, BAND, 0x00, 0x00); 1777 | #else 1778 | byte A = 0x00; 1779 | for (int i = 0; i < 8; i++) { // outputs 1-8 1780 | if(matrix[BAND][i]==1){ 1781 | A = A | (1< ")); 1816 | Serial.println(ShiftByte[0], BIN); 1817 | Serial.flush(); 1818 | } 1819 | //--------------------------------------------------------------------------------------------------------- 1820 | 1821 | void bcdOut(){ 1822 | if (BCDmatrixOUT[0][BAND] == 1){ digitalWrite(BcdIn1Pin, HIGH); }else{ digitalWrite(BcdIn1Pin, LOW);} 1823 | if (BCDmatrixOUT[1][BAND] == 1){ digitalWrite(BcdIn2Pin, HIGH); }else{ digitalWrite(BcdIn2Pin, LOW);} 1824 | if (BCDmatrixOUT[2][BAND] == 1){ digitalWrite(BcdIn3Pin, HIGH); }else{ digitalWrite(BcdIn3Pin, LOW);} 1825 | if (BCDmatrixOUT[3][BAND] == 1){ digitalWrite(BcdIn4Pin, HIGH); }else{ digitalWrite(BcdIn4Pin, LOW);} 1826 | } 1827 | //--------------------------------------------------------------------------------------------------------- 1828 | 1829 | void watchDog() { 1830 | #if defined(WATCHDOG) 1831 | if((millis() - WatchdogTimeout[0]) > WatchdogTimeout[1]) { 1832 | BAND=0; 1833 | freq=0; 1834 | bandSET(); // set outputs 1835 | } 1836 | #endif 1837 | } 1838 | //--------------------------------------------------------------------------------------------------------- 1839 | 1840 | #if defined(ICOM_CIV) || defined(ICOM_CIV_OUT) 1841 | /*http://www.plicht.de/ekki/civ/civ-p0a.html 1842 | stty -F /dev/ttyUSB3 115200 raw -echo -echoe -echok -echoctl -echoke 1843 | echo -n -e '\xFE\xFE\x00\xA2\x00\x80\x48\x06\x44\x01\xFD' > /dev/ttyUSB3 1844 | echo -n -e '\xFE\xFE\x00\xA2\x00\x00\x50\x11\x32\x04\xFD' > /dev/ttyUSB3 1845 | echo -n -e '\xFE\xFE\x00\xA2\x00\x00\x20\x30\x96\x12\xFD' > /dev/ttyUSB3 1846 | FE|FE|0|56|0|70|99|99|52|0|FD 1847 | FE|FE|0|56|0|30| 0| 0|53|0|FD 1848 | IC9700 1849 | FE|FE|0|A2|0|80|48| 6|44|1|FD 2m 1850 | FE|FE|0|A2|0| 0|50|11|32|4|FD 70cm 1851 | FE|FE|0|A2|0| 0|20|30|96|12|FD 23cm 1852 | IC7300 1853 | FE|FE|0|74|0|0|0|15|70|0|FD 70 MHz 1854 | 1855 | */ 1856 | int icomSM(byte b){ // state machine 1857 | // This filter solves read from 0x00 0x05 0x03 commands and 00 E0 F1 address used by software 1858 | static bool Band23cm; 1859 | 1860 | // Serial.print(b, HEX); 1861 | // Serial.print(" | "); 1862 | // Serial.print(state); 1863 | // Serial.print(" | "); 1864 | // Serial.println(Band23cm); 1865 | 1866 | switch (state) { 1867 | case 1: if( b == 0xFE ){ state = 2; rdI[0]=b; rdI[10]=0x00; }; break; 1868 | case 2: if( b == 0xFE ){ state = 3; rdI[1]=b; }else{ state = 1;}; break; 1869 | // addresses that use different software 00-trx, e0-pc-ale, winlinkRMS, f1-winlink trimode 1870 | case 3: if( b == 0x00 || b == 0xE0 || b == 0x0E || b == 0xF1 ){ state = 4; rdI[2]=b; // choose command $03 1871 | }else if( b == CIV_ADRESS ){ state = 6; rdI[2]=b; 1872 | }else if( b == 0xFE ){ state = 3; rdI[1]=b; // FE (3x reduce to 2x) 1873 | }else{ state = 1;}; break; // or $05 1874 | 1875 | case 4: if( b == CIV_ADRESS ){ state = 5; rdI[3]=b; }else{ state = 1;}; break; // select command $03 1876 | case 5: if( b == 0x00 || b == 0x03 ){state = 8; rdI[4]=b; // freq 1877 | }else if( b == 0x04 ){state = 14; rdI[4]=b; // mode 1878 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1879 | }else{ state = 1;}; break; 1880 | 1881 | case 6: if( b == 0x00 || b == 0xE0 || b == 0xF1 ){ state = 7; rdI[3]=b; }else{ state = 1;}; break; // select command $05 1882 | case 7: if( b == 0x00 || b == 0x05 ){ state = 8; rdI[4]=b; }else{ state = 1;}; break; 1883 | 1884 | case 8: if( b <= 0x99 ){state = 9; rdI[5]=b; // 10Hz 1Hz 1885 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1886 | }else{state = 1;}; break; 1887 | case 9: if( b <= 0x99 ){state = 10; rdI[6]=b; // 1kHz 100Hz 1888 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1889 | }else{state = 1;}; break; 1890 | case 10: if( b <= 0x99 ){state = 11; rdI[7]=b; // 100kHz 10kHz 1891 | Band23cm = false; 1892 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1893 | }else{state = 1;}; break; 1894 | case 11: if( b <= 0x54 || b == 0x70 || b == 0x96 ){ state = 12; rdI[8]=b; // 10MHz 1Mhz 1895 | if(b == 0x96){ Band23cm = true; } 1896 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1897 | }else{ state = 1; } break; 1898 | case 12: if( b <= 0x01 || b == 0x04 || (b == 0x12 && Band23cm==true) ){state = 13; rdI[9]=b; // 1GHz 100MHz <-- 1xx/4xx/12xx MHz limit 1899 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1900 | }else{state = 1;}; break; 1901 | case 13: if( b == 0xFD ){state = 1; rdI[10]=b; StateMachineEnd = true; 1902 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1903 | }else{state = 1; rdI[10] = 0x00;}; break; 1904 | 1905 | case 14: if( b <= 0x12 ){state = 15; rdI[5]=b; 1906 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1907 | }else{state = 1;}; break; // Mode 1908 | case 15: if( b <= 0x03 ){state = 16; rdI[6]=b; 1909 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1910 | }else{state = 1;}; break; // Filter 1911 | case 16: if( b == 0xFD ){state = 1; rdI[7]=b; 1912 | }else if( b == 0xFE ){ state = 2; rdI[0]=b; // FE 1913 | }else{state = 1; rdI[7] = 0;}; break; 1914 | } 1915 | } 1916 | //--------------------------------------------------------------------------------------------------------- 1917 | bool CheckPartFreqInRange(byte FRQ, int PART){ 1918 | bool result=false; 1919 | for (int i=0; i<16; i++){ 1920 | if( PartFreqToByte(Freq2Band[i][0],PART)=0; x=x-2){ // loop for 5x2 char [xx xx xx xx xx] 1955 | freqCIVtxPart = freqCIVtx.substring(x,x+2); // cut freq to five part 1956 | Serial.write(hexToDec(freqCIVtxPart)); // HEX to DEC, because write as DEC format from HEX variable 1957 | } 1958 | } 1959 | Serial.write(253); // FD 1960 | // Serial.flush(); 1961 | while(Serial.available()){ // clear buffer 1962 | Serial.read(); 1963 | } 1964 | } 1965 | //--------------------------------------------------------------------------------------------------------- 1966 | 1967 | unsigned int hexToDec(String hexString) { 1968 | hexString.reserve(2); 1969 | unsigned int decValue = 0; 1970 | int nextInt; 1971 | for (int i = 0; i < hexString.length(); i++) { 1972 | nextInt = int(hexString.charAt(i)); 1973 | if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9); 1974 | if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15); 1975 | if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15); 1976 | nextInt = constrain(nextInt, 0, 15); 1977 | decValue = (decValue * 16) + nextInt; 1978 | } 1979 | return decValue; 1980 | } 1981 | //--------------------------------------------------------------------------------------------------------- 1982 | #endif 1983 | 1984 | void FreqToBandRules(){ 1985 | if (freq >=Freq2Band[0][0] && freq <=Freq2Band[0][1] ) {BAND=1;} // 160m 1986 | else if (freq >=Freq2Band[1][0] && freq <=Freq2Band[1][1] ) {BAND=2;} // 80m 1987 | else if (freq >=Freq2Band[2][0] && freq <=Freq2Band[2][1] ) {BAND=3;} // 40m 1988 | else if (freq >=Freq2Band[3][0] && freq <=Freq2Band[3][1] ) {BAND=4;} // 30m 1989 | else if (freq >=Freq2Band[4][0] && freq <=Freq2Band[4][1] ) {BAND=5;} // 20m 1990 | else if (freq >=Freq2Band[5][0] && freq <=Freq2Band[5][1] ) {BAND=6;} // 17m 1991 | else if (freq >=Freq2Band[6][0] && freq <=Freq2Band[6][1] ) {BAND=7;} // 15m 1992 | else if (freq >=Freq2Band[7][0] && freq <=Freq2Band[7][1] ) {BAND=8;} // 12m 1993 | else if (freq >=Freq2Band[8][0] && freq <=Freq2Band[8][1] ) {BAND=9;} // 10m 1994 | else if (freq >=Freq2Band[9][0] && freq <=Freq2Band[9][1] ) {BAND=10;} // 6m 1995 | else if (freq >=Freq2Band[10][0] && freq <=Freq2Band[10][1] ) {BAND=11;} // 2m 1996 | else if (freq >=Freq2Band[11][0] && freq <=Freq2Band[11][1] ) {BAND=12;} // 70cm 1997 | else {BAND=0;} // out of range 1998 | } 1999 | --------------------------------------------------------------------------------