Code:
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_S6D02A1.h> // Hardware-specific library
#include <SPI.h>
#include <Wire.h>
#include <si5351.h>
//#include <Encoder.h>
#include <Rotary.h>
#include <Bounce2.h>
// This examples uses the hardware SPI only. Non-hardware SPI
// is just too slow (~8 times slower!)
#define BACKLIGHT 0 // backlight control signal
#define sclk 13 // Don't change
#define mosi 11 // Don't change
#define cs 2
#define dc 3
#define rst 1 // you can also connect this to the Arduino reset
#define ENCODER_BTN 16 //I use this instead of TuneSW
Adafruit_S6D02A1 display = Adafruit_S6D02A1(cs, dc, mosi, sclk, rst); // Invoke custom library
Rotary tune(15, 14); //pins 15 and 14 used for encoder
Si5351 si5351;
//const int8_t TuneSW =18; // low for fast tune - encoder pushbutton(I don't use this)
volatile uint32_t vfo = 1420000000ULL / SI5351_FREQ_MULT; //start freq - change to suit
volatile uint32_t LSB = 899950000ULL;
volatile uint32_t USB = 900150000ULL;
volatile uint32_t bfo = 900150000ULL; //start in usb
volatile uint32_t radix = 100;
volatile uint32_t lastVFO;
int myOldList[9]= {0,0,0,0,0,0,0,0,0};
uint32_t Bands[] {
1800000L, 3500000L, 7000000L, 10100000L, 14200000L, 18065000L, 21000000L, 24890000L, 28000000L
}; //not used at the moment
boolean changed_f = 0;
String tbfo = "USB";
void setup(void) {
Serial.begin(9600); // debug console
Wire.begin();
pinMode(BACKLIGHT, INPUT_PULLUP); // yanks up display BackLight signal
pinMode(ENCODER_BTN, INPUT_PULLUP); // tuning rate = high "radix"
attachInterrupt(14, chk_encoder, CHANGE); //I attach interrupts to encoder pins
attachInterrupt(15, chk_encoder, CHANGE); //but use the same Interrupt Service Routine //(chk_encoder())
si5351.init(SI5351_CRYSTAL_LOAD_8PF,0);
//si5351.set_correction(157);
// Set CLK0 to output vfo plus IF frequency with a fixed PLL frequency
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
si5351.set_freq((vfo * SI5351_FREQ_MULT) + bfo, SI5351_PLL_FIXED, SI5351_CLK0);
//volatile uint32_t vfoT = (vfo * SI5351_FREQ_MULT) + bfo; //test stuff
tbfo = "USB"; //for lower left display display
// Set CLK2 to output bfo frequency
si5351.set_freq( bfo, 0, SI5351_CLK2);
display.initR(INITR_BLACKTAB); // initialize a S6D02A1S chip, black tab
SPI.setClockDivider(SPI_CLOCK_DIV2); // crank up the spi
uint16_t time = millis();
display.setRotation(1); // 0 - Portrait, 1 - Lanscape
display.fillScreen(S6D02A1_BLACK);
display.setTextWrap(true);
delay(500);
//testdrawrects(S6D02A1_GREEN);
delay(500);
setUpDisplay();
display_frequency();
display_radix();
}
void loop() {
if(changed_f) //this flag is changed to yes(1) when the encoder changes
{
display_frequency();
//synt.simple_set_frequency(CLK0, frequency*F_MULT);
si5351.set_freq((vfo * SI5351_FREQ_MULT) + bfo, SI5351_PLL_FIXED, SI5351_CLK0);
si5351.drive_strength(SI5351_CLK0,SI5351_DRIVE_8MA);
if (vfo >= 10000000ULL & tbfo != "USB")
{
bfo = USB;
tbfo = "USB";
si5351.set_freq( bfo, 0, SI5351_CLK2);
Serial.println("We've switched from LSB to USB");
}
else if (vfo < 10000000ULL & tbfo != "LSB")
{
bfo = LSB;
tbfo = "LSB";
si5351.set_freq( bfo, 0, SI5351_CLK2);
Serial.println("We've switched from USB to LSB");
}
changed_f = 0; //and cleared back to no(0) after updates are made to the si5351
}
if (get_button())
{
switch (radix)
{
case 1:
radix = 10;
break;
case 10:
radix = 100;
break;
case 100:
radix = 1000;
break;
case 1000:
radix = 10000;
break;
case 10000:
radix = 100000;
break;
case 100000:
radix = 1;
break;
}
display_radix();
}
}
// show frequency
void display_frequency() {
//lastVFO = vfo;
char string[80]; // print format stuff - I always have to look this up :)
sprintf(string,"%d.%03d.%03d",vfo/1000000,(vfo-vfo/1000000*1000000)/1000,
vfo%1000 );
display.setCursor(35, 5);
display.setTextColor(S6D02A1_GREEN,S6D02A1_BLUE); //full display blanking -
display.setTextSize(2); //you really need the
display.print(string); //2nd parameter to keep the
} //display from flickering
void set_frequency(short dir)
{
if(dir == 1) //This routine is called by the Interrupt Service Routine chk_encoder()
vfo += radix; //which sets the vfo to its new value up or down plus or minus the
if(dir == -1) //the step size(radix)
vfo -= radix;
changed_f = 1; //it also sets this yes/no flag to yes to tell the loop that there has been a
} //a change in frequency
void chk_encoder(){ //This routine (ISR) is called by the Arduino
//Serial.println("inside encoder"); // every time the encoder changes. Interrupts
unsigned char result = tune.process(); // tell microprocessors, "STOP WHAT YOU
if (result) { // ARE DOING!....and take care of me before
//Serial.println(result == DIR_CW ? 1 : -1); //going any further"
if (result == DIR_CW) //calls set_frequency() with a +1 or -1
set_frequency(1);
else if (result == DIR_CCW)
set_frequency(-1);
}
}
void setUpDisplay(){
//display.fillRect(1,1,158,25,S6D02A1_BLUE);
//display.Color565(245, 179, 190);
display.fillScreen(S6D02A1_BLUE);
//display.fillRect(0,5,158,23,S6D02A1_BLUE);
display.fillRect(1,1,13,24,S6D02A1_RED);
//display.fillRect(1,1,13,24,Color565);
display.drawFastVLine(0, 0, 25, S6D02A1_WHITE);
display.drawFastVLine(159, 0, 25, S6D02A1_WHITE);
display.drawFastHLine(0,0,160,S6D02A1_WHITE);
display.drawFastHLine(0,25,160,S6D02A1_WHITE);
display.setCursor(1, 5);
display.setTextSize(2);
display.setTextColor(S6D02A1_GREEN);
display.println("A");
// display.setCursor(1, 90);
// display.setTextSize(1);
// display.setTextColor(S6D02A1_GREEN);
// display.println("USB RIT off 100Hz");
}
/**************************************/
/* Read the button with debouncing */
/**************************************/
boolean get_button()
{
if(!digitalRead(ENCODER_BTN))
{
delay(20);
if(!digitalRead(ENCODER_BTN))
{
while(!digitalRead(ENCODER_BTN));
return 1;
}
}
return 0;
}
void display_radix()
{
//display.fillRect(0,90,158,24,S6D02A1_BLUE);
display.setTextSize(1);
display.setTextColor(S6D02A1_GREEN,S6D02A1_BLUE);
display.setCursor(110, 85);
//display.println("USB RIT off 100Hz");
switch (radix)
{
case 1:
display.print(" 1");
break;
case 10:
display.print(" 10");
break;
case 100:
display.print(" 100");
break;
case 1000:
display.print(" 1k");
break;
case 10000:
display.print(" 10k");
break;
case 100000:
//display.setCursor(10, 1);
display.print(" 100k");
break;
//case 1000000:
//display.setCursor(9, 1);
//display.print("1000k"); //1MHz increments
//break;
}
display.print("Hz");
}