Monday, 29 January 2018

80/40/20m Base Rig Notes



Current notes for the 80/40/20m SSB rig.













VFO/BFO Test Code

#include <UTFT.h>
#include <si5351.h>

extern uint8_t SmallFont[];

volatile int updatedisplay = 0;
volatile long freq = 6200000;
volatile long currentfreq = 0;
volatile long oldfreq = 0;
volatile long remainder = 0;
const uint32_t bandStart = 1000000;
const uint32_t bandEnd =   30000000;

volatile long BFOfreq = 8000000;
volatile long BFOcurrentfreq = 0;
volatile long BFOoldfreq = 0;
volatile long BFOremainder = 0;

float OnesHz = 0;
float TensHz = 0;
float HundredsHz = 0;
float OneskHz = 0;
float TenskHz = 0;
float HundredskHz = 0;
float OnesMHz = 0;
float TensMhz = 0;

float BFOOnesHz = 0;
float BFOTensHz = 0;
float BFOHundredsHz = 0;
float BFOOneskHz = 0;
float BFOTenskHz = 0;
float BFOHundredskHz = 0;
float BFOOnesMHz = 0;
float BFOTensMhz = 0;

volatile long radix = 100;
volatile long oldradix = 100;

volatile long BFOradix = 100;
volatile long BFOoldradix = 100;

int mode = 1;
int button_delay = 100;

volatile uint32_t LSB_IF_freq = 8011500;    // Crystal filter centre freq
volatile uint32_t LSB_BFO_freq = 8013000;   // Crystal filter centre freq

// Rotary encoder pins and other inputs
static const int pushPin = 4;
static const int rotBPin = 3;
static const int rotAPin = 2;

// Rotary encoder variables, used by interrupt routines
volatile int rotState = 0;
volatile int rotAval = 1;
volatile int rotBval = 1;


// Usage: TFT(<model code>, SDA, SCL, CS, RST, RS/A0);
UTFT TFT(ITDB18SP, 11, 10, 9, 12, 8);   // Remember to change the model parameter to suit your display module!
Si5351 si5351;


void setup()
{
  // Set up frequency and radix switches
  pinMode(rotAPin, INPUT);
  pinMode(rotBPin, INPUT);
  pinMode(pushPin, INPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);


  // Set up pull-up resistors on inputs
  digitalWrite(rotAPin, HIGH);
  digitalWrite(rotBPin, HIGH);
  digitalWrite(pushPin, HIGH);
  digitalWrite(A0, HIGH);
  digitalWrite(A1, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A3, HIGH);

  // Set up interrupt pins
  attachInterrupt(digitalPinToInterrupt(rotAPin), ISRrotAChange, CHANGE);
  attachInterrupt(digitalPinToInterrupt(rotBPin), ISRrotBChange, CHANGE);

  // Setup the LCD
  TFT.InitLCD();
  TFT.clrScr();
  TFT.setFont(SmallFont);
  SetupScreen();

  // Initialize the DDS
  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0);
  si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);
  si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_8MA);
}


void loop()
{
  currentfreq = getfreq();                // Interrupt safe method to get the current frequency

  if (currentfreq != oldfreq)
  {
    UpdateFreq();
    SendFrequency();
    oldfreq = currentfreq;
  }


  BFOcurrentfreq = BFOgetfreq();                // Interrupt safe method to get the current frequency

  if (BFOcurrentfreq != BFOoldfreq)
  {
    UpdateFreq();
    SendFrequency();
    BFOoldfreq = BFOcurrentfreq;
  }


  if (digitalRead(A3) == LOW)
  {
    delay(10);
    if (digitalRead(A3) == LOW)
    {
      if (mode == 1)            // VFO
      {
        if (radix == 1000000)
          radix = 100000;
        else if (radix == 100000)
          radix = 10000;
        else if (radix == 10000)
          radix = 1000;
        else if (radix == 1000)
          radix = 100;
        else if (radix == 100)
          radix = 10;
        else if (radix == 10)
          radix = 1;
        else
          radix = 1000000;
      }
      if (mode == 2)              // BFO
      {
        if (BFOradix == 1000000)
          BFOradix = 100000;
        else if (BFOradix == 100000)
          BFOradix = 10000;
        else if (BFOradix == 10000)
          BFOradix = 1000;
        else if (BFOradix == 1000)
          BFOradix = 100;
        else if (BFOradix == 100)
          BFOradix = 10;
        else if (BFOradix == 10)
          BFOradix = 1;
        else
          BFOradix = 1000000;
      }
    }
    delay(button_delay);
    UpdateFreq();
  }

  if (digitalRead(A1) == LOW)
  {
    delay(10);
    if (digitalRead(A1) == LOW)
    {
      if (mode == 1)            // VFO
      {
        if (radix == 1)
          radix = 10;
        else if (radix == 10)
          radix = 100;
        else if (radix == 100)
          radix = 1000;
        else if (radix == 1000)
          radix = 10000;
        else if (radix == 10000)
          radix = 100000;
        else if (radix == 100000)
          radix = 1000000;
        else
          radix = 1;
      }
      if (mode == 2)              // BFO
      {
        if (BFOradix == 1)
          BFOradix = 10;
        else if (BFOradix == 10)
          BFOradix = 100;
        else if (BFOradix == 100)
          BFOradix = 1000;
        else if (BFOradix == 1000)
          BFOradix = 10000;
        else if (BFOradix == 10000)
          BFOradix = 100000;
        else if (BFOradix == 100000)
          BFOradix = 1000000;
        else
          BFOradix = 1;
      }
    }
    UpdateFreq();
    delay(button_delay);
  }

  if (digitalRead(A0) == LOW)
  {
    delay(10);
    if (digitalRead(A0) == LOW)
    {
      mode++;
      if (mode == 3)
        mode = 1;
    }
    delay(button_delay);
    UpdateFreq();
  }


  if (digitalRead(A2) == LOW)
  {
    delay(10);
    if (digitalRead(A2) == LOW)
    {
      mode--;
      if (mode == 0)
        mode = 2;
    }
    delay(button_delay);
    UpdateFreq();
  }
}


long getfreq()
{
  long temp_freq;
  cli();
  temp_freq = freq;
  sei();
  return temp_freq;
}


long BFOgetfreq()
{
  long temp_freq;
  cli();
  temp_freq = BFOfreq;
  sei();
  return temp_freq;
}


// Interrupt routines
void ISRrotAChange()
{
  if (digitalRead(rotAPin))
  {
    rotAval = 1;
    UpdateRot();
  }
  else
  {
    rotAval = 0;
    UpdateRot();
  }
}


void ISRrotBChange()
{
  if (digitalRead(rotBPin))
  {
    rotBval = 1;
    UpdateRot();
  }
  else
  {
    rotBval = 0;
    UpdateRot();
  }
}


void UpdateRot()
{
  switch (rotState)
  {

    case 0:                                         // Idle state, look for direction
      if (!rotBval)
        rotState = 1;                               // CW 1
      if (!rotAval)
        rotState = 11;                              // CCW 1
      break;

    case 1:                                         // CW, wait for A low while B is low
      if (!rotBval)
      {
        if (!rotAval)
        {
          if (mode == 1)
          {
            // either increment radixindex or freq
            freq = (freq + radix);
            if (freq > bandEnd)
              freq = bandEnd;
          }
          if (mode == 2)
          {
            BFOfreq = (BFOfreq + BFOradix);
            if (BFOfreq > bandEnd)
              BFOfreq = bandEnd;
          }
          rotState = 2;                             // CW 2
        }
      }
      else if (rotAval)
        rotState = 0;                             // It was just a glitch on B, go back to start
      break;

    case 2:                                         // CW, wait for B high
      if (rotBval)
        rotState = 3;                               // CW 3
      break;

    case 3:                                         // CW, wait for A high
      if (rotAval)
        rotState = 0;                               // back to idle (detent) state
      break;

    case 11:                                        // CCW, wait for B low while A is low
      if (!rotAval)
      {
        if (!rotBval)
        {
          // either decrement radixindex or freq
          if (mode == 1)
          {
            freq = (freq - radix);
            if (freq < bandStart)
              freq = bandStart;
          }
          if (mode == 2)
          {
            BFOfreq = (BFOfreq - BFOradix);
            if (BFOfreq < bandStart)
              BFOfreq = bandStart;
          }
          rotState = 12;                            // CCW 2
        }
      }
      else if (rotBval)
        rotState = 0;                             // It was just a glitch on A, go back to start
      break;

    case 12:                                        // CCW, wait for A high
      if (rotAval)
        rotState = 13;                              // CCW 3
      break;

    case 13:                                        // CCW, wait for B high
      if (rotBval)
        rotState = 0;                               // back to idle (detent) state
      break;
  }
}


void SetupScreen()
{
  TFT.setColor(VGA_BLUE);
  TFT.fillRect(0, 0, 159, 13);
  TFT.drawRect(0, 0, 159, 127);
  TFT.setColor(VGA_WHITE);
  TFT.setBackColor(VGA_BLUE);
  TFT.print("ZL2CTM Base Rig", CENTER, 1);
}


void UpdateFreq()
{
  TFT.setBackColor(VGA_BLACK);
  if (mode == 1)
    TFT.setColor(VGA_AQUA);
  else if (mode == 2)
    TFT.setColor(VGA_GRAY);
  TFT.print("VFO", 10, 20);

  if (mode == 2)
    TFT.setColor(VGA_AQUA);
  else if (mode == 1)
    TFT.setColor(VGA_GRAY);
  TFT.print("BFO", 10, 40);

  TensMhz = freq / 10000000;                                // TensMHz = 12345678 / 10000000 = 1
  remainder = freq - (TensMhz * 10000000);                  // remainder = 12345678 - 10000000 = 2345678
  OnesMHz = remainder / 1000000;                            // OnesMhz = 2345678 / 1000000 = 2
  remainder = remainder - (OnesMHz * 1000000);              // remainder = 2345678 - (2 * 1000000) = 345678
  HundredskHz = remainder / 100000;                         // HundredskHz = 345678 / 100000 = 3
  remainder = remainder - (HundredskHz * 100000);           // remainder = 345678 - (3 * 100000) = 45678
  TenskHz = remainder / 10000;                              // TenskHz = 45678 / 10000 = 4
  remainder = remainder - (TenskHz * 10000);                // remainder = 45678 - (4 * 10000) = 5678
  OneskHz = remainder / 1000;                               // OneskHz = 5678 / 1000 = 5
  remainder = remainder - (OneskHz * 1000);                 // remainder = 5678 - (5 * 1000) = 678
  HundredsHz = remainder / 100;                             // HundredsHz = 678 / 100 = 6
  remainder = remainder - (HundredsHz * 100);               // remainder = 678 - (6 * 100) = 78
  TensHz = remainder / 10;                                  // TensHz = 78 / 10 = 7
  remainder = remainder - (TensHz * 10);                    // remainder = 78 - (7 * 10) = 8
  OnesHz = remainder;                                       // OnesHz = 8

  BFOTensMhz = BFOfreq / 10000000;                                // TensMHz = 12345678 / 10000000 = 1
  BFOremainder = BFOfreq - (BFOTensMhz * 10000000);                  // remainder = 12345678 - 10000000 = 2345678
  BFOOnesMHz = BFOremainder / 1000000;                            // OnesMhz = 2345678 / 1000000 = 2
  BFOremainder = BFOremainder - (BFOOnesMHz * 1000000);              // remainder = 2345678 - (2 * 1000000) = 345678
  BFOHundredskHz = BFOremainder / 100000;                         // HundredskHz = 345678 / 100000 = 3
  BFOremainder = BFOremainder - (BFOHundredskHz * 100000);           // remainder = 345678 - (3 * 100000) = 45678
  BFOTenskHz = BFOremainder / 10000;                              // TenskHz = 45678 / 10000 = 4
  BFOremainder = BFOremainder - (BFOTenskHz * 10000);                // remainder = 45678 - (4 * 10000) = 5678
  BFOOneskHz = BFOremainder / 1000;                               // OneskHz = 5678 / 1000 = 5
  BFOremainder = BFOremainder - (BFOOneskHz * 1000);                 // remainder = 5678 - (5 * 1000) = 678
  BFOHundredsHz = BFOremainder / 100;                             // HundredsHz = 678 / 100 = 6
  BFOremainder = BFOremainder - (BFOHundredsHz * 100);               // remainder = 678 - (6 * 100) = 78
  BFOTensHz = BFOremainder / 10;                                  // TensHz = 78 / 10 = 7
  BFOremainder = BFOremainder - (BFOTensHz * 10);                    // remainder = 78 - (7 * 10) = 8
  BFOOnesHz = BFOremainder;                                       // OnesHz = 8


  // VFO
  if (TensMhz == 0)
  {
    TFT.setColor(VGA_BLACK);
    TFT.printNumI(TensMhz, 75, 20);
  }
  if (TensMhz > 0)
  {
    if (mode == 1)
      TFT.setColor(VGA_AQUA);
    else if (mode == 2)
      TFT.setColor(VGA_GRAY);
    TFT.printNumI(TensMhz, 75, 20);
  }
  if (mode == 1)
    TFT.setColor(VGA_AQUA);
  else if (mode == 2)
    TFT.setColor(VGA_GRAY);
  TFT.printNumI(OnesMHz, 84, 20);
  TFT.print(".", 93, 20);
  TFT.printNumI(HundredskHz, 102, 20);
  TFT.printNumI(TenskHz, 111, 20);
  TFT.printNumI(OneskHz, 120, 20);
  TFT.printNumI(HundredsHz, 129, 20);
  TFT.printNumI(TensHz, 138, 20);
  TFT.printNumI(OnesHz, 147, 20);



  // BFO
  if (BFOTensMhz == 0)
  {
    TFT.setColor(VGA_BLACK);
    TFT.printNumI(BFOTensMhz, 75, 40);
  }
  if (BFOTensMhz > 0)
  {
    if (mode == 2)
      TFT.setColor(VGA_AQUA);
    else if (mode == 1)
      TFT.setColor(VGA_GRAY);
    TFT.printNumI(BFOTensMhz, 75, 40);
  }
  if (mode == 2)
    TFT.setColor(VGA_AQUA);
  else if (mode == 1)
    TFT.setColor(VGA_GRAY);
  TFT.printNumI(BFOOnesMHz, 84, 40);
  TFT.print(".", 93, 40);
  TFT.printNumI(BFOHundredskHz, 102, 40);
  TFT.printNumI(BFOTenskHz, 111, 40);
  TFT.printNumI(BFOOneskHz, 120, 40);
  TFT.printNumI(BFOHundredsHz, 129, 40);
  TFT.printNumI(BFOTensHz, 138, 40);
  TFT.printNumI(BFOOnesHz, 147, 40);

  if (mode == 1)
  {
    //Radix
    TFT.setColor(VGA_BLACK);
    if (oldradix == 1)
      TFT.drawLine(147, 31, 151, 31);
    else if (oldradix == 10)
      TFT.drawLine(138, 31, 142, 31);
    else if (oldradix == 100)
      TFT.drawLine(129, 31, 133, 31);
    else if (oldradix == 1000)
      TFT.drawLine(120, 31, 124, 31);
    else if (oldradix == 10000)
      TFT.drawLine(111, 31, 115, 31);
    else if (oldradix == 100000)
      TFT.drawLine(102, 31, 106, 31);
    else if (oldradix == 1000000)
      TFT.drawLine(84, 31, 88, 31);

    TFT.setColor(VGA_AQUA);
    //TFT.setFont(SmallFont);
    if (radix == 1)
      TFT.drawLine(147, 31, 151, 31);
    else if (radix == 10)
      TFT.drawLine(138, 31, 142, 31);
    else if (radix == 100)
      TFT.drawLine(129, 31, 133, 31);
    else if (radix == 1000)
      TFT.drawLine(120, 31, 124, 31);
    else if (radix == 10000)
      TFT.drawLine(111, 31, 115, 31);
    else if (radix == 100000)
      TFT.drawLine(102, 31, 106, 31);
    else if (radix == 1000000)
      TFT.drawLine(84, 31, 88, 31);

    oldradix = radix;
  }

  if (mode == 2)
  {
    //Radix
    TFT.setColor(VGA_BLACK);
    if (BFOoldradix == 1)
      TFT.drawLine(147, 51, 151, 51);
    else if (BFOoldradix == 10)
      TFT.drawLine(138, 51, 142, 51);
    else if (BFOoldradix == 100)
      TFT.drawLine(129, 51, 133, 51);
    else if (BFOoldradix == 1000)
      TFT.drawLine(120, 51, 124, 51);
    else if (BFOoldradix == 10000)
      TFT.drawLine(111, 51, 115, 51);
    else if (BFOoldradix == 100000)
      TFT.drawLine(102, 51, 106, 51);
    else if (BFOoldradix == 1000000)
      TFT.drawLine(84, 51, 88, 51);

    TFT.setColor(VGA_AQUA);
    //TFT.setFont(SmallFont);
    if (BFOradix == 1)
      TFT.drawLine(147, 51, 151, 51);
    else if (BFOradix == 10)
      TFT.drawLine(138, 51, 142, 51);
    else if (BFOradix == 100)
      TFT.drawLine(129, 51, 133, 51);
    else if (BFOradix == 1000)
      TFT.drawLine(120, 51, 124, 51);
    else if (BFOradix == 10000)
      TFT.drawLine(111, 51, 115, 51);
    else if (BFOradix == 100000)
      TFT.drawLine(102, 51, 106, 51);
    else if (BFOradix == 1000000)
      TFT.drawLine(84, 51, 88, 51);

    BFOoldradix = BFOradix;
  }
}


void SendFrequency()
{
  //si5351.set_freq(((freq - BFOfreq) * 100ULL), SI5351_PLL_FIXED, SI5351_CLK0);
  si5351.set_freq((freq * 100ULL), SI5351_PLL_FIXED, SI5351_CLK0);
  si5351.set_freq((BFOfreq * 100ULL), SI5351_PLL_FIXED, SI5351_CLK2);
}




Rig Code (not finished)

#include <UTFT.h>
#include <si5351.h>

extern uint8_t SmallFont[];

volatile int updatedisplay = 0;
volatile long freq = 14200000;
volatile long currentfreq = 0;
volatile long oldfreq = 0;
volatile long remainder = 0;
const uint32_t bandStart = 3000000;
const uint32_t bandEnd =   15000000;


float OnesHz = 0;
float TensHz = 0;
float HundredsHz = 0;
float OneskHz = 0;
float TenskHz = 0;
float HundredskHz = 0;
float OnesMHz = 0;
float TensMhz = 0;

volatile long radix = 1000;
volatile long oldradix = 1000;
int button_delay = 150;

volatile uint32_t LSB_BFO_freq = 8000000;    // Crystal filter centre freq
volatile uint32_t USB_BFO_freq = 8000000;   // Crystal filter centre freq

// Rotary encoder pins and other inputs
static const int pushPin = 4;
static const int rotBPin = 3;
static const int rotAPin = 2;

// Rotary encoder variables, used by interrupt routines
volatile int rotState = 0;
volatile int rotAval = 1;
volatile int rotBval = 1;


// Usage: TFT(<model code>, SDA, SCL, CS, RST, RS/A0);
UTFT TFT(ITDB18SP, 11, 10, 9, 12, 8);   // Remember to change the model parameter to suit your display module!
Si5351 si5351;


void setup()
{
  // Set up frequency and radix switches
  pinMode(rotAPin, INPUT);
  pinMode(rotBPin, INPUT);
  pinMode(pushPin, INPUT);
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);

  // Set up pull-up resistors on inputs
  digitalWrite(rotAPin, HIGH);
  digitalWrite(rotBPin, HIGH);
  digitalWrite(pushPin, HIGH);
  digitalWrite(A0, HIGH);
  digitalWrite(A1, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A3, HIGH);

  // Set up interrupt pins
  attachInterrupt(digitalPinToInterrupt(rotAPin), ISRrotAChange, CHANGE);
  attachInterrupt(digitalPinToInterrupt(rotBPin), ISRrotBChange, CHANGE);

  // Setup the LCD
  TFT.InitLCD();
  TFT.clrScr();
  TFT.setFont(SmallFont);
  SetupScreen();

  // Initialize the DDS
  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0);
  si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
  si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);
  si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_8MA);
}

void loop()
{
  currentfreq = getfreq();                // Interrupt safe method to get the current frequency

  if (currentfreq != oldfreq)
  {
    UpdateFreq();
    SendFrequency();
    oldfreq = currentfreq;
  }


  if (digitalRead(A3) == LOW)
  {
    delay(10);
    if (digitalRead(A3) == LOW)
    {
      if (radix == 1000000)
        radix = 100000;
      else if (radix == 100000)
        radix = 10000;
      else if (radix == 10000)
        radix = 1000;
      else if (radix == 1000)
        radix = 100;
      else if (radix == 100)
        radix = 10;
      else if (radix == 10)
        radix = 1;
      else
        radix = 1000000;
    }
    delay(button_delay);
    UpdateFreq();
  }


  if (digitalRead(A1) == LOW)
  {
    delay(10);
    if (digitalRead(A1) == LOW)
    {
      if (radix == 1)
        radix = 10;
      else if (radix == 10)
        radix = 100;
      else if (radix == 100)
        radix = 1000;
      else if (radix == 1000)
        radix = 10000;
      else if (radix == 10000)
        radix = 100000;
      else if (radix == 100000)
        radix = 1000000;
      else
        radix = 1;
    }
    delay(button_delay);
    UpdateFreq();
  }
}


long getfreq()
{
  long temp_freq;
  cli();
  temp_freq = freq;
  sei();
  return temp_freq;
}


// Interrupt routines
void ISRrotAChange()
{
  if (digitalRead(rotAPin))
  {
    rotAval = 1;
    UpdateRot();
  }
  else
  {
    rotAval = 0;
    UpdateRot();
  }
}


void ISRrotBChange()
{
  if (digitalRead(rotBPin))
  {
    rotBval = 1;
    UpdateRot();
  }
  else
  {
    rotBval = 0;
    UpdateRot();
  }
}


void UpdateRot()
{
  switch (rotState)
  {

    case 0:                                         // Idle state, look for direction
      if (!rotBval)
        rotState = 1;                               // CW 1
      if (!rotAval)
        rotState = 11;                              // CCW 1
      break;

    case 1:                                         // CW, wait for A low while B is low
      if (!rotBval)
      {
        if (!rotAval)
        {
          freq = (freq + radix);
          if (freq > bandEnd)
            freq = bandEnd;
          rotState = 2;                             // CW 2
        }
      }
      else if (rotAval)
        rotState = 0;                             // It was just a glitch on B, go back to start
      break;

    case 2:                                         // CW, wait for B high
      if (rotBval)
        rotState = 3;                               // CW 3
      break;

    case 3:                                         // CW, wait for A high
      if (rotAval)
        rotState = 0;                               // back to idle (detent) state
      break;

    case 11:                                        // CCW, wait for B low while A is low
      if (!rotAval)
      {
        if (!rotBval)
        {
          freq = (freq - radix);
          if (freq < bandStart)
            freq = bandStart;
          rotState = 12;                            // CCW 2
        }
      }
      else if (rotBval)
        rotState = 0;                             // It was just a glitch on A, go back to start
      break;

    case 12:                                        // CCW, wait for A high
      if (rotAval)
        rotState = 13;                              // CCW 3
      break;

    case 13:                                        // CCW, wait for B high
      if (rotBval)
        rotState = 0;                               // back to idle (detent) state
      break;
  }
}


void SetupScreen()
{
  TFT.setColor(VGA_BLUE);
  TFT.fillRect(0, 0, 159, 13);
  TFT.drawRect(0, 0, 159, 127);
  TFT.setColor(VGA_WHITE);
  TFT.setBackColor(VGA_BLUE);
  TFT.print("ZL2CTM Base Rig", CENTER, 1);

  TFT.setBackColor(VGA_BLACK);
  TFT.setColor(VGA_AQUA);
  TFT.print("VFO-A", 10, 20);
  TFT.setColor(VGA_GRAY);
  TFT.print("VFO-B", 10, 40);
  TFT.setColor(VGA_GRAY);
  TFT.print("MEM-10", 10, 60);
  TFT.setColor(VGA_GRAY);
  TFT.print("SCAN-12", 10, 80);
}

void UpdateFreq()
{
  TensMhz = freq / 10000000;                                // TensMHz = 12345678 / 10000000 = 1
  remainder = freq - (TensMhz * 10000000);                  // remainder = 12345678 - 10000000 = 2345678
  OnesMHz = remainder / 1000000;                            // OnesMhz = 2345678 / 1000000 = 2
  remainder = remainder - (OnesMHz * 1000000);              // remainder = 2345678 - (2 * 1000000) = 345678
  HundredskHz = remainder / 100000;                         // HundredskHz = 345678 / 100000 = 3
  remainder = remainder - (HundredskHz * 100000);           // remainder = 345678 - (3 * 100000) = 45678
  TenskHz = remainder / 10000;                              // TenskHz = 45678 / 10000 = 4
  remainder = remainder - (TenskHz * 10000);                // remainder = 45678 - (4 * 10000) = 5678
  OneskHz = remainder / 1000;                               // OneskHz = 5678 / 1000 = 5
  remainder = remainder - (OneskHz * 1000);                 // remainder = 5678 - (5 * 1000) = 678
  HundredsHz = remainder / 100;                             // HundredsHz = 678 / 100 = 6
  remainder = remainder - (HundredsHz * 100);               // remainder = 678 - (6 * 100) = 78
  TensHz = remainder / 10;                                  // TensHz = 78 / 10 = 7
  remainder = remainder - (TensHz * 10);                    // remainder = 78 - (7 * 10) = 8
  OnesHz = remainder;                                       // OnesHz = 8

  if (TensMhz == 0)
  {
    TFT.setColor(VGA_BLACK);
    TFT.printNumI(TensMhz, 75, 20);
  }
  if (TensMhz > 0)
  {
    TFT.setColor(VGA_AQUA);
    TFT.printNumI(TensMhz, 75, 20);
  }

  TFT.setColor(VGA_AQUA);
  TFT.printNumI(OnesMHz, 84, 20);
  TFT.print(".", 93, 20);
  TFT.printNumI(HundredskHz, 102, 20);
  TFT.printNumI(TenskHz, 111, 20);
  TFT.printNumI(OneskHz, 120, 20);
  TFT.printNumI(HundredsHz, 129, 20);
  TFT.printNumI(TensHz, 138, 20);
  TFT.printNumI(OnesHz, 147, 20);

  //Radix
  TFT.setColor(VGA_BLACK);
  //TFT.setFont(SmallFont);
  if (oldradix == 1)
    TFT.drawLine(147, 31, 151, 31);
  else if (oldradix == 10)
    TFT.drawLine(138, 31, 142, 31);
  else if (oldradix == 100)
    TFT.drawLine(129, 31, 133, 31);
  else if (oldradix == 1000)
    TFT.drawLine(120, 31, 124, 31);
  else if (oldradix == 10000)
    TFT.drawLine(111, 31, 115, 31);
  else if (oldradix == 100000)
    TFT.drawLine(102, 31, 106, 31);
  else if (oldradix == 1000000)
    TFT.drawLine(84, 31, 88, 31);

  TFT.setColor(VGA_AQUA);
  //TFT.setFont(SmallFont);
  if (radix == 1)
    TFT.drawLine(147, 31, 151, 31);
  else if (radix == 10)
    TFT.drawLine(138, 31, 142, 31);
  else if (radix == 100)
    TFT.drawLine(129, 31, 133, 31);
  else if (radix == 1000)
    TFT.drawLine(120, 31, 124, 31);
  else if (radix == 10000)
    TFT.drawLine(111, 31, 115, 31);
  else if (radix == 100000)
    TFT.drawLine(102, 31, 106, 31);
  else if (radix == 1000000)
    TFT.drawLine(84, 31, 88, 31);

  oldradix = radix;
}

void SendFrequency()
{
  if (freq <= 8000000)
  {
    // VFO
    si5351.set_freq(((freq + LSB_BFO_freq) * 100ULL), SI5351_PLL_FIXED, SI5351_CLK0);
    // BFO
    si5351.set_freq((LSB_BFO_freq * 100ULL), SI5351_PLL_FIXED, SI5351_CLK2);
  }
  
  if (freq > 8000000)
  {
    // VFO
    si5351.set_freq(((freq - USB_BFO_freq) * 100ULL), SI5351_PLL_FIXED, SI5351_CLK0);
    // BFO
    si5351.set_freq((USB_BFO_freq * 100ULL), SI5351_PLL_FIXED, SI5351_CLK2);
  }
}

5 comments:

  1. Have you tried using the Hybrid Cascode circuit with a BJT transistor in the upper position rather than a FET?
    Those 741 opamps are rather long in the tooth these days, modern FET input types have much lower noise. However, for DC amplifier use (AGC circuits, power supply regulators, etc) they are more than good enough and they are cheap. I still have a ton of them in my junk box, but also lots of the Ti FET type too.

    ReplyDelete
    Replies
    1. Hi. No note yet, but I understand that is a good configuration for battery powered rigs in that the gain holds up well for falling battery voltage. Good point too about the 741.

      Charlie

      Delete
  2. Hi. No I haven't, but I'm keen to based on the comments in SSDRA and EMFRD. I think I will look to use on in the next build. Good point about the 741, I still have a few of those in the junk box. I should really look to replace them with a modern version. I'll check out the Ti version.

    Thanks again.

    Charlie, ZL2CTM

    ReplyDelete
  3. Hi,
    I really am enjoying these build and is saving all of them. I currently work away from but as soon as I am back I am going to build one of these. It's been an awesome learning experience so far.
    Thanks
    Stephanus Nell K6NG

    ReplyDelete
  4. Hi Stephanus. I'm glad you are finding it useful. That's the aim!

    Charlie ZL2CTM

    ReplyDelete

Note: only a member of this blog may post a comment.