Saturday, 26 June 2021

Arduino Clock






 Initial code using a 120x120 TFT display and a realtime clock module.






/*****************************************************************************
   The ST7789 IPS SPI display.is a 3.3v Device, do not use with a 5v Arduino
    unless you level shift.

    Display          |    Arduino
    -------------------------------------------
    VCC              |    3.3v
    GND              |    Gnd
    SCL              |    Pin 13 (SCK)
    SDA              |    Pin 11 (MOSI)
    RES              |    Pin 9
    DC               |    Pin 8
    BLK              |    Leave disconnected
 *****************************************************************************/

#include <Adafruit_GFX.h>
#include <Arduino_ST7789.h>
#include <SPI.h>
#include "RTClib.h"

#define TFT_DC    8
#define TFT_RST   9
#define TFT_MOSI  11
#define TFT_SCLK  13
#define DAYLIGHT_SAVING_PIN  5

// Clock Variables
int _Day, _OldDay = 0;
int _Hours, _OldHours = 0;
int _Minutes, _OldMinutes = 0;
int _DaylightSaving = 0;
int _xH, _yH, _OldxH, _OldyH = 0;
int _xM, _yM, _OldxM, _OldyM = 0;

Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK);   //No CS pin
RTC_DS3231 rtc;

void setup(void)
{
  pinMode(DAYLIGHT_SAVING_PIN, INPUT);                            // Setup daylight saving sw port
  digitalWrite(DAYLIGHT_SAVING_PIN, HIGH);

  // initialize the realtime clock
  rtc.begin();

  // initialize the display
  tft.init(240, 240);
  tft.setRotation(3);
  tft.fillScreen(BLACK);
  tft.setTextSize(2);
  DrawClockFace();
  DrawClockNumbers();
}

void loop()
{
  DateTime now = rtc.now();
  _Day = now.day();
  _Hours = now.hour();
  _Minutes = now.minute();

  if (digitalRead(DAYLIGHT_SAVING_PIN) == 0)
    delay(50);
  if (digitalRead(DAYLIGHT_SAVING_PIN) == 0)
    _DaylightSaving = !_DaylightSaving;

  if (_DaylightSaving == 1)
    _Hours++;

  if ((_Hours != _OldHours) || (_Minutes != _OldMinutes))
  {
    UpdateHands();
    DrawClockNumbers();
    _OldHours = _Hours;
    _OldMinutes = _Minutes;
  }

  if (_Day != _OldDay)
  {
    UpdateDate();
    _OldDay = _Day;
  }

  delay(1000);
}

void UpdateHands()
{
  //x = x0 + r * Math.Cos(theta * Math.PI / 180);
  //y = y0 + r * Math.Sin(theta * Math.PI / 180);

  //Hours hands (erase old hours hand then redraw new one)
  tft.drawLine((tft.width() / 2), (tft.height() / 2), _OldxH, _OldyH, BLACK);

  _xH = (tft.width() / 2) + 70 * cos((((30 * _Hours) + (0.5 * _Minutes)) - 90) * PI / 180);
  _yH = (tft.height() / 2) + 70 * sin((((30 * _Hours) + (0.5 * _Minutes)) - 90) * PI / 180);
  tft.drawLine((tft.width() / 2), (tft.height() / 2), _xH, _yH, WHITE);
  _OldyH = _yH;
  _OldxH = _xH;

  //Minutes hands (erase old minutes hand then redraw new one)
  tft.drawLine((tft.width() / 2), (tft.height() / 2), _OldxM, _OldyM, BLACK);

  _xM = (tft.width() / 2) + 95 * cos(((6 * _Minutes) - 90) * PI / 180);
  _yM = (tft.height() / 2) + 95 * sin(((6 * _Minutes) - 90) * PI / 180);
  tft.drawLine((tft.width() / 2), (tft.height() / 2), _xM, _yM, WHITE);
  _OldxM = _xM;
  _OldyM = _yM;

  tft.fillCircle((tft.width() / 2), (tft.height() / 2), 3, WHITE);
}

void UpdateDate()
{
  tft.setTextColor(BLACK);
  tft.setCursor(210, 220);
  tft.print(_OldDay);

  tft.setTextColor(GREEN);
  tft.setCursor(210, 220);
  tft.print(_Day);

  tft.setTextColor(WHITE);
}

void DrawClockFace()
{
  int _x1, _y1 = 0;

  //x = x0 + r * Math.Cos(theta * Math.PI / 180);
  //y = y0 + r * Math.Sin(theta * Math.PI / 180);

  tft.drawCircle((tft.width() / 2), (tft.height() / 2), 119, WHITE);
  tft.drawCircle((tft.width() / 2), (tft.height() / 2), 118, WHITE);

  // Minute marks
  for (int x = 0; x <= 60; x++)
  {
    _x1 = (tft.width() / 2) + 118 * cos(((6 * x) - 90) * PI / 180);
    _y1 = (tft.height() / 2) + 118 * sin(((6 * x) - 90) * PI / 180);
    tft.drawLine((tft.width() / 2), (tft.height() / 2), _y1, _x1, WHITE);
  }
  tft.fillCircle((tft.width() / 2), (tft.height() / 2), 110, BLACK);

  // 5 minute marks
  for (int x = 0; x <= 12; x++)
  {
    _x1 = (tft.width() / 2) + 118 * cos(((30 * x) - 90) * PI / 180);
    _y1 = (tft.height() / 2) + 118 * sin(((30 * x) - 90) * PI / 180);
    tft.drawLine((tft.width() / 2), (tft.height() / 2), _y1, _x1, WHITE);
  }
  tft.fillCircle((tft.width() / 2), (tft.height() / 2), 105, BLACK);
}

void DrawClockNumbers()
{
  tft.setTextColor(WHITE);
  tft.setCursor(163, 32);
  tft.print("1");

  tft.setCursor(196, 65);
  tft.print("2");

  tft.setCursor(210, 113);
  tft.print("3");

  tft.setCursor(199, 160);
  tft.print("4");

  tft.setCursor(164, 193);
  tft.print("5");

  tft.setCursor(115, 207);
  tft.print("6");

  tft.setCursor(70, 195);
  tft.print("7");

  tft.setCursor(35, 160);
  tft.print("8");

  tft.setCursor(20, 113);
  tft.print("9");

  tft.setCursor(33, 66);
  tft.print("10");

  tft.setCursor(66, 34);
  tft.print("11");

  tft.setCursor(109, 20);
  tft.print("12");
}

Thursday, 14 January 2021

Simple SSB Transceiver

 Please see the YouTube channel for details: https://www.youtube.com/channel/UCSNPW3_gzuMJcX_ErBZTv2g




AF Amp






IF Amps










Mixers







BPF




Mic Amp





AGC/Limiter


Relays




RF PA Experiments

1st iteration





2nd iteration






****************************************************************
Final Arduino code

#include <LiquidCrystal_I2C.h>
#include <si5351.h>

static const long bandStart = 3500000;          // start of VFO range
static const long bandEnd =   3900000;          // end of VFO range
static const long bandInit =  3690000;          // where to initially set the frequency
volatile long freq = 3690000;                   // the current freq
volatile long oldfreq = 0;                      // the previous freq
volatile long rx_LSB_BFO_freq = 8997200;           // High side injection thus SB inversion.
volatile long rx_USB_BFO_freq = 8998700;           // High side injection thus SB inversion.
volatile long tx_LSB_BFO_freq = 8996300;           // High side injection thus SB inversion.
volatile long tx_USB_BFO_freq = 8999800;           // High side injection thus SB inversion.
volatile long radix = 1000;                     // How much to change the frequency by, clicking the Up Down switches
volatile long oldradix = 0;                     // the previous radix
volatile int mode = 0;                          // the current mode (0=LSB, 1=USB)
volatile int oldmode = 0;                       // the previous mode (0=LSB, 1=USB)
volatile int TX = 0;                            // 0=RX, 1=TX
volatile int oldTX = 1;                         // the old TX
unsigned int encoderA, encoderB, encoderC = 1;  // rotary encoder variables

// Rotary encoder pins and other inputs
static const int rotAPin = 2;
static const int rotBPin = 3;
static const int radixPin = 4;
static const int modePin = 5;
static const int PTTPin = 6;

// Instantiate the Objects
LiquidCrystal_I2C lcd(0x3F, 16, 2);              // 3F the address of the LCD
Si5351 si5351;


void setup()
{
  // Set up I/O pins
  pinMode(rotAPin, INPUT);
  digitalWrite(rotAPin, HIGH);                    // internal pull-up enabled
  pinMode(rotBPin, INPUT);
  digitalWrite(rotBPin, HIGH);                    // internal pull-up enabled
  pinMode(radixPin, INPUT);
  digitalWrite(radixPin, HIGH);                   // internal pull-up enabled
  pinMode(modePin, INPUT);
  digitalWrite(modePin, HIGH);                    // internal pull-up enabled
  pinMode(PTTPin, INPUT);
  digitalWrite(PTTPin, LOW);                      // internal pull-up disabled

  // Initialize the display
  lcd.begin();
  lcd.backlight();
  lcd.noCursor();

  // Initialize the DDS
  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 62100);         // 62100 is the specific calibration factor for this Si5351 board
  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_2MA);   // 2 mA for HB mixers
  si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_2MA);   // 2 mA for HB mixers
}

void loop()
{
  CheckEncoder();
  CheckRadixSwitch();
  CheckModeSwitch();
  CheckPTTPin();
}

void CheckEncoder()
{
  byte encoderA = digitalRead(rotAPin);
  byte encoderB = digitalRead(rotBPin);

  if ((encoderA == HIGH) && (encoderC == LOW))
  {
    if (encoderB == HIGH)
      // Decrease frequency
      freq = constrain(freq - radix, bandStart, bandEnd);
    else
      // Increase frequency
      freq = constrain(freq + radix, bandStart, bandEnd);
  }
  encoderC = encoderA;

  if (freq != oldfreq)
  {
    UpdateDisplay();
    SendFrequency();
    oldfreq = freq;
  }
}

void CheckRadixSwitch()
{
  if (digitalRead(radixPin) == 0)
  {
    radix = radix / 10;
    if (radix < 1)
      radix = 1000;
    delay(200);
  }

  if (radix != oldradix)
  {
    UpdateRadixDisplay();
    oldradix = radix;
  }
}

void CheckModeSwitch()
{
  if (digitalRead(modePin) == 0)
    mode = 0;                                 // 0=LSB
  if (digitalRead(modePin) == 1)
    mode = 1;                                 // 1=USB

  if (mode != oldmode)
  {
    UpdateDisplay();
    SendFrequency();
    oldmode = mode;
  }
}

void CheckPTTPin()
{
  TX = digitalRead(PTTPin);
  if (TX != oldTX)
  {
    UpdateDisplay();
    SendFrequency();
    oldTX = TX;
  }
}

void UpdateDisplay()
{
  // freq
  lcd.setCursor(0, 0);
  lcd.print(freq);
  // mode
  lcd.setCursor(0, 1);
  if (mode == 0)
    lcd.print("LSB");
  else
    lcd.print("USB");
  lcd.setCursor(10, 1);
  // PTT
  lcd.setCursor(4, 1);
  if (TX == 1)
    lcd.print("TX");
  if (TX == 0)
    lcd.print("RX");
  // callsign
  lcd.setCursor(10, 1);
  lcd.print("ZL2CTM");
}

void UpdateRadixDisplay()
{
  // radix
  if (radix == 1000)
  {
    lcd.setCursor(9, 0);
    lcd.print("      ");
    lcd.setCursor(9, 0);
    lcd.print(radix);
    lcd.setCursor(14, 0);
    lcd.print("Hz");
  }
  if (radix == 100)
  {
    lcd.setCursor(9, 0);
    lcd.print("      ");
    lcd.setCursor(10, 0);
    lcd.print(radix);
    lcd.setCursor(14, 0);
    lcd.print("Hz");
  }
  if (radix == 10)
  {
    lcd.setCursor(9, 0);
    lcd.print("      ");
    lcd.setCursor(11, 0);
    lcd.print(radix);
    lcd.setCursor(14, 0);
    lcd.print("Hz");
  }
  if (radix == 1)
  {
    lcd.setCursor(9, 0);
    lcd.print("      ");
    lcd.setCursor(12, 0);
    lcd.print(radix);
    lcd.setCursor(14, 0);
    lcd.print("Hz");
  }
}

void SendFrequency()
{
  if (mode == 0)                                                          // LSB
  {
    if (TX == 1)                                                          // Transmit
    {
      si5351.set_freq(((tx_LSB_BFO_freq + freq) * 100ULL), SI5351_CLK2);     // VFO
      si5351.set_freq((tx_LSB_BFO_freq * 100ULL), SI5351_CLK0);              // BFO
    }
    else                                                                  // Receive
    {
      si5351.set_freq(((rx_LSB_BFO_freq + freq) * 100ULL), SI5351_CLK0);     // VFO
      si5351.set_freq((rx_LSB_BFO_freq * 100ULL), SI5351_CLK2);              // BFO
    }
  }

  if (mode == 1)                                                          // USB
  {
    if (TX == 1)                                                          // Transmit
    {
      si5351.set_freq(((tx_USB_BFO_freq + freq) * 100ULL), SI5351_CLK2);     // VFO
      si5351.set_freq((tx_USB_BFO_freq * 100ULL), SI5351_CLK0);              // BFO
    }
    else                                                                  // Receive
    {
      si5351.set_freq(((rx_USB_BFO_freq + freq) * 100ULL), SI5351_CLK0);     // VFO
      si5351.set_freq((rx_USB_BFO_freq * 100ULL), SI5351_CLK2);              // BFO
    }
  }
}

Monday, 11 January 2021

Friday, 13 November 2020

Go QRP Portable SSB Rig

 


IF Amplifiers (1st and 2nd)







VFO, BFO Frequencies and AF Amplifier





LPF after RF PA


Receive-Transmit Switching



Microphone Amplifier





RF PA








Arduino Code


#include <LiquidCrystal_I2C.h>
#include <si5351.h>

static const long bandStart = 3500000;          // start of VFO range
static const long bandEnd =   3900000;          // end of VFO range
static const long bandInit =  3690000;          // where to initially set the frequency
volatile long freq = 3690000;                   // the current freq
volatile long oldfreq = 0;                      // the previous freq
volatile long LSB_BFO_freq = 10748350;          // High side injection thus SB inversion.
volatile long USB_BFO_freq = 10751750;          // High side injection thus SB inversion.
volatile long radix = 1000;                     // How much to change the frequency by, clicking the Up Down switches
volatile long oldradix = 0;                     // the previous radix
volatile int mode = 0;                          // the current mode (0=LSB, 1=USB)
volatile int oldmode = 0;                       // the previous mode (0=LSB, 1=USB)
volatile int TX = 0;                            // 0=RX, 1=TX
volatile int oldTX = 1;                         // the old TX
unsigned int encoderA, encoderB, encoderC = 1;  // rotary encoder variables

// Rotary encoder pins and other inputs
static const int rotAPin = 2;
static const int rotBPin = 3;
static const int radixPin = 4;
static const int modePin = 5;
static const int PTTPin = 6;

// Instantiate the Objects
LiquidCrystal_I2C lcd(0x3F, 16, 2);              // 3F the address of the LCD
Si5351 si5351;


void setup()
{
  // Set up I/O pins
  pinMode(rotAPin, INPUT);
  digitalWrite(rotAPin, HIGH);                    // internal pull-up enabled
  pinMode(rotBPin, INPUT);
  digitalWrite(rotBPin, HIGH);                    // internal pull-up enabled
  pinMode(radixPin, INPUT);
  digitalWrite(radixPin, HIGH);                   // internal pull-up enabled
  pinMode(modePin, INPUT);
  digitalWrite(modePin, HIGH);                    // internal pull-up enabled
  pinMode(PTTPin, INPUT);
  digitalWrite(PTTPin, LOW);                      // internal pull-up disabled

  // Initialize the display
  lcd.begin();
  lcd.backlight();
  lcd.noCursor();

  // Initialize the DDS
  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 62100);         // 62100 is the specific calibration factor for this Si5351 board
  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);
  si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_8MA);
}

void loop()
{
  CheckEncoder();
  CheckRadixSwitch();
  CheckModeSwitch();
  CheckPTTPin();
}

void CheckEncoder()
{
  byte encoderA = digitalRead(rotAPin);
  byte encoderB = digitalRead(rotBPin);

  if ((encoderA == HIGH) && (encoderC == LOW))
  {
    if (encoderB == HIGH)
      // Decrease frequency
      freq = constrain(freq - radix, bandStart, bandEnd);
    else
      // Increase frequency
      freq = constrain(freq + radix, bandStart, bandEnd);
  }
  encoderC = encoderA;

  if (freq != oldfreq)
  {
    UpdateDisplay();
    SendFrequency();
    oldfreq = freq;
  }
}

void CheckRadixSwitch()
{
  if (digitalRead(radixPin) == 0)
  {
    radix = radix / 10;
    if (radix < 1)
      radix = 1000;
    delay(200);
  }

  if (radix != oldradix)
  {
    UpdateRadixDisplay();
    oldradix = radix;
  }
}

void CheckModeSwitch()
{
  if (digitalRead(modePin) == 0)
    mode = 0;                                 // 0=LSB
  if (digitalRead(modePin) == 1)
    mode = 1;                                 // 1=USB

  if (mode != oldmode)
  {
    UpdateDisplay();
    SendFrequency();
    oldmode = mode;
  }
}

void CheckPTTPin()
{
  TX = digitalRead(PTTPin);
  if (TX != oldTX)
  {
    UpdateDisplay();
    SendFrequency();
    oldTX = TX;
  }
}

void UpdateDisplay()
{
  // freq
  lcd.setCursor(0, 0);
  lcd.print(freq);
  // mode
  lcd.setCursor(0, 1);
  if (mode == 0)
    lcd.print("LSB");
  else
    lcd.print("USB");
  lcd.setCursor(10, 1);
  // PTT
  lcd.setCursor(4, 1);
  if (TX == 1)
    lcd.print("TX");
  if (TX == 0)
    lcd.print("RX");
  // callsign
  lcd.setCursor(10, 1);
  lcd.print("ZL2CTM");
}

void UpdateRadixDisplay()
{
  // radix
  if (radix == 1000)
  {
    lcd.setCursor(9, 0);
    lcd.print("      ");
    lcd.setCursor(9, 0);
    lcd.print(radix);
    lcd.setCursor(14, 0);
    lcd.print("Hz");
  }
  if (radix == 100)
  {
    lcd.setCursor(9, 0);
    lcd.print("      ");
    lcd.setCursor(10, 0);
    lcd.print(radix);
    lcd.setCursor(14, 0);
    lcd.print("Hz");
  }
  if (radix == 10)
  {
    lcd.setCursor(9, 0);
    lcd.print("      ");
    lcd.setCursor(11, 0);
    lcd.print(radix);
    lcd.setCursor(14, 0);
    lcd.print("Hz");
  }
  if (radix == 1)
  {
    lcd.setCursor(9, 0);
    lcd.print("      ");
    lcd.setCursor(12, 0);
    lcd.print(radix);
    lcd.setCursor(14, 0);
    lcd.print("Hz");
  }
}

void SendFrequency()
{
  if (mode == 0)                                                          // LSB
  {
    if (TX == 1)                                                          // Transmit
    {
      si5351.set_freq(((LSB_BFO_freq + freq) * 100ULL), SI5351_CLK2);     // VFO
      si5351.set_freq((LSB_BFO_freq * 100ULL), SI5351_CLK0);              // BFO
    }
    else                                                                  // Receive
    {
      si5351.set_freq(((LSB_BFO_freq + freq) * 100ULL), SI5351_CLK0);     // VFO
      si5351.set_freq((LSB_BFO_freq * 100ULL), SI5351_CLK2);              // BFO
    }
  }

  if (mode == 1)                                                          // USB
  {
    if (TX == 1)                                                          // Transmit
    {
      si5351.set_freq(((USB_BFO_freq + freq) * 100ULL), SI5351_CLK2);     // VFO
      si5351.set_freq((USB_BFO_freq * 100ULL), SI5351_CLK0);              // BFO
    }
    else                                                                  // Receive
    {
      si5351.set_freq(((USB_BFO_freq + freq) * 100ULL), SI5351_CLK0);     // VFO
      si5351.set_freq((USB_BFO_freq * 100ULL), SI5351_CLK2);              // BFO
    }
  }
}

Thursday, 25 June 2020

Digital Modes Transceiver

Initial CAT Code. The radio emulates a Kenwood TS-480. (https://www.kenwood.com/i/products/info/amateur/ts_480/pdf/ts_480_pc.pdf)
Refer to the YouTube video for an explanation.




#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

int debug = 0;

const int numChars = 14;
volatile long freq = 0;
boolean newCATcmd = false;

char CATcmd[numChars] = {'0'};    // an array to store the received CAT data
int freq10GHz = 0;
int freq1GHz = 0;
int freq100MHz = 0;
int freq10MHz = 1;
int freq1MHz = 4;
int freq100kHz = 1;
int freq10kHz = 2;
int freq1kHz = 3;
int freq100Hz = 4;
int freq10Hz = 5;
int freq1Hz = 6;
int RIT, XIT, MEM1, MEM2, RX, TX, VFO, SCAN, SIMPLEX, CTCSS, TONE1, TONE2 = 0;
int MODE = 2;

SoftwareSerial mySerial(31, 32);      // RX, TX
LiquidCrystal_I2C lcd(0x3F, 16, 2);

void setup()
{
  lcd.begin();
  lcd.backlight();
  CalcFreq();

  Serial.begin(9600);

  // Debug serial port
  mySerial.begin(9600);
}

void loop()
{
  rxCATcmd();
  analyseCATcmd();
}

void rxCATcmd()
{
  int index = 0;
  char endMarker = ';';
  char data;                    // CAT commands are ASCII characters

  while ((Serial.available() > 0) && (newCATcmd == false))
  {
    data = Serial.read();

    if (data != endMarker)
    {
      CATcmd[index] = data;
      index++;

      if (index >= numChars)
        index = numChars - 1;   // leave space for the \0 array termination
    }
    else
    {
      CATcmd[index] = ';';      // Indicate end of command
      debug = index;            // Needed later to print out the command
      CATcmd[index + 1] = '\0'; // terminate the array
      index = 0;                // reset for next CAT command
      newCATcmd = true;
    }
  }
}

void analyseCATcmd()
{
  if (newCATcmd == true)
  {
    newCATcmd = false;        // reset for next CAT time

    // Debug printing
    mySerial.println();
    for (int x = 0; x <= debug; x++)
      mySerial.print(CATcmd[x]);
    mySerial.print("\t");

    if ((CATcmd[0] == 'F') && (CATcmd[1] == 'A') && (CATcmd[2] == ';'))              // must be freq get command
      Command_GETFreqA();

    else if ((CATcmd[0] == 'F') && (CATcmd[1] == 'A') && (CATcmd[13] == ';'))        // must be freq set command
      Command_SETFreqA();

    else if ((CATcmd[0] == 'I') && (CATcmd[1] == 'F') && (CATcmd[2] == ';'))
      Command_IF();

    else if ((CATcmd[0] == 'I') && (CATcmd[1] == 'D') && (CATcmd[2] == ';'))
      Command_ID();

    else if ((CATcmd[0] == 'P') && (CATcmd[1] == 'S') && (CATcmd[2] == ';'))
      Command_PS();

    else if ((CATcmd[0] == 'P') && (CATcmd[1] == 'S') && (CATcmd[2] == '1'))
      Command_PS1();

    else if ((CATcmd[0] == 'A') && (CATcmd[1] == 'I') && (CATcmd[2] == ';'))
      Command_AI();

    else if ((CATcmd[0] == 'A') && (CATcmd[1] == 'I') && (CATcmd[2] == '0'))
      Command_AI0();

    else if ((CATcmd[0] == 'M') && (CATcmd[1] == 'D') && (CATcmd[2] == ';'))
      Command_MD();

    else if ((CATcmd[0] == 'R') && (CATcmd[1] == 'X') && (CATcmd[2] == ';'))
      Command_RX();

    else if ((CATcmd[0] == 'T') && (CATcmd[1] == 'X') && (CATcmd[2] == ';'))
      Command_TX();

    else if ((CATcmd[0] == 'T') && (CATcmd[1] == 'X') && (CATcmd[2] == '1'))
      Command_TX1();

    else if ((CATcmd[0] == 'R') && (CATcmd[1] == 'S') && (CATcmd[2] == ';'))
      Command_RS();

    Serial.flush();       // Get ready for next command
    //delay(50);            // Needed to eliminate WSJT-X connection errors
  }
}

void Command_ID()
{
  Serial.print("ID020;");
  mySerial.print("ID020;");
}

void Command_PS()
{
  Serial.print("PS1;");
  mySerial.print("PS1;");
}

void Command_PS1()
{
  Serial.print("PS1;");
  mySerial.print("PS1;");
}

void Command_GETFreqA()
{
  Serial.print("FA");
  Serial.print(freq10GHz);
  Serial.print(freq1GHz);
  Serial.print(freq100MHz);
  Serial.print(freq10MHz);
  Serial.print(freq1MHz);
  Serial.print(freq100kHz);
  Serial.print(freq10kHz);
  Serial.print(freq1kHz);
  Serial.print(freq100Hz);
  Serial.print(freq10Hz);
  Serial.print(freq1Hz);
  Serial.print(";");

  mySerial.print("FA");
  mySerial.print(freq10GHz);
  mySerial.print(freq1GHz);
  mySerial.print(freq100MHz);
  mySerial.print(freq10MHz);
  mySerial.print(freq1MHz);
  mySerial.print(freq100kHz);
  mySerial.print(freq10kHz);
  mySerial.print(freq1kHz);
  mySerial.print(freq100Hz);
  mySerial.print(freq10Hz);
  mySerial.print(freq1Hz);
  mySerial.print(";");
}

void Command_SETFreqA()
{
  freq10GHz = CATcmd[2] - 48;       // convert ASCII char to int equivalent. int 0 = ASCII 48;
  freq1GHz = CATcmd[3] - 48;
  freq100MHz = CATcmd[4] - 48;
  freq10MHz = CATcmd[5] - 48;
  freq1MHz = CATcmd[6] - 48;
  freq100kHz = CATcmd[7] - 48;
  freq10kHz = CATcmd[8] - 48;
  freq1kHz = CATcmd[9] - 48;
  freq100Hz = CATcmd[10] - 48;
  freq10Hz = CATcmd[11] - 48;
  freq1Hz = CATcmd[12] - 48;

  //Command_GETFreqA();               // now RSP with FA

  Serial.print("FA");
  Serial.print(freq10GHz);
  Serial.print(freq1GHz);
  Serial.print(freq100MHz);
  Serial.print(freq10MHz);
  Serial.print(freq1MHz);
  Serial.print(freq100kHz);
  Serial.print(freq10kHz);
  Serial.print(freq1kHz);
  Serial.print(freq100Hz);
  Serial.print(freq10Hz);
  Serial.print(freq1Hz);
  Serial.print(";");

  mySerial.print("FA");
  mySerial.print(freq10GHz);
  mySerial.print(freq1GHz);
  mySerial.print(freq100MHz);
  mySerial.print(freq10MHz);
  mySerial.print(freq1MHz);
  mySerial.print(freq100kHz);
  mySerial.print(freq10kHz);
  mySerial.print(freq1kHz);
  mySerial.print(freq100Hz);
  mySerial.print(freq10Hz);
  mySerial.print(freq1Hz);
  mySerial.print(";");

  CalcFreq();
}

void CalcFreq()
{
  freq = (
                (10000000000L * freq10GHz) +
                (1000000000L * freq1GHz) +
                (100000000L * freq100MHz) +
                (10000000L * freq10MHz) +
                (1000000L * freq1MHz) +
                (100000L * freq100kHz) +
                (10000L * freq10kHz) +
                (1000L * freq1kHz) +
                (100L * freq100Hz) +
                (10L * freq10Hz) +
                freq1Hz);

  // Debug print
  lcd.setCursor(0, 1);
  lcd.print(freq10GHz);
  lcd.print(freq1GHz);
  lcd.print(freq100MHz);
  lcd.print(freq10MHz);
  lcd.print(freq1MHz);
  lcd.print(freq100kHz);
  lcd.print(freq10kHz);
  lcd.print(freq1kHz);
  lcd.print(freq100Hz);
  lcd.print(freq10Hz);
  lcd.print(freq1Hz);

  lcd.setCursor(0, 0);      // Col, Row
  lcd.print("                ");
  lcd.setCursor(0, 0);
  lcd.print(freq);
}

void Command_IF()
{
  Serial.print("IF");
  Serial.print(freq10GHz);        // P1
  Serial.print(freq1GHz);
  Serial.print(freq100MHz);
  Serial.print(freq10MHz);
  Serial.print(freq1MHz);
  Serial.print(freq100kHz);
  Serial.print(freq10kHz);
  Serial.print(freq1kHz);
  Serial.print(freq100Hz);
  Serial.print(freq10Hz);
  Serial.print(freq1Hz);
  Serial.print("00000");          // P2 Always five 0s
  Serial.print("+0000");          // P3 RIT/XIT freq +/-9990
  Serial.print(RIT);              // P4
  Serial.print(XIT);              // P5
  Serial.print("0");              // P6 Always 0
  Serial.print(MEM1);             // P7
  Serial.print(MEM2);
  Serial.print(RX);               // P8
  Serial.print(MODE);             // P9
  Serial.print(VFO);              // P10  FR/FT 0=VFO
  Serial.print(SCAN);             // P11
  Serial.print(SIMPLEX);          // P12
  Serial.print(CTCSS);            // P13
  Serial.print(TONE1);            // P14
  Serial.print(TONE2);
  Serial.print("0");              // P15 Always 0
  Serial.print(";");

  mySerial.print("IF");
  mySerial.print(freq10GHz);        // P1
  mySerial.print(freq1GHz);
  mySerial.print(freq100MHz);
  mySerial.print(freq10MHz);
  mySerial.print(freq1MHz);
  mySerial.print(freq100kHz);
  mySerial.print(freq10kHz);
  mySerial.print(freq1kHz);
  mySerial.print(freq100Hz);
  mySerial.print(freq10Hz);
  mySerial.print(freq1Hz);
  mySerial.print("00000");          // P2 Always five 0s
  mySerial.print("+0000");          // P3 RIT/XIT freq +/-9990
  mySerial.print(RIT);              // P4
  mySerial.print(XIT);              // P5
  mySerial.print("0");              // P6 Always 0
  mySerial.print(MEM1);             // P7
  mySerial.print(MEM2);
  mySerial.print(RX);               // P8
  mySerial.print(MODE);             // P9
  mySerial.print(VFO);              // P10  FR/FT 0=VFO
  mySerial.print(SCAN);             // P11
  mySerial.print(SIMPLEX);          // P12
  mySerial.print(CTCSS);            // P13
  mySerial.print(TONE1);            // P14
  mySerial.print(TONE2);
  mySerial.print("0");              // P15 Always 0
  mySerial.print(";");
}

void Command_AI()
{
  Serial.print("AI0;");
  mySerial.print("AI0;");
}

void Command_MD()
{
  Serial.print("MD2;");
  mySerial.print("MD2;");
}

void Command_AI0()
{
  Serial.print("AI0;");
  mySerial.print("AI0;");
}

void Command_RX()
{
  RX = 0;
  TX = 0;
  Serial.print("RX0;");
  mySerial.print("RX0;");
}

void Command_TX()
{
  RX = 1;
  TX = 1;
  Serial.print("TX0;");
  mySerial.print("TX0;");
}

void Command_TX1()
{
  RX = 1;
  TX = 1;
  Serial.print("TX2;");
  mySerial.print("TX2;");
}

void Command_RS()
{
  Serial.print("RS0;");
  mySerial.print("RS0;");
}


***********************************************************
Additional code to enable audio and serial data across the single USB connection. This is test code only at this stage.


#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <Audio.h>                         // Teensy audio library

int debug = 0;

const int numChars = 14;
volatile long freq = 0;
boolean newCATcmd = false;

char CATcmd[numChars] = {'0'};    // an array to store the received CAT data
int freq10GHz = 0;
int freq1GHz = 0;
int freq100MHz = 0;
int freq10MHz = 1;
int freq1MHz = 4;
int freq100kHz = 1;
int freq10kHz = 2;
int freq1kHz = 3;
int freq100Hz = 4;
int freq10Hz = 5;
int freq1Hz = 6;
int RIT, XIT, MEM1, MEM2, RX, TX, VFO, SCAN, SIMPLEX, CTCSS, TONE1, TONE2 = 0;
int MODE = 2;

SoftwareSerial mySerial(31, 32);      // RX, TX
AudioControlSGTL5000    audioShield;

// Audio objects
AudioInputUSB           audioInputUSB;
AudioSynthWaveformSine  TestOsc;
AudioOutputUSB          audioOutputUSB;
AudioOutputI2S          audioOutputHeadphones;

// Audio connections
AudioConnection         patchCord5(TestOsc, 0, audioOutputUSB, 0);
AudioConnection         patchCord10(TestOsc, 0, audioOutputUSB, 1);
AudioConnection         patchCord15(audioInputUSB, 0, audioOutputHeadphones, 0);
AudioConnection         patchCord20(audioInputUSB, 1, audioOutputHeadphones, 1);


void setup()
{
  CalcFreq();

  Serial.begin(9600);
  mySerial.begin(9600);

  // Setup the audio shield
  AudioNoInterrupts();
  AudioMemory(12);
  audioShield.enable();
  TestOsc.amplitude(0.1);
  TestOsc.frequency(700);
  audioShield.unmuteHeadphone();                                              // Output to the audio amplifier
  audioShield.volume(0.8);
  AudioInterrupts();
}

void loop()
{
  rxCATcmd();
  analyseCATcmd();
}

void rxCATcmd()
{
  int index = 0;
  char endMarker = ';';
  char data;                    // CAT commands are ASCII characters

  while ((Serial.available() > 0) && (newCATcmd == false))
  {
    data = Serial.read();

    if (data != endMarker)
    {
      CATcmd[index] = data;
      index++;

      if (index >= numChars)
        index = numChars - 1;   // leave space for the \0 array termination
    }
    else
    {
      CATcmd[index] = ';';      // Indicate end of command
      debug = index;            // Needed later to print out the command
      CATcmd[index + 1] = '\0'; // terminate the array
      index = 0;                // reset for next CAT command
      newCATcmd = true;
    }
  }
}

void analyseCATcmd()
{
  if (newCATcmd == true)
  {
    newCATcmd = false;        // reset for next CAT time

    // Debug printing
    mySerial.println();
    for (int x = 0; x <= debug; x++)
      mySerial.print(CATcmd[x]);
    mySerial.print("\t");

    if ((CATcmd[0] == 'F') && (CATcmd[1] == 'A') && (CATcmd[2] == ';'))              // must be freq get command
      Command_GETFreqA();

    else if ((CATcmd[0] == 'F') && (CATcmd[1] == 'A') && (CATcmd[13] == ';'))        // must be freq set command
      Command_SETFreqA();

    else if ((CATcmd[0] == 'I') && (CATcmd[1] == 'F') && (CATcmd[2] == ';'))
      Command_IF();

    else if ((CATcmd[0] == 'I') && (CATcmd[1] == 'D') && (CATcmd[2] == ';'))
      Command_ID();

    else if ((CATcmd[0] == 'P') && (CATcmd[1] == 'S') && (CATcmd[2] == ';'))
      Command_PS();

    else if ((CATcmd[0] == 'P') && (CATcmd[1] == 'S') && (CATcmd[2] == '1'))
      Command_PS1();

    else if ((CATcmd[0] == 'A') && (CATcmd[1] == 'I') && (CATcmd[2] == ';'))
      Command_AI();

    else if ((CATcmd[0] == 'A') && (CATcmd[1] == 'I') && (CATcmd[2] == '0'))
      Command_AI0();

    else if ((CATcmd[0] == 'M') && (CATcmd[1] == 'D') && (CATcmd[2] == ';'))
      Command_MD();

    else if ((CATcmd[0] == 'R') && (CATcmd[1] == 'X') && (CATcmd[2] == ';'))
      Command_RX();

    else if ((CATcmd[0] == 'T') && (CATcmd[1] == 'X') && (CATcmd[2] == ';'))
      Command_TX();

    else if ((CATcmd[0] == 'T') && (CATcmd[1] == 'X') && (CATcmd[2] == '1'))
      Command_TX1();

    else if ((CATcmd[0] == 'R') && (CATcmd[1] == 'S') && (CATcmd[2] == ';'))
      Command_RS();

    Serial.flush();       // Get ready for next command
    //delay(50);            // Needed to eliminate WSJT-X connection errors
  }
}

void Command_ID()
{
  Serial.print("ID020;");
  mySerial.print("ID020;");
}

void Command_PS()
{
  Serial.print("PS1;");
  mySerial.print("PS1;");
}

void Command_PS1()
{
  Serial.print("PS1;");
  mySerial.print("PS1;");
}

void Command_GETFreqA()
{
  Serial.print("FA");
  Serial.print(freq10GHz);
  Serial.print(freq1GHz);
  Serial.print(freq100MHz);
  Serial.print(freq10MHz);
  Serial.print(freq1MHz);
  Serial.print(freq100kHz);
  Serial.print(freq10kHz);
  Serial.print(freq1kHz);
  Serial.print(freq100Hz);
  Serial.print(freq10Hz);
  Serial.print(freq1Hz);
  Serial.print(";");

  mySerial.print("FA");
  mySerial.print(freq10GHz);
  mySerial.print(freq1GHz);
  mySerial.print(freq100MHz);
  mySerial.print(freq10MHz);
  mySerial.print(freq1MHz);
  mySerial.print(freq100kHz);
  mySerial.print(freq10kHz);
  mySerial.print(freq1kHz);
  mySerial.print(freq100Hz);
  mySerial.print(freq10Hz);
  mySerial.print(freq1Hz);
  mySerial.print(";");
}

void Command_SETFreqA()
{
  freq10GHz = CATcmd[2] - 48;       // convert ASCII char to int equivalent. int 0 = ASCII 48;
  freq1GHz = CATcmd[3] - 48;
  freq100MHz = CATcmd[4] - 48;
  freq10MHz = CATcmd[5] - 48;
  freq1MHz = CATcmd[6] - 48;
  freq100kHz = CATcmd[7] - 48;
  freq10kHz = CATcmd[8] - 48;
  freq1kHz = CATcmd[9] - 48;
  freq100Hz = CATcmd[10] - 48;
  freq10Hz = CATcmd[11] - 48;
  freq1Hz = CATcmd[12] - 48;

  //Command_GETFreqA();               // now RSP with FA

  Serial.print("FA");
  Serial.print(freq10GHz);
  Serial.print(freq1GHz);
  Serial.print(freq100MHz);
  Serial.print(freq10MHz);
  Serial.print(freq1MHz);
  Serial.print(freq100kHz);
  Serial.print(freq10kHz);
  Serial.print(freq1kHz);
  Serial.print(freq100Hz);
  Serial.print(freq10Hz);
  Serial.print(freq1Hz);
  Serial.print(";");

  mySerial.print("FA");
  mySerial.print(freq10GHz);
  mySerial.print(freq1GHz);
  mySerial.print(freq100MHz);
  mySerial.print(freq10MHz);
  mySerial.print(freq1MHz);
  mySerial.print(freq100kHz);
  mySerial.print(freq10kHz);
  mySerial.print(freq1kHz);
  mySerial.print(freq100Hz);
  mySerial.print(freq10Hz);
  mySerial.print(freq1Hz);
  mySerial.print(";");

  CalcFreq();
}

void CalcFreq()
{
  freq = (
           (10000000000L * freq10GHz) +
           (1000000000L * freq1GHz) +
           (100000000L * freq100MHz) +
           (10000000L * freq10MHz) +
           (1000000L * freq1MHz) +
           (100000L * freq100kHz) +
           (10000L * freq10kHz) +
           (1000L * freq1kHz) +
           (100L * freq100Hz) +
           (10L * freq10Hz) +
           freq1Hz);
}

void Command_IF()
{
  Serial.print("IF");
  Serial.print(freq10GHz);        // P1
  Serial.print(freq1GHz);
  Serial.print(freq100MHz);
  Serial.print(freq10MHz);
  Serial.print(freq1MHz);
  Serial.print(freq100kHz);
  Serial.print(freq10kHz);
  Serial.print(freq1kHz);
  Serial.print(freq100Hz);
  Serial.print(freq10Hz);
  Serial.print(freq1Hz);
  Serial.print("00000");          // P2 Always five 0s
  Serial.print("+0000");          // P3 RIT/XIT freq +/-9990
  Serial.print(RIT);              // P4
  Serial.print(XIT);              // P5
  Serial.print("0");              // P6 Always 0
  Serial.print(MEM1);             // P7
  Serial.print(MEM2);
  Serial.print(RX);               // P8
  Serial.print(MODE);             // P9
  Serial.print(VFO);              // P10  FR/FT 0=VFO
  Serial.print(SCAN);             // P11
  Serial.print(SIMPLEX);          // P12
  Serial.print(CTCSS);            // P13
  Serial.print(TONE1);            // P14
  Serial.print(TONE2);
  Serial.print("0");              // P15 Always 0
  Serial.print(";");

  mySerial.print("IF");
  mySerial.print(freq10GHz);        // P1
  mySerial.print(freq1GHz);
  mySerial.print(freq100MHz);
  mySerial.print(freq10MHz);
  mySerial.print(freq1MHz);
  mySerial.print(freq100kHz);
  mySerial.print(freq10kHz);
  mySerial.print(freq1kHz);
  mySerial.print(freq100Hz);
  mySerial.print(freq10Hz);
  mySerial.print(freq1Hz);
  mySerial.print("00000");          // P2 Always five 0s
  mySerial.print("+0000");          // P3 RIT/XIT freq +/-9990
  mySerial.print(RIT);              // P4
  mySerial.print(XIT);              // P5
  mySerial.print("0");              // P6 Always 0
  mySerial.print(MEM1);             // P7
  mySerial.print(MEM2);
  mySerial.print(RX);               // P8
  mySerial.print(MODE);             // P9
  mySerial.print(VFO);              // P10  FR/FT 0=VFO
  mySerial.print(SCAN);             // P11
  mySerial.print(SIMPLEX);          // P12
  mySerial.print(CTCSS);            // P13
  mySerial.print(TONE1);            // P14
  mySerial.print(TONE2);
  mySerial.print("0");              // P15 Always 0
  mySerial.print(";");
}

void Command_AI()
{
  Serial.print("AI0;");
  mySerial.print("AI0;");
}

void Command_MD()
{
  Serial.print("MD2;");
  mySerial.print("MD2;");
}

void Command_AI0()
{
  Serial.print("AI0;");
  mySerial.print("AI0;");
}

void Command_RX()
{
  RX = 0;
  TX = 0;
  Serial.print("RX0;");
  mySerial.print("RX0;");
}

void Command_TX()
{
  RX = 1;
  TX = 1;
  Serial.print("TX0;");
  mySerial.print("TX0;");
}

void Command_TX1()
{
  RX = 1;
  TX = 1;
  Serial.print("TX2;");
  mySerial.print("TX2;");
}

void Command_RS()
{
  Serial.print("RS0;");
  mySerial.print("RS0;");
}


*************************************************************************

RF Splitter/Combiner