Arduino Band Decoder with FURUNO PA2500 Control

Here I use a multi band HF Yagi antenna, on a single boom and different band elements placed on it and controlled with a Heavy duty Antenna Switch. On normal operation, I am manually switching the Antenna, Solid state HF amp and other stuffs. In case of any carelessness, all goes wrong, sometimes I forget to select antenna, anplifier band ettc. So I thought to make it auto via CAT/RS232 control from the radio directly. More over Mr. Vikas Vasudevan VU2OT was also searching something like that as he is also having the same issue. So we both started searching for it on the internet and found some interesting at RemoteQTH web page.

This project is purely based on Band decoder with Arduino by the OK1HRA an open source code project. His project cannot be utilized as is for both of us as it won't meet our requirements like selecting antenna, amplifier band etc. So we decided to modify and assemble the code.

Parts List used in the project:

Following parts were collected from amazon.

  • 1. Nano V3.0 Development Board compatible with Arduino- just plug and play different modules.

  • 2. DC 12V 16 Channel Relay Module Interface Board with Opto coupler Protection LM2576 Power for Arduino,

  • 3. CD4514 4 Bit Latch/4-16 Line Decoder IC DIP-24 Package – for selecting antenna.

  • 4. MAX3232 RS232 to TTL Converter Module – for TRX to Nano communication.

  • 5. 4 line 20x4 LCD Display with Blue Backlight – for visual output

  • 6. 12 Position SP12T Rotary Switch & knob – for Auto / Manual Antenna section

  • 7. Connectors including, DC, Din pin9, Mic & Serial Port.

Initial assemblies before the components arrives:

Initial stage of the project starts with the modification of 400W Solid State Marine PA, FURUNO PA2500 for automatic LPF selection and its dual antenna output switching both manually if needed or automatically with the new Band Decoder. The front panel of PA is modified with a 7 pole rotary switch for Automatic and Manual switching of Amplifier LPF as required.

A DC to DC converter module using LM2596 is installed for 24V to 12V ON/OFF control of FURUNO. Out put +ve and -ve wires are connected to Toggle switch installed  at front side, 2pole 2way centre pins.


We have to use only 4 wires on J1 in FURUNO. Grey is connected to +Ve pole and White to -Ve pole of front panel ON/OFF Switch.

 
Also existing connector in the back side is removed and installed a 2pin DIN connector for PTT. The Green and Red wires from J1 is connected to this PTT Jack.

A 12 pole rotary switch which locked at 7th pole is installed at front and wired for BPF. 2set of wires are soldered in switch, one for automatic switching from Decoder and another to LPF connector of FURUNO. Centre pole is connected to positive line, from J3, pin1 tapped.

J3 pin 6,7,8,9,10,11 are the BPF switching wires to BPF Pcb and bottom side. Cut these wires blindly at J3 and connect to one set of wires soldered in Selector switch. Look like this.

 

Other set of wires from rotary switch is brought to bock panel and soldered to a 8pin mic connector for connecting to Band Decoder Unit. 

BPF and PTT Wiring OK now. Another toggle switch is installed in the front side and 3wires are soldered from it. Middle one goes to coil of an additional 12V DPDT relay installed in between the rear SO239 connectors for using 2 separate antenna Cable entry to Amplifier, like one from Yagi, another from vertical etc. Other 2 side wires are used to switch this relay either manually or automatically in auto mode.

One of these wire is connected to 12v on the rear new 8pin mic connector (above picture), when selected, this will manually enable the DPDT relay. Other wire is connected to 7th pole of this Mic connector for auto mode voltage injection by Band Decoder to enable relay.

Final Assembly look like this. With these modifications a FURUNO amp is ready for HF amplifier purpose.

By this time the Components arrived from amazon. I just assembled it and uploaded a modified sketch to check communication. It was nice to see working.


Then selected  a 24 x 24 x 8 cm size metal enclosure taken out from one of my oldest DDS VFO project to accommodate the above mentioned stuffs with enough spacing for wiring. The Arduino sketch was heavily modified, assembled & tested to suite the customization needs at VU2OT and VU2WJ. Front panel was designed by VU3YLI. The front panel molded with a 3 mm black acrylic sheet by a local vendor. Display also changed to a bigger one. CD4514B was soldered on a common pcb and attached to the main unit.





  

Here is the final testing at my shack. It was hard to complete LoL. 

The final Project at Mr. Vikas Vasudevan VU2OT. When it reached his Big Shack, It looked pretty good. I Thank Mr. Vikas Vasudevan VU2OT for his continuous support and motivation. With out him, it was sure, nothing was going to happen.

YouTube video is here 


Modified portion of code is here if anybody interested. 

////////////////////////////************************/////////////////
#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//LiquidCrystal_I2C lcd(0x3F,16,2); // Display  I2C 16 x 2
LiquidCrystal_I2C lcd(0x3F,20,4); // Display  I2C 20 x 4
//=====[ Inputs ]=============================================================================================

// #define INPUT_SERIAL       // telnet ascii input - cvs format [band],[freq]\n (serial.h)
// #define ICOM_CIV           // read frequency from CIV (icom_civ.h) ** you must enabled 'CI-V transceive' in TRX settings **
    #define KENWOOD_PC         // RS232 CAT (kenwood_pc.h)
// #define YAESU_CAT          // RS232 CAT (yaesu_cat.h) YAESU CAT since 2015 ascii format
// #define YAESU_CAT_OLD      // Old binary format RS232 CAT (yaesu_cat_old.h) <------- ** tested on FT-817 **
 //     #define YAESU_BCD     // TTL BCD in A  (yaesu_bcd.h)
//   #define ICOM_ACC           // voltage 0-8V on pin4 ACC(2) connector - need calibrate in (icom_acc.h)

//=====[ Outputs ]============================================================================================

// #define SERIAL_echo        // Feedback on serial line in same baudrate, CVS format <[band],[freq]>\n
// #define ICOM_CIV_OUT       // send frequency to CIV ** you must set TRX CIV_ADRESS, and disable ICOM_CIV **
// #define KENWOOD_PC_OUT     // send frequency to RS232 CAT ** for operation must disable REQUEST **
// #define YAESU_CAT_OUT      // send frequency to RS232 CAT ** for operation must disable REQUEST **
// #define BCD_OUT            // output 11-14 relay used as Yaesu BCD

//=====[ Settings ]===========================================================================================

 #define SERBAUD        9600  // [baud] Serial port in/out baudrate
 #define WATCHDOG       10    // [sec] determines the time, after which the all relay OFF, if missed next input data - uncomment for the enabled
 #define REQUEST       500     // use TXD output for sending frequency request (Kenwood PC, Yaesu CAT, Yaesu CAT old, Icom CIV)
 #define CIV_ADRESS   0x56  // CIV input HEX Icom adress (0x is prefix)
 #define CIV_ADR_OUT  0x56  // CIV output HEX Icom adress (0x is prefix)

//=====[ Sets band -->  to output in MATRIX table ]===========================================================

        boolean matrix[15][15] = { /*

        Band 0 --> */ { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, /*  If inputs out of range, or WATCHDOG timeout
\       Band 1 --> */ { 1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, /*
 \      Band 2 --> */ { 0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, /*
  \     Band 3 --> */ { 0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, /*
   \    Band 4 --> */ { 0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, /*
    \   Band 5 --> */ { 0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, /*
     \  Band 6 --> */ { 0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0 }, /*
IN    ) Band 7 --> */ { 0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0 }, /*
     /  Band 8 --> */ { 0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0 }, /*
    /   Band 9 --> */ { 0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0 }, /*
   /    Band 10 -> */ { 0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0 }, /*
  /     Band 11 -> */ { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0 }, /*
 /      Band 12 -> */ { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0 }, /*
/       Band 13 -> */ { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0 }, /*
        Band 14 -> */ { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0 }, /*
                        |   |   |   |   |   |   |   |   |   |   |   |   |   |
                        V   V   V   V   V   V   V   V   V   V   V   V   V   V   
                     -----------------------------------------------------------
                     |  1   2   3   4   5   6   7   8   9  10  11  12  13  14  |
                     -----------------------------------------------------------
                                          OUTPUTS RELAY*/
        };                                                 
//=====[ Output BCD ]=========================================================================================
     const   boolean BCDmatrixOUT[4][12] = { /*
        --------------------------------------------------------------------
        Band # to output relay   0   1   2   3   4   5   6   7   8   9  10
        (Yaesu BCD)                 160 80  60  40  30  20  17  15  12  10m
        --------------------------------------------------------------------
                                 |   |   |   |   |   |   |   |   |   |   |
                                 V   V   V   V   V   V   V   V   V   V   V
                            */ { 0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1 }, /* --> Relay 11
                            */ { 0,  0,  1,  1,  0,  0,  1,  1,  0,  0,  1,  1 }, /* --> Relay 12
                            */ { 0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  0 }, /* --> Relay 13
                            */ { 0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1 }, /* --> Relay 14
        */};
        
//============================================================================================================
  const char* ANTname[17][4] = {

/*    If enable #define MULTI_OUTPUT_BY_BCD
      you can fill name for another antennas on the same band
      dependency to select BCD input

Default or BCD-1   BCD-2   BCD-3    BCD-4
             |       |       |        |
*/    {"OUT OF BAND", "OUT OF BAND", "OUT OF BAND", "OUT OF BAND"},  // Band 0 (no data)
      {"INVERTED L",  "BCD-2", "BCD-3", "BCD-4"},      // Band 1
      {"HORI.DIPOLE", "BCD-2", "BCD-3", "BCD-4"},      // Band 2
      {"INVERTED V",  "BCD-2", "BCD-3", "BCD-4"},      // Band 3
      {"EF404VU",     "BCD-2", "BCD-3", "BCD-4"},      // Band 4
      {"INVERTED V",  "BCD-2", "BCD-3", "BCD-4"},      // Band 5
      {"EF20-15DUO",  "BCD-2", "BCD-3", "BCD-4"},      // Band 6
      {"TAHABEAM",    "BCD-2", "BCD-3", "BCD-4"},      // Band 7
      {"EF20-15DUO",  "BCD-2", "BCD-3", "BCD-4"},      // Band 8
      {"TAHABEAM",    "BCD-2", "BCD-3", "BCD-4"},      // Band 9
      {"EF105M",      "BCD-2", "BCD-3", "BCD-4"},      // Band 10
      {"EF0606",      "BCD-2", "BCD-3", "BCD-4"},      // Band 11
      {"60-Dipole",   "BCD-2", "BCD-3", "BCD-4"},      // Band 12
      {"20EL QUAD",   "BCD-2", "BCD-3", "BCD-4"},      // Band 13
      {"Dish 1.2m",   "BCD-2", "BCD-3", "BCD-4"},      // Band 14
      {"Dish 1.2m",   "BCD-2", "BCD-3", "BCD-4"},      // Band 15
  };
//============================================================================================================

char inByte;  // incoming byte from serial RX
String buffer = "";  // empty string to store incoming serial data -- a buffer
boolean stringComplete = false;  // whether the string is complete or not
/*                     Arduino Ports / in-out layout
-------------------------------------------------------------------------------
        PIND       |       PINB        |         PINC         | Arduino Ports
   6 5 4 3 2 1 x x | x x x 11 10 9 8 7 | x x x 16 15 14 13 12 | switch number
-------------------------------------------------------------------------------
*/

// Hardware key Port bit 0->7 to #out in matrix
int key[3][8] = {
      { 15, 15,  1,  2,  3,  4,  5,  6 }, // dataD
      {  7,  8,  9, 10, 11, 15, 15, 15 }, // dataB
      { 12, 13, 14, 15, 15, 15, 15, 15 }, // dataC
};
int bitNR;
int dataD;
int dataB;
int dataC;
int BAND = 0;
int BANDs;
long freq = 0;

#if defined(WATCHDOG)
    int previous;
    int timeout;
#endif
#if defined(REQUEST)
    int watchdog2 = 500;     // REQUEST refresh time [ms]
    int previous2;
    int timeout2;
#endif
// icom AD = A7;
//  A5  LCD SCL
//  A4  LCD SDA
//  A3  BCD1 > 409 = 2V = HIGH
//  A2  BCD2
//  A1  BCD3
//  A0  BCD4
// BCDmatrixOUT[0] 8
// BCDmatrixOUT[1] 9
// BCDmatrixOUT[2] 10
// BCDmatrixOUT[3] 11
// BCDmatrixOUT[EN] 12

    const int AD = A7;
    int VALUE = 0;
    int prevVALUE=0;
    float VOLTAGE = 0;
    int band = 0;
    int counter = 0;

    boolean BCD1;
    boolean BCD2;
    boolean BCD3;
    boolean BCD4;
    int  bandBCD;

#if defined(KENWOOD_PC) || defined(YAESU_CAT)
    int lf = 59;  // 59 = ;
#endif
#if defined(KENWOOD_PC)
    char rdK[37];   //read data kenwood
    String rdKS;    //read data kenwood string
#endif
#if defined(YAESU_CAT)
    char rdY[37];   //read data yaesu
    String rdYS;    //read data yaesu string
#endif
#if defined(YAESU_CAT_OLD)
    byte rdYO[37];   //read data yaesu
    String rdYOS;    //read data yaesu string
#endif
#if defined(ICOM_CIV) || defined(ICOM_CIV_OUT)
    int fromAdress = 14;              // 0E
    byte rdI[10];   //read data icom
    String rdIS;    //read data icom string
    long freqPrev1;
    byte incomingByte = 0;
    int state = 1;  // state machine
#endif
#if defined(KENWOOD_PC_OUT) || defined(YAESU_CAT_OUT)
    long freqPrev2;
#endif
//#if defined(BCD_OUT)
    char BCDout;
//#endif
/*
char * message = "Arduino Band Decoder";

void showLetters(int printStart, int startLetter)
{
 lcd.setCursor(printStart,1);
 for (int currentLetter = startLetter; currentLetter < strlen(message); currentLetter++)
 {
   lcd.print(message[currentLetter]);
 }
 lcd.print(" ");
 delay(300);
}
*/
void setup() {

   lcd.init();  
   lcd.init();
   lcd.backlight();
  delay(500);
  lcd.setCursor(2,0); //Start at character 4 on line 0
  lcd.print(" VU2OT de VU2WJ ");
    delay(200);
/*    
{
 for (int printStart = 15; printStart >= 0; printStart--)  //scroll on from right
 {
   showLetters(printStart, 0);
 }
 for (int letter = 1; letter <= strlen(8); letter++)  //scroll off to left
 {
   showLetters(0, letter);
 }
}

*/
  lcd.setCursor(0,2); //Start at character 4 on line 0
  lcd.print("ARDUINO BAND DECODER");
  delay(2000);
  lcd.clear();
 // Serial.begin(9600);   // setup serial speed
  buffer.reserve(64);    // reserve 64 bytes for the incoming data buffer; UARTS's buffer is only 64 bytes long... 😛
 
    #if defined(INPUT_SERIAL) || defined(SERIAL_echo) || defined(KENWOOD_PC) || defined(ICOM_CIV) || defined(YAESU_CAT)
        Serial.begin(SERBAUD);
        Serial.setTimeout(10);
    #endif
    #if defined(YAESU_CAT_OLD)
        Serial.begin(SERBAUD, SERIAL_8N2);
        Serial.setTimeout(10);
    #endif
    #if defined(KENWOOD_PC) || defined(YAESU_CAT)
//        CATdata.reserve(200);          // reserve bytes for the CATdata
    #endif

    DDRD = DDRD | B11111100; // D7-2 output ADDITIONAL SWITCHING, 1-0   (RX/TX)
    DDRB =        B00111111; // CD4514B , 12=LATCH     bit7-6 not use, D13-8 output
    DDRC =        B00000000; // A PORT ( 0 input,1 output )   A7- V input
}
//   bandSET();   
void loop() {
    dataD = B00000000;
    dataB = B00000000;
    dataC = B00000000;

    #if defined(INPUT_SERIAL)
        #include "serial.h"
    #endif
    #if defined(ICOM_ACC)
        #include "icom_acc.h"
    #endif
    #if defined(ICOM_CIV)
        #include "icom_civ.h"
    #endif
    #if defined(YAESU_BCD)
        #include "yaesu_bcd.h"
    #endif
    #if defined(KENWOOD_PC)
        #include "kenwood_pc.h"
    #endif
    #if defined(YAESU_CAT)
        #include "yaesu_cat.h"
    #endif
    #if defined(YAESU_CAT_OLD)
        #include "yaesu_cat_old.h"
    #endif
    //=====[ Output Icom CIV ]=======================
    #if defined(ICOM_CIV_OUT)
        if(freq!= freqPrev1){                    // if change
            txCIV(0, freq, CIV_ADR_OUT);         // 0 - set freq
            freqPrev1 = freq;
        }
    #endif
   bandSET();   
    //=====[ Output Kenwood PC ]=====================
    #if !defined(REQUEST) && defined(KENWOOD_PC_OUT)
        if(freq != freqPrev2){                     // if change
            String freqPCtx = String(freq);        // to string
            while (freqPCtx.length() < 11) {       // leding zeros
                freqPCtx = 0 + freqPCtx;
            }
           Serial.print("FA" + freqPCtx + ";");    // sets both VFO
           Serial.print("FB" + freqPCtx + ";");
 //          Serial.print("FA" + freqPCtx + ";");    // first packet not read every time
           Serial.flush();
           freqPrev2 = freq;
        }
    #endif
    //=====[ Output Yaesu CAT ]=====================
    #if !defined(REQUEST) && defined(YAESU_CAT_OUT)
        if(freq != freqPrev2){                     // if change
            String freqPCtx = String(freq);        // to string
            while (freqPCtx.length() < 8) {        // leding zeros
                freqPCtx = 0 + freqPCtx;
            }
           Serial.print("FA" + freqPCtx + ";");    // sets both VFO
           Serial.print("FB" + freqPCtx + ";");
           Serial.flush();
           freqPrev2 = freq;
        }
    #endif
    //=====[ Output Yaesu CAT OLD ]=================
    #if !defined(REQUEST) && defined(YAESU_CAT_OUT_OLD)
        if(freq != freqPrev2){                     // if change
            String freqPCtx = String(freq);        // to string
            while (freqPCtx.length() < 8) {        // leding zeros
                freqPCtx = 0 + freqPCtx;
           }
           Serial.write(1);                        // set freq
           Serial.flush();
           freqPrev2 = freq;
        }
    #endif
      lcd.setCursor(0,0);
          lcd.print("BAND   : ");
        if(BAND==0){
          lcd.print("OUT OF DATA");     }   
   else if(BAND==1){
          lcd.print("160-METER  ");  }
   else if(BAND==2){
          lcd.print("80-METER   ");  }
   else if(BAND==3){
          lcd.print("60-METER   ");  }
   else if(BAND==4){
          lcd.print("40-METER   ");  }
   else if(BAND==5){
          lcd.print("30-METER   ");  }
   else if(BAND==6){
          lcd.print("20-METER   ");  }
   else if(BAND==7){
          lcd.print("17-METER   ");  }
   else if(BAND==8){
          lcd.print("15-METER   ");  }
   else if(BAND==9){
          lcd.print("12-METER   ");  }
   else if(BAND==10){
          lcd.print("10-METER   ");  }
   else if(BAND==11){
          lcd.print(" 6-METER   ");  }
   else if(BAND==12){
          lcd.print("2-METER    ");  }
   else   lcd.print("           ");

         lcd.setCursor(0, 3);
         lcd.print("FURUNO :");    
       if(BAND==1)               {  digitalWrite(7, LOW); digitalWrite(6, LOW);digitalWrite(3, HIGH); lcd.print(" 1.6-2.4 MHz"); }
   else { digitalWrite(3, LOW);}
  //  if((BAND==2) || (BAND==3) || (BAND==4) || (BAND==5) )    {  digitalWrite(7, LOW); digitalWrite(6, LOW);digitalWrite(4, HIGH); lcd.print(" 2.4-3.6 MHz"); }
  // else { digitalWrite(4, LOW);}     
    if((BAND==2) || (BAND==3) || (BAND==4) || (BAND==5))   {  digitalWrite(7, LOW); digitalWrite(6, LOW);digitalWrite(5, HIGH); lcd.print(" 6.0- 10 MHz"); }
   else { digitalWrite(5, LOW);}
   if(BAND==6)        {  digitalWrite(7, LOW); digitalWrite(6, HIGH); lcd.print(" 10 - 18 MHz"); }     
   if(BAND==7)        { digitalWrite(6, LOW); digitalWrite(7, HIGH); lcd.print(" 18 - 30 MHz"); }   
   if(BAND==8)        { digitalWrite(6, LOW);  digitalWrite(7, HIGH); lcd.print(" 18 - 30 MHz"); }
   if(BAND==9)        {  digitalWrite(6, LOW); digitalWrite(7, HIGH); lcd.print(" 18 - 30 MHz"); }
   if(BAND==10)        {  digitalWrite(6, LOW); digitalWrite(7, HIGH); lcd.print(" 18 - 30 MHz"); }
   if(BAND==11)        {  digitalWrite(6, LOW); digitalWrite(7, HIGH); lcd.print(" 18 - 30 MHz"); }
   if(BAND==12)        {  digitalWrite(6, LOW); digitalWrite(7, HIGH); lcd.print(" 18 - 30 MHz"); }
   if(BAND==13)        {  digitalWrite(6, LOW); digitalWrite(7, HIGH); lcd.print(" 18 - 30 MHz"); }                    
    else
      
         lcd.setCursor(0, 1);
           lcd.print("FREQ   :");         
 #if !defined(INPUT_BCD) && !defined(ICOM_ACC)
      Space(6, String(freq/1000).length(), ' ');
      PrintFreq();
 #endif
       if(freq<100000000){
        lcd.setCursor(3, 1);
    }else{
       lcd.setCursor(2, 1);
        }
        #if !defined(INPUT_BCD) && !defined(ICOM_ACC)
          lcd.setCursor(15,1);
          lcd.print(" MHz");
        #endif
        #if defined(ICOM_ACC)
          lcd.setCursor(10,1);
          lcd.print(VOLTAGE);
          lcd.print(" V");
      #endif
        #if defined(YAESU_BCD)
      lcd.setCursor(15,0);
      lcd.print(" ");
        lcd.print(BCDmatrixOUT[3][BAND]);
        lcd.print(BCDmatrixOUT[2][BAND]);
        lcd.print(BCDmatrixOUT[1][BAND]);
        lcd.print(BCDmatrixOUT[0][BAND]);
        #endif
    lcd.setCursor(0,2);
 int NameByBcd=0;   
   lcd.print("ANTENNA: ");
   lcd.print(String(ANTname[BAND][NameByBcd]).substring(0, 12));  // crop up to 7 char
          Space(11, String(ANTname[BAND][NameByBcd]).length(), ' ');    
}
//=================================================================================
  void Space(int MAX, int LENGHT, char CHARACTER){
    int NumberOfSpace = MAX-LENGHT;
    if(NumberOfSpace>0){
      for (int i=0; i<NumberOfSpace; i++){
        lcd.print(CHARACTER);
      }
    }
  }
//===============================================
  void PrintFreq(){
    int longer=String(freq/1000).length();
    if(longer<4){
      lcd.print(" ");
      lcd.print(freq);
    }else{
      lcd.print(String(freq/1000).substring(0, longer-3));
      lcd.print(".");
      lcd.print(String(freq/1000).substring(longer-3, longer));
    }
  }
//=====[ Output relay ]=======================================================================================

void bandSET() {                                               // set outputs by BAND variable

        BANDs=13;

        if (BAND>=0 && BAND<=BANDs){
            for (bitNR=0; bitNR<8; bitNR++){
                // D                                          // portD
                if (matrix[BAND][(key[0][bitNR])-1] == 1){    // read in/out matrix over hw pin key matrix to PORTx
                    dataD = dataD << 1;                       // move 1 bit left
                    dataD = dataD | (1<<bitNR);               // 0-th bit to 1
                }
                // B                                          // portB
                if (matrix[BAND][(key[1][bitNR])-1] == 1){
                    dataB = dataB << 1;
                    dataB = dataB | (1<<bitNR);
                }
                // C                                          // portC
                if (matrix[BAND][(key[2][bitNR])-1] == 1){
                    dataC = dataC << 1;
                    dataC = dataC | (1<<bitNR);
                }
            }
                bcdOut();
        }
}

//=====[ Output serial ]======================================================================================

void serialEcho() {
    Serial.print("<");
    Serial.print(BAND);
    Serial.print(",");
    Serial.print(freq);
    Serial.println(">");
    Serial.flush();
}

    void bcdOut(){
    
        if (BCDmatrixOUT[0][BAND] == 1){ digitalWrite(8, HIGH); }else{ digitalWrite(8, LOW);;}
        if (BCDmatrixOUT[1][BAND] == 1){ digitalWrite(9, HIGH); }else{ digitalWrite(9, LOW);;}
        if (BCDmatrixOUT[2][BAND] == 1){ digitalWrite(10, HIGH); }else{ digitalWrite(10, LOW);;}
        if (BCDmatrixOUT[3][BAND] == 1){ digitalWrite(11, HIGH); }else{ digitalWrite(11, LOW);;}
        digitalWrite(12, HIGH);
        delay (1);        
        digitalWrite(12, LOW);
    }

//=====[ Watchdog ]===========================================================================================

#if defined(WATCHDOG)
    void watchDog() {
        timeout = millis()-previous;                   // check timeout
        if (timeout>(WATCHDOG*1000)){
            BAND=0;
            bandSET();                                 // set outputs
            previous = millis();                       // set time mark
        }
    }
#endif

//=====[ Icom CIV ]===========================================================================================

#if defined(ICOM_CIV) || defined(ICOM_CIV_OUT)

    int icomSM(byte b){      // state machine
        // This filter solves read from 0x00 0x05 0x03 commands and 00 E0 F1 address used by software
        switch (state) {
            case 1: if( b == 0xFE ){ state = 2; rdI[0]=b; }; break;
            case 2: if( b == 0xFE ){ state = 3; rdI[1]=b; }else{ state = 1;}; break;
            // addresses that use different software 00-trx, e0-pc-ale, winlinkRMS, f1-winlink trimode
            case 3: if( b == 0x00 || b == 0xE0 || b == 0xF1 ){ state = 4; rdI[2]=b;                             // choose command $03
              }else if( b == CIV_ADRESS ){ state = 6; rdI[2]=b;}else{ state = 1;}; break;                       // or $05

            case 4: if( b == CIV_ADRESS ){ state = 5; rdI[3]=b; }else{ state = 1;}; break;                      // select command $03
            case 5: if( b == 0x00 || b == 0x03 ){state = 8; rdI[4]=b; }else{ state = 1;}; break;

            case 6: if( b == 0x00 || b == 0xE0 || b == 0xF1 ){ state = 7; rdI[3]=b; }else{ state = 1;}; break;  // select command $05
            case 7: if( b == 0x00 || b == 0x05 ){ state = 8; rdI[4]=b; }else{ state = 1;}; break;            
            
            case 8: if( b <= 0x99 ){state = 9; rdI[5]=b; }else{state = 1;}; break;
            case 9: if( b <= 0x99 ){state = 10; rdI[6]=b; }else{state = 1;}; break;
           case 10: if( b <= 0x99 ){state = 11; rdI[7]=b; }else{state = 1;}; break;
           case 11: if( b <= 0x99 ){state = 12; rdI[8]=b; }else{state = 1;}; break;
           case 12: if( b <= 0x99 ){state = 13; rdI[9]=b; }else{state = 1;}; break;
           case 13: if( b == 0xFD ){state = 1; rdI[10]=b; }else{state = 1; rdI[10] = 0;}; break;
        }
    }

    int txCIV(int commandCIV, long dataCIVtx, int toAddress) {
        //Serial.flush();
        Serial.write(254);                                    // FE
        Serial.write(254);                                    // FE
        Serial.write(toAddress);                              // to adress
        Serial.write(fromAdress);                             // from OE
        Serial.write(commandCIV);                             // data
        if (dataCIVtx != 0){
            String freqCIVtx = String(dataCIVtx);             // to string
            String freqCIVtxPart;
            while (freqCIVtx.length() < 10) {                 // leding zeros
                freqCIVtx = 0 + freqCIVtx;
            }
            for (int x=8; x>=0; x=x-2){                       // loop for 5x2 char [xx xx xx xx xx]
                freqCIVtxPart = freqCIVtx.substring(x,x+2);   // cut freq to five part
                    Serial.write(hexToDec(freqCIVtxPart));    // HEX to DEC, because write as DEC format from HEX variable
            }                    
        }
        Serial.write(253);                                    // FD
        Serial.flush();
    }
    
    unsigned int hexToDec(String hexString) {
        unsigned int decValue = 0;
        int nextInt;
        for (int i = 0; i < hexString.length(); i++) {
            nextInt = int(hexString.charAt(i));
            if (nextInt >= 48 && nextInt <= 57) nextInt = map(nextInt, 48, 57, 0, 9);
            if (nextInt >= 65 && nextInt <= 70) nextInt = map(nextInt, 65, 70, 10, 15);
            if (nextInt >= 97 && nextInt <= 102) nextInt = map(nextInt, 97, 102, 10, 15);
            nextInt = constrain(nextInt, 0, 15);
            decValue = (decValue * 16) + nextInt;
        }
        return decValue;
    }
#endif

////////////////////////////************************/////////////////

Here is an alternate link for this project. 

https://malabarradiosociety.in/arduino-band-decoder/

Thanks

SHAJI - VU2WJ




Comments