Arduino CAT Controller

We want to build an Arduino-based antenna switch that will sniff the CAT commands sent to the radios and switch the antennas automatically based on the freq sent to the radio.  Here's the start of a blog and some reference articles:

https://github.com/pavelmc/FT857d

https://g0wfv.wordpress.com/2017/06/19/how-to-program-or-cat-control-your-rig-with-an-arduino/

CAT library: http://ve3bux.com/?page_id=501

This looks like a complete project: http://iz6ndw.blogspot.com/2012/01/arduino-radio-cat-interface-for-antenna.html

7/18/18 additional thoughts

  • Implement the CAT with a Y connector on the 847 serial cable. We only need to read the freq on one radio, and it's easier to get to the CAT cable on the 847 and connect the other connection to the Arduino
  • Use an Arduino Mega because it has multiple serial ports.  We'll pipe the CAT signal to the Arduino and it will repeat it out a serial port to the 847.
  • Also need to feed the CAT from the 847 back to PST Rotator.
  • May need to use interrupt-driven code to not drop CAT freq changes.
  • Need a SPST switch to turn off CAT control in case we want to set the antennas manually.

TAPR article with Arduino diagram and code - very useful: https://www.tapr.org/pdf/DCC2015-ArduinoCAT-Controller4HPSDR-G0ORX-1.pdf

Arduino library thread: http://forum.arduino.cc/index.php?topic=118988.0

Adruino CAT library: http://ve3bux.com/?page_id=501

Here's the first sketch:
/////////////////////////////////////////////////////////////////

//W2MMD Satellite Antenna Manager

// Pins for relay output
#define RelayPin2 51
#define RelayPin70 52
#define PreampRelayPin 53
// Relay pin low = SDR radio

// Pins for button controllers
#define ModeChangeButton 4

// Pins for LEDs
#define Yaesu70cm 22 //red
#define Yaesu2Meter 23 //yellow
#define SDR70cm 24 //blue
#define SDR2meter 25 //green
#define ButtonActive 27 //white
#define Debug 1 // debug mode

  int OpMode=0; //0 = vu, 1 = uv

void setup() {
  // put your setup code here, to run once:

  pinMode (RelayPin2, OUTPUT);
  pinMode (RelayPin70, OUTPUT);
  pinMode (PreampRelayPin, OUTPUT);

  pinMode (Yaesu70cm, OUTPUT);
  pinMode (Yaesu2Meter, OUTPUT);
  pinMode (SDR70cm, OUTPUT);
  pinMode (SDR2meter, OUTPUT);
  pinMode (ButtonActive, OUTPUT);

  pinMode (ModeChangeButton, INPUT_PULLUP);

  Serial.begin(9600);
  Serial1.begin (57600);
}

void CheckButtons()
{
  if (digitalRead (ModeChangeButton) == LOW)
    {
      digitalWrite (ButtonActive,HIGH);
      if (OpMode ==1)
        {
          OpMode = 0;
          if (Debug==1) Serial.println ("Changed mode to 0");
        }
        else
        {
          OpMode = 1;
          if (Debug==1) Serial.println ("Changed mode to 1");
        }
    }
  else // Button not pressed
    {
      digitalWrite (ButtonActive,LOW);
    }
    delay (10); // give time to release button


void SwitchAntennas ()
{
  if (OpMode == 1)// mode uv
  {
    digitalWrite (RelayPin2, LOW); //Receive on 2 meters
    digitalWrite (RelayPin70, HIGH); // Transmit on 70 CM
    digitalWrite (PreampRelayPin, LOW); //Preamp off
    if (Debug==1) Serial.println ("Mode is uv");
  }
  else // mode vu
    {
    digitalWrite (RelayPin2, HIGH); //Transmit on 2 meters
    digitalWrite (RelayPin70, LOW); // Receive on 70 CM
    digitalWrite (PreampRelayPin, HIGH); //Preamp on
    if (Debug==1) Serial.println ("Mode is vu");
    }
    delay (1000);
}

void SetLEDs()
{
  if (digitalRead (RelayPin2) == LOW)
    {
      digitalWrite (SDR2meter, HIGH);
      digitalWrite (Yaesu2Meter, LOW);
    }
    else
    {
      digitalWrite (SDR2meter, LOW);
      digitalWrite (Yaesu2Meter, HIGH);
    }
 
  if(digitalRead (RelayPin70) == LOW)
  {
    digitalWrite (Yaesu70cm,LOW);
    digitalWrite (SDR70cm, HIGH);
  }
  else
  {
    digitalWrite (Yaesu70cm,HIGH);
    digitalWrite (SDR70cm, LOW);
  } 
}

void CheckFreq ()
{
  char data; //incoming character

  // print the incoming data
  if (Serial1.available() > 0)
  {
    data = Serial1.read ();
    Serial.print (data);
  }
}

void loop()
{
  // put your main code here, to run repeatedly:
  CheckFreq ();
  CheckButtons ();
  SwitchAntennas();
  SetLEDs ();
}

-----------------------------------------------------------------------------------------------------------\
7/25/18 Using Putty connected to COM11 after shutting down SDR Console. Sending commands to that port from PST Rotator:

7/28/18 - Was able to sniff the CAT from the Y cable on the 847 and pipe it into the Arduino. Found that the data was hex characters that didn't appear to be decodable to the freq; however the same prefix numbers always used for the 425 and 144 MHz settings, so I just used them to change the switching. That worked! Now need to case it.  Here's the code:

ow ne//W2MMD Satellite Antenna Manager

// Pins for relay output
#define RelayPin2 51
#define RelayPin70 52
#define PreampRelayPin 53
// Relay pin low = SDR radio

// Pins for button controllers
#define ModeChangeButton 4
#define ToggleFreqControl 5

// Pins for LEDs
#define Yaesu70cm 22 //red
#define Yaesu2Meter 23 //yellow
#define SDR70cm 24 //blue
#define SDR2meter 25 //green
#define ButtonActive 27 //white
#define Debug 0 // debug mode

  int OpMode=0; //0 = vu, 1 = uv
  int SerialInt=0; //incoming ASCII value
  char SerialChar; // incoming chars
  int LastChar = 0;//Last character sent
  int FreqControlEnabled=1;

void setup() {
  // put your setup code here, to run once:

  pinMode (RelayPin2, OUTPUT);
  pinMode (RelayPin70, OUTPUT);
  pinMode (PreampRelayPin, OUTPUT);

  pinMode (Yaesu70cm, OUTPUT);
  pinMode (Yaesu2Meter, OUTPUT);
  pinMode (SDR70cm, OUTPUT);
  pinMode (SDR2meter, OUTPUT);
  pinMode (ButtonActive, OUTPUT);

  pinMode (ModeChangeButton, INPUT_PULLUP);
  pinMode (ToggleFreqControl, INPUT_PULLUP);
  Serial.begin(9600);
  Serial1.begin (57600,SERIAL_8N1);
}

void CheckButtons()
{
  if (digitalRead (ModeChangeButton) == LOW)
    {
      digitalWrite (ButtonActive,HIGH);
      if (OpMode ==1)
        {
          OpMode = 0;
          if (Debug==1) Serial.println ("Changed mode to 0");
        }
        else
        {
          OpMode = 1;
          if (Debug==1) Serial.println ("Changed mode to 1");
        }
        delay (1000); // give time to release button
    }
  else // Button not pressed
    {
      digitalWrite (ButtonActive,LOW);
    }
// Check Freq Control button   
  if (digitalRead (ToggleFreqControl) == LOW)
    {
      Serial.println ("Freq control button pressed");
      if (FreqControlEnabled == 1)
      {
        digitalWrite (ButtonActive,HIGH); // White LED means freq control disabled
        FreqControlEnabled=0;
        Serial.println ("Freq control disabled");
        delay (1000);
      }
      else
      {
        FreqControlEnabled=1;
        digitalWrite (ButtonActive,LOW); // White LED off
        Serial.println ("Freq control enabled");
        delay (1000);
      }
    } 
  }
void SwitchAntennas ()
{
  if (OpMode == 1)// mode uv
  {
    digitalWrite (RelayPin2, LOW); //Receive on 2 meters
    digitalWrite (RelayPin70, HIGH); // Transmit on 70 CM
    digitalWrite (PreampRelayPin, LOW); //Preamp off
    if (Debug==1) Serial.println ("Mode is uv");
  }
  else // mode vu
    {
    digitalWrite (RelayPin2, HIGH); //Transmit on 2 meters
    digitalWrite (RelayPin70, LOW); // Receive on 70 CM
    digitalWrite (PreampRelayPin, HIGH); //Preamp on
    if (Debug==1) Serial.println ("Mode is vu");
    }
    delay (10);
}

void SetLEDs()
{
  if (digitalRead (RelayPin2) == LOW)
    {
      digitalWrite (SDR2meter, HIGH);
      digitalWrite (Yaesu2Meter, LOW);
    }
    else
    {
      digitalWrite (SDR2meter, LOW);
      digitalWrite (Yaesu2Meter, HIGH);
    }
 
  if(digitalRead (RelayPin70) == LOW)
  {
    digitalWrite (Yaesu70cm,LOW);
    digitalWrite (SDR70cm, HIGH);
  }
  else
  {
    digitalWrite (Yaesu70cm,HIGH);
    digitalWrite (SDR70cm, LOW);
  } 
}

void CheckFreq ()
{
  // print the incoming data
  if (Serial1.available() > 0)
  {
    SerialInt = Serial1.read ();
//    Serial.print ("LastChar = ");
//    Serial.print (LastChar);
//    Serial.print (" Data=");
//    Serial.println (SerialInt);
    if (SerialInt == 0) // No data on this line
      {
        LastChar = 0;
      }
      else // non-zero data
      {
        if (LastChar == 0) // this the first freq set character
        {
          if (SerialInt == 94) // Setting to a 70 cm freq
          {
            OpMode = 1; // set uv
          }
         
          if (SerialInt == 157) // set 847 to 2 meters
          {
            OpMode = 0;// set vu
          }
         
          if (SerialInt == 63) // 847 to 10 meters
          {
            OpMode = 0;// set vu
          }
         
          if (SerialInt == 118) // 847 to NOAA
          {
            OpMode = 1;// set uv
          }   
        LastChar = SerialInt;     
      }
    } // non-zero data
  }
}
void loop()
{
  // put your main code here, to run repeatedly:
  if (FreqControlEnabled) CheckFreq ();
  CheckButtons ();
  SwitchAntennas();
  SetLEDs ();
}

Comments

Popular posts from this blog

How We Built the GOES Reception Project

GOES Satellite Reception Project

Building the Raspberry Pi NOAA Satellite Station