Tuesday, 21 January 2025

40m Pelican Case SSB Trabsceiver


 


Test code for the LCD and Si5351

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

static const long bandStart = 7000000;          // start of VFO range
static const long bandEnd = 7300000;            // end of VFO range
static const long bandInit = 7090000;           // where to initially set the frequency
volatile long freq = 7090000;                   // the current freq
volatile long oldfreq = 0;                      // the previous freq
volatile long BFO_freq = 0;                     // Low side injection thus no SB inversion. (was 8997200)
volatile long radix = 1000;                     // How much to change the frequency by, clicking the Up Down switches
volatile long oldradix = 0;                     // the previous radix
volatile float SWR = 2.6;                       // SWR
volatile float oldSWR = 2.6;                    // the previoud SWR
volatile float FWD = 5.1;                       // Forward power
volatile float REV = 1.1;                       // Reflected power
volatile int TX = 0;                            // 0=RX, 1=TX
volatile int oldTX = 1;                         // the old TX
volatile int tune = 0;                          // 0=No tune, 1=tune
volatile int oldtune = 1;                       // the old tune
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 PTTPin = 5;
static const int TunePin = 6;

byte OneBar[8] = {  // Array of bytes
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000
};

byte TwoBar[8] = {  // Array of bytes
  B10100,
  B10100,
  B10100,
  B10100,
  B10100,
  B10100,
  B10100,
  B10100
};

byte ThreeBar[8] = {  // Array of bytes
  B10101,
  B10101,
  B10101,
  B10101,
  B10101,
  B10101,
  B10101,
  B10101
};

// Instantiate the Objects
LiquidCrystal_I2C lcd(0x27, 16, 2);  // 0x27 is the address of the test LCD (3F for the main LCD)
Si5351 si5351;


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

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

  // Initialize the DDS
  si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 25740);  // 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);

  lcd.createChar(1, OneBar);  // Create a custom character
  lcd.createChar(2, TwoBar);
  lcd.createChar(3, ThreeBar);
}

void loop() {
  CheckEncoder();
  CheckRadixSwitch();
  CheckTuneSwitch();
  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);
      SWR = constrain(SWR - 0.1, 1, 9);
    else
      // Increase frequency
      //freq = constrain(freq + radix, bandStart, bandEnd);
      SWR = constrain(SWR + 0.1, 1, 9);
  }
  encoderC = encoderA;

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

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

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

void CheckTuneSwitch() {
  if (digitalRead(TunePin) == 0)
    tune = 1;  // 1=tune

  if (digitalRead(TunePin) == 1)
    tune = 0;  // 0=no tune

  if (tune != oldtune) {
    lcd.setCursor(0, 0);
    lcd.print("                ");
    UpdateDisplay();
    UpdateRadixDisplay();
    SendFrequency();
    oldtune = tune;
  }
}

void CheckPTTPin() {
  if ((digitalRead(PTTPin) == 0) || (tune == 1))
    TX = 1;  // tranmitting
  if (digitalRead(PTTPin) == 1)
    TX = 0;  // receiving

  if (TX != oldTX) {
    SendFrequency();
    oldTX = TX;
  }
}

void UpdateDisplay() {
  if (tune == 0) {
    // Freq
    lcd.setCursor(0, 0);
    lcd.print(freq);
  }
  if (tune == 1) {

    int SWRtotal = SWR * 10;
    int NumberFullBars = (SWRtotal / 3) - 3;      // -3 to make SWR=1.0 the first bar on the left
    int remainder = SWRtotal % 3;

    for (int x = 0; x <= 15; x++) {
      lcd.setCursor(x, 0);

      if (x < NumberFullBars)
        lcd.write(byte(3));

      if ((x == NumberFullBars) && (remainder == 1))
        lcd.write(byte(1));

      if ((x == NumberFullBars) && (remainder == 2))
        lcd.write(byte(2));

      if (x == (NumberFullBars + 1))
        lcd.print(" ");
    }
  }
  // Power
  lcd.setCursor(0, 1);
  lcd.print("PWR:");
  lcd.print(FWD);
  // SWR
  lcd.setCursor(9, 1);
  lcd.print("SWR:");
  lcd.print(SWR);
}

void UpdateRadixDisplay() {
  if (tune == 0) {
    // 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 (tune == 0)  // no tune
  {
    if (TX == 1)  // Transmit
    {
      si5351.set_freq(((BFO_freq + freq) * 100ULL), SI5351_CLK2);  // VFO
      si5351.set_freq((BFO_freq * 100ULL), SI5351_CLK0);           // BFO
    } else                                                         // Receive
    {
      si5351.set_freq(((BFO_freq + freq) * 100ULL), SI5351_CLK0);  // VFO
      si5351.set_freq((BFO_freq * 100ULL), SI5351_CLK2);           // BFO
    }
  }

  if (tune == 1)  // tune
  {
  }
}