-[[.:start]]
====== 60m Transceiver ======
The 60m transceiver has the following features, which vary according to the loaded firmware
* Channelized operation
* LCD display
* Frequency
* Mode (SSB / CW)
* Modulation Source (Mic/Key/Data)
* RX / TX status
* 9MHz IF with Xtal filter
* SSB & CW set via mode switch
* Approx 3W PEP
* Digital mode input/output and PTT via 9-pin D
* SSB Mic input via 8-pin round "Icom" connector
* Modulation Source (Mic or Data) can chosen via select switch
* Scan start switch - scan a preset group of channels - cycles continuously, no "squelch"
* Use of Jenal SC2 CCIR493 Selcal microphone can be supported - including scanning
===== Arduino Versions =====
There are several different firmware versions....this is just a sample...
==== RX Only, with SSB, CW & scan ====
{{ :public:radio:topics:arduino:gm4slv_60m_channels_cwscan_noptt_new_calibration_130523.ino |}}
++++ Firmware (Click to view) |
#include
#include
char version[] = "v0.1";
const long channel_array[] =
{
5258500,5260000,5261000,5262000,5263000, 5276000,
5278500,5279000,5287200,5290000,5298000,
5301000,5304000,5317000,5320000,5333000,
5334000,5335000,5354000,5355000,5362000,
5363000,5364700,5366500,5371500,5378000,
5379000,5395000,5398500,5403500,
5345000,5245000,5450000,5505000,5680000,
5195000,5616000,5649000
} ;
const long scan_array[] =
{
5260000,5261000,
5262000,5263000,
5366500,5354000,
5355000,
} ;
const int mems = sizeof(channel_array)/sizeof(long);
const int scan_mems = sizeof(scan_array)/sizeof(long);
// the last "no_scan" number channels of
// channel_array are not to be scanned.
// Put the channels not to be scanned last
// in the array and update no_scan to reflect.
const int no_scan = 0;
const long bandStart = 5000000;
const long bandEnd = 6000000;
const long txcio = 9001200;
const long cwoffset = 600;
const long filteroffset = 500;
volatile int channel = 01;
volatile long freq = channel_array[channel]; //
volatile long oldfreq = 0;
volatile long currentfreq = 0;
volatile int updatedisplay = 0;
// Rotary encoder pins and other inputs
static const int rotAPin = 2;
static const int rotBPin = 3;
static const int pushSwPin = 4;
static const int mictxrxPin = 5;
static const int txRLA1Pin = 7;
static const int txRLA2Pin = 6;
static const int datatxrxPin = 8;
static const int modRLAPin = 9;
static const int modeSWPin = 11;
static const int scanSWPin = 10;
volatile int scanning = 0;
volatile int old_scanning = 0;
volatile int tx = 0;
volatile int oldtxrx = 0;
volatile int mod = 0;
volatile int oldmod = 0;
volatile int channel_freq = 0; // push-button to toggle tune method
volatile int old_channel_freq = 0;
volatile long scan_freq = scan_array[channel];
volatile long old_scan_freq = 0;
volatile int mode = 1; // 1 = USB/LSB, 0 = CW
volatile int oldmode = 0;
// Rotary encoder variables, used by interrupt routines
volatile int rotState = 0;
volatile int rotAval = 1;
volatile int rotBval = 1;
int digit1 = 0;
int digit2 = 0;
int digit3 = 0;
int digit4 = 0;
int digit5 = 0;
int digit6 = 0;
int digit7 = 0;
// Instantiate the Objects
rgb_lcd lcd;
Si5351 si5351;
byte customChar[8] = {
0b11111,
0b11011,
0b11001,
0b00000,
0b11001,
0b11011,
0b11111,
0b11111
};
void setup()
{
// Set up frequency and radix switches
pinMode(rotAPin, INPUT_PULLUP);
pinMode(rotBPin, INPUT_PULLUP);
pinMode(pushSwPin, INPUT_PULLUP);
pinMode(mictxrxPin, INPUT_PULLUP);
pinMode(datatxrxPin, INPUT_PULLUP);
pinMode(modeSWPin, INPUT_PULLUP);
pinMode(scanSWPin, INPUT_PULLUP);
pinMode(txRLA1Pin, OUTPUT);
pinMode(txRLA2Pin, OUTPUT);
pinMode(modRLAPin, OUTPUT);
digitalWrite(txRLA1Pin, LOW);
digitalWrite(txRLA2Pin, LOW);
digitalWrite(modRLAPin, LOW);
// Set up interrupt pins
attachInterrupt(digitalPinToInterrupt(rotAPin), ISRrotAChange, CHANGE);
attachInterrupt(digitalPinToInterrupt(rotBPin), ISRrotBChange, CHANGE);
// Initialize the display
lcd.begin(16, 2);
lcd.createChar(0, customChar); // create a new custom character
lcd.cursor();
// Initialize the Si5351
//si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, -31200); //
//si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA); // 2 mA for HB mixers
//si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_8MA); // 2 mA for HB mixers
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
si5351.set_correction(-34976, SI5351_PLL_INPUT_XO);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);
si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_8MA);
// Update display and send start frequency
UpdateDisplay();
SendFrequency();
}
void loop()
{
CheckScanSwitch();
//CheckTXSwitch();
//CheckModSwitch();
CheckModeSwitch();
// Check to see if the freq has changed
currentfreq = getfreq(); // Interrupt safe method to get the current frequency
if (currentfreq != oldfreq)
{
oldfreq = currentfreq;
UpdateDisplay();
SendFrequency();
}
// Check the rotary encoder (radix) swith
if (digitalRead(pushSwPin) == LOW) // Read the rotary encoder switch
{
delay(500);
if (digitalRead(pushSwPin) == LOW)
{
if (channel_freq == 1)
{
channel_freq = 0;
}
else if (channel_freq == 0)
{
channel_freq = 1;
}
//delay(50);
UpdateDisplay();
}
}
} // end of main loop
long getfreq()
{
long temp_freq;
cli();
temp_freq = freq;
sei();
return temp_freq;
}
void CheckScanSwitch()
{
if (digitalRead(scanSWPin) == 0)
{
scanning = 1;
scan_freq = 0;
channel = channel + 1;
if (channel > scan_mems - (no_scan + 1))
{
channel = 0;
}
freq = scan_array[channel];
UpdateDisplay();
SendFrequency();
delay(500);
}
else
{
if (scanning != old_scanning)
{
scanning = 0;
UpdateDisplay();
}
old_scanning = scanning;
}
}
//void CheckModSwitch()
//{
// if (digitalRead(modSWPin) == 0)
// mod = 0; // 0 = Phone
// else if (digitalRead(modSWPin) == 1)
// mod = 1; // 1=Data
// if (mod != oldmod)
// {
// if ( mod == 0)
// {
// digitalWrite(modRLAPin,LOW);
// }
// else
// {
// digitalWrite(modRLAPin,HIGH);
// }
// UpdateDisplay();
// SendFrequency();
// oldmod = mod;
// }
//}
void CheckModeSwitch()
{
if (digitalRead(modeSWPin) == 0)
mode = 0; // 0 = CW
else if (digitalRead(modeSWPin) == 1)
mode = 1; // 1=SSB
if (mode != oldmode)
{
if ( mode == 0)
{
}
else
{
}
UpdateDisplay();
SendFrequency();
oldmode = mode;
}
}
void CheckTXSwitch()
{
if (scanning == 0)
{
if (digitalRead(mictxrxPin) == 0)
{
tx = 1; // 1=TX
mod = 0;
} else if (digitalRead(datatxrxPin) == 0)
{ tx = 1;
mod = 1;
} else if (digitalRead(mictxrxPin) == 1)
{ tx = 0; // 0=Phone
} else if (digitalRead(datatxrxPin) == 1)
{ tx = 0;
}
if (tx != oldtxrx)
{
if ( tx == 1)
{
if ( mod == 0 )
{
digitalWrite(modRLAPin,LOW);
}
else if ( mod == 1 )
{
digitalWrite(modRLAPin,HIGH);
}
digitalWrite(txRLA1Pin,HIGH);
digitalWrite(txRLA2Pin,HIGH);
}
else
{
digitalWrite(txRLA1Pin,LOW);
digitalWrite(txRLA2Pin,LOW);
}
UpdateDisplay();
SendFrequency();
oldtxrx = tx;
}
}
}
// 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();
}
}
// Determine which way the rotary encoder is rotating and action as required
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)
{
// either increment the radix or freq
if (channel_freq == 1)
{
updatedisplay = 1;
if (mode == 1)
{
freq = freq + 500;
}
else
{
freq = freq + 100;
}
if (freq > bandEnd)
{
freq = bandEnd;
}
}
else
{
channel = channel + 1;
if (channel > mems -1)
{
channel = 0;
}
freq = channel_array[channel];
}
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)
{
if ( channel_freq == 1 )
{
updatedisplay = 1;
if (mode == 1)
{
freq = freq - 500;
}
else
{
freq = freq - 100;
}
if (freq < bandStart)
{
freq = bandStart;
}
}
else
{
channel = channel - 1;
if (channel < 0)
{
channel = mems - 1;
}
freq = channel_array[channel];
}
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 UpdateDisplay()
{
digit1 = (freq%10);
digit2 = ((freq/10)%10);
digit3 = ((freq/100)%10);
digit4 = ((freq/1000)%10);
digit5 = ((freq/10000)%10);
digit6 = ((freq/100000)%10);
digit7 = ((freq/1000000)%10);
lcd.setCursor(0,0);
lcd.print(digit7);
lcd.setCursor(1,0);
lcd.print(",");
lcd.setCursor(2,0);
lcd.print(digit6);
lcd.setCursor(3,0);
lcd.print(digit5);
lcd.setCursor(4,0);
lcd.print(digit4);
lcd.setCursor(5,0);
lcd.print(".");
lcd.setCursor(6,0);
lcd.print(digit3);
lcd.setCursor(7,0);
lcd.print(digit2);
lcd.setCursor(8,0);
lcd.print("kHz");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(channel,1);
if (scanning == 1)
{
// lcd.print("|");
lcd.write((byte)0); // print the custom char at (2, 0)
}
/*
//if (channel < 10)
//{
//lcd.print("0");
//}
//lcd.print(channel);
lcd.setCursor(0,1);
if (freq == 5287200 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("WSPR1");
}
if (freq == 5290000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("ORK");
}
if (freq == 5364700 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("WSPR2");
}
if (freq == 5450000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("RAF");
}
if (freq == 5505000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("EIP");
}
if (freq == 5317000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("VMARS");
}
if (freq == 5366500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FK");
}
if (freq == 5258500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FA");
}
if (freq == 5278500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FB");
}
if (freq == 5288500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FC");
}
if (freq == 5371500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FL");
}
if (freq == 5398500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FE");
}
if (freq == 5403500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FM");
}
if (freq == 5195000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("DRA5");
}
if (freq == 5262000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("QRP CW");
}
if ((freq >= 5259000) && (freq < 5262000) )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("CW");
}
*/
lcd.setCursor(14,0);
if (tx == 0)
{ lcd.print("RX");
} else if (tx == 1)
{
lcd.print("TX");
}
lcd.setCursor(8,1);
if (mode == 1)
{
lcd.print("SSB");
}
if (mode == 0)
{
lcd.print(" CW");
}
lcd.setCursor(12,1);
if ( mode == 0 )
{
lcd.print(" Key");
//lcd.print(version);
}
else
{
if (mod == 0)
{
lcd.print(" Mic");
//lcd.print(version);
}
else
{
lcd.print("Data");
//lcd.print(version);
}
}
if (channel_freq == 1)
{
if (mode == 1)
{
lcd.setCursor(6,0);
}
else if ( mode == 0 )
{
lcd.setCursor(7,0);
}
lcd.blink();
}
else
{
lcd.noBlink();
}
} // end of updatedisplay()
void SendFrequency()
{
if (mode == 1 ) // SSB
{
si5351.set_freq(((txcio + freq) * 100ULL), SI5351_CLK0); // VFO
si5351.set_freq((txcio * 100ULL), SI5351_CLK2); // BFO
}
else if (mode == 0) // CW
if ( tx == 0 )
{
si5351.set_freq(((txcio + freq - cwoffset - filteroffset) * 100ULL), SI5351_CLK0); // VFO
si5351.set_freq(((txcio - filteroffset) * 100ULL), SI5351_CLK2); // BFO
}
else if (tx == 1 )
{
si5351.set_freq(((txcio + freq - cwoffset - filteroffset) * 100ULL), SI5351_CLK0); // VFO
si5351.set_freq(((txcio - cwoffset - filteroffset) * 100ULL), SI5351_CLK2); // BFO
}
} // end of sendfrequency()
++++
==== Full TX/RX - with SSB, CW & Scan ====
{{ :public:radio:topics:arduino:gm4slv_60m_channels_cwscan_ptt_new_calibration_230823.ino |}}
++++ Firmware (Click to view) |
#include
#include
char version[] = "v0.1";
const long channel_array[] =
{
5258500,5260000,5261000,5262000,5263000, 5276000,
5278500,5279000,5287200,5290000,5298000,
5301000,5304000,5317000,5320000,5333000,
5334000,5335000,5354000,5355000,5362000,
5363000,5364700,5366500,5371500,5378000,
5379000,5395000,5398500,5403500,
5345000,5245000,5450000,5505000,5680000,
5195000,5616000,5649000
} ;
const long scan_array[] =
{
5260000,5261000,
5262000,5263000,
5366500,5354000,
5355000,
} ;
const int mems = sizeof(channel_array)/sizeof(long);
const int scan_mems = sizeof(scan_array)/sizeof(long);
// the last "no_scan" number channels of
// channel_array are not to be scanned.
// Put the channels not to be scanned last
// in the array and update no_scan to reflect.
const int no_scan = 0;
const long bandStart = 5000000;
const long bandEnd = 6000000;
const long txcio = 9001200;
const long cwoffset = 600;
const long filteroffset = 500;
volatile int channel = 01;
volatile long freq = channel_array[channel]; //
volatile long oldfreq = 0;
volatile long currentfreq = 0;
volatile int updatedisplay = 0;
// Rotary encoder pins and other inputs
static const int rotAPin = 2;
static const int rotBPin = 3;
static const int pushSwPin = 4;
static const int mictxrxPin = 5;
static const int txRLA1Pin = 7;
static const int txRLA2Pin = 6;
static const int datatxrxPin = 8;
static const int modRLAPin = 9;
static const int modeSWPin = 11;
static const int scanSWPin = 10;
volatile int scanning = 0;
volatile int old_scanning = 0;
volatile int tx = 0;
volatile int oldtxrx = 0;
volatile int mod = 0;
volatile int oldmod = 0;
volatile int channel_freq = 0; // push-button to toggle tune method
volatile int old_channel_freq = 0;
volatile long scan_freq = scan_array[channel];
volatile long old_scan_freq = 0;
volatile int mode = 1; // 1 = USB/LSB, 0 = CW
volatile int oldmode = 0;
// Rotary encoder variables, used by interrupt routines
volatile int rotState = 0;
volatile int rotAval = 1;
volatile int rotBval = 1;
int digit1 = 0;
int digit2 = 0;
int digit3 = 0;
int digit4 = 0;
int digit5 = 0;
int digit6 = 0;
int digit7 = 0;
// Instantiate the Objects
rgb_lcd lcd;
Si5351 si5351;
byte customChar[8] = {
0b11111,
0b11011,
0b11001,
0b00000,
0b11001,
0b11011,
0b11111,
0b11111
};
void setup()
{
// Set up frequency and radix switches
pinMode(rotAPin, INPUT_PULLUP);
pinMode(rotBPin, INPUT_PULLUP);
pinMode(pushSwPin, INPUT_PULLUP);
pinMode(mictxrxPin, INPUT_PULLUP);
pinMode(datatxrxPin, INPUT_PULLUP);
pinMode(modeSWPin, INPUT_PULLUP);
pinMode(scanSWPin, INPUT_PULLUP);
pinMode(txRLA1Pin, OUTPUT);
pinMode(txRLA2Pin, OUTPUT);
pinMode(modRLAPin, OUTPUT);
digitalWrite(txRLA1Pin, LOW);
digitalWrite(txRLA2Pin, LOW);
digitalWrite(modRLAPin, LOW);
// Set up interrupt pins
attachInterrupt(digitalPinToInterrupt(rotAPin), ISRrotAChange, CHANGE);
attachInterrupt(digitalPinToInterrupt(rotBPin), ISRrotBChange, CHANGE);
// Initialize the display
lcd.begin(16, 2);
lcd.createChar(0, customChar); // create a new custom character
lcd.cursor();
// Initialize the Si5351
//si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, -31200); //
//si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA); // 2 mA for HB mixers
//si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_8MA); // 2 mA for HB mixers
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
si5351.set_correction(-34976, SI5351_PLL_INPUT_XO);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
si5351.drive_strength(SI5351_CLK0, SI5351_DRIVE_8MA);
si5351.drive_strength(SI5351_CLK2, SI5351_DRIVE_8MA);
// Update display and send start frequency
UpdateDisplay();
SendFrequency();
}
void loop()
{
CheckScanSwitch();
CheckTXSwitch();
//CheckModSwitch();
CheckModeSwitch();
// Check to see if the freq has changed
currentfreq = getfreq(); // Interrupt safe method to get the current frequency
if (currentfreq != oldfreq)
{
oldfreq = currentfreq;
UpdateDisplay();
SendFrequency();
}
// Check the rotary encoder (radix) swith
if (digitalRead(pushSwPin) == LOW) // Read the rotary encoder switch
{
delay(500);
if (digitalRead(pushSwPin) == LOW)
{
if (channel_freq == 1)
{
channel_freq = 0;
}
else if (channel_freq == 0)
{
channel_freq = 1;
}
//delay(50);
UpdateDisplay();
}
}
} // end of main loop
long getfreq()
{
long temp_freq;
cli();
temp_freq = freq;
sei();
return temp_freq;
}
void CheckScanSwitch()
{
if (digitalRead(scanSWPin) == 0)
{
scanning = 1;
scan_freq = 0;
channel = channel + 1;
if (channel > scan_mems - (no_scan + 1))
{
channel = 0;
}
freq = scan_array[channel];
UpdateDisplay();
SendFrequency();
delay(500);
}
else
{
if (scanning != old_scanning)
{
scanning = 0;
UpdateDisplay();
}
old_scanning = scanning;
}
}
//void CheckModSwitch()
//{
// if (digitalRead(modSWPin) == 0)
// mod = 0; // 0 = Phone
// else if (digitalRead(modSWPin) == 1)
// mod = 1; // 1=Data
// if (mod != oldmod)
// {
// if ( mod == 0)
// {
// digitalWrite(modRLAPin,LOW);
// }
// else
// {
// digitalWrite(modRLAPin,HIGH);
// }
// UpdateDisplay();
// SendFrequency();
// oldmod = mod;
// }
//}
void CheckModeSwitch()
{
if (digitalRead(modeSWPin) == 0)
mode = 0; // 0 = CW
else if (digitalRead(modeSWPin) == 1)
mode = 1; // 1=SSB
if (mode != oldmode)
{
if ( mode == 0)
{
}
else
{
}
UpdateDisplay();
SendFrequency();
oldmode = mode;
}
}
void CheckTXSwitch()
{
if (scanning == 0)
{
if (digitalRead(mictxrxPin) == 0)
{
tx = 1; // 1=TX
mod = 0;
} else if (digitalRead(datatxrxPin) == 0)
{ tx = 1;
mod = 1;
} else if (digitalRead(mictxrxPin) == 1)
{ tx = 0; // 0=Phone
} else if (digitalRead(datatxrxPin) == 1)
{ tx = 0;
}
if (tx != oldtxrx)
{
if ( tx == 1)
{
if ( mod == 0 )
{
digitalWrite(modRLAPin,LOW);
}
else if ( mod == 1 )
{
digitalWrite(modRLAPin,HIGH);
}
digitalWrite(txRLA1Pin,HIGH);
digitalWrite(txRLA2Pin,HIGH);
}
else
{
digitalWrite(txRLA1Pin,LOW);
digitalWrite(txRLA2Pin,LOW);
}
UpdateDisplay();
SendFrequency();
oldtxrx = tx;
}
}
}
// 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();
}
}
// Determine which way the rotary encoder is rotating and action as required
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)
{
// either increment the radix or freq
if (channel_freq == 1)
{
updatedisplay = 1;
if (mode == 1)
{
freq = freq + 500;
}
else
{
freq = freq + 100;
}
if (freq > bandEnd)
{
freq = bandEnd;
}
}
else
{
channel = channel + 1;
if (channel > mems -1)
{
channel = 0;
}
freq = channel_array[channel];
}
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)
{
if ( channel_freq == 1 )
{
updatedisplay = 1;
if (mode == 1)
{
freq = freq - 500;
}
else
{
freq = freq - 100;
}
if (freq < bandStart)
{
freq = bandStart;
}
}
else
{
channel = channel - 1;
if (channel < 0)
{
channel = mems - 1;
}
freq = channel_array[channel];
}
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 UpdateDisplay()
{
digit1 = (freq%10);
digit2 = ((freq/10)%10);
digit3 = ((freq/100)%10);
digit4 = ((freq/1000)%10);
digit5 = ((freq/10000)%10);
digit6 = ((freq/100000)%10);
digit7 = ((freq/1000000)%10);
lcd.setCursor(0,0);
lcd.print(digit7);
lcd.setCursor(1,0);
lcd.print(",");
lcd.setCursor(2,0);
lcd.print(digit6);
lcd.setCursor(3,0);
lcd.print(digit5);
lcd.setCursor(4,0);
lcd.print(digit4);
lcd.setCursor(5,0);
lcd.print(".");
lcd.setCursor(6,0);
lcd.print(digit3);
lcd.setCursor(7,0);
lcd.print(digit2);
lcd.setCursor(8,0);
lcd.print("kHz");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(channel,1);
if (scanning == 1)
{
// lcd.print("|");
lcd.write((byte)0); // print the custom char at (2, 0)
}
/*
//if (channel < 10)
//{
//lcd.print("0");
//}
//lcd.print(channel);
lcd.setCursor(0,1);
if (freq == 5287200 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("WSPR1");
}
if (freq == 5290000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("ORK");
}
if (freq == 5364700 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("WSPR2");
}
if (freq == 5450000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("RAF");
}
if (freq == 5505000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("EIP");
}
if (freq == 5317000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("VMARS");
}
if (freq == 5366500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FK");
}
if (freq == 5258500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FA");
}
if (freq == 5278500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FB");
}
if (freq == 5288500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FC");
}
if (freq == 5371500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FL");
}
if (freq == 5398500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FE");
}
if (freq == 5403500 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("FM");
}
if (freq == 5195000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("DRA5");
}
if (freq == 5262000 )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("QRP CW");
}
if ((freq >= 5259000) && (freq < 5262000) )
{
//lcd.setCursor(3,1);
//lcd.print(" ");
//lcd.setCursor(3,1);
lcd.print("CW");
}
*/
lcd.setCursor(14,0);
if (tx == 0)
{ lcd.print("RX");
} else if (tx == 1)
{
lcd.print("TX");
}
lcd.setCursor(8,1);
if (mode == 1)
{
lcd.print("SSB");
}
if (mode == 0)
{
lcd.print(" CW");
}
lcd.setCursor(12,1);
if ( mode == 0 )
{
lcd.print(" Key");
//lcd.print(version);
}
else
{
if (mod == 0)
{
lcd.print(" Mic");
//lcd.print(version);
}
else
{
lcd.print("Data");
//lcd.print(version);
}
}
if (channel_freq == 1)
{
if (mode == 1)
{
lcd.setCursor(6,0);
}
else if ( mode == 0 )
{
lcd.setCursor(7,0);
}
lcd.blink();
}
else
{
lcd.noBlink();
}
} // end of updatedisplay()
void SendFrequency()
{
if (mode == 1 ) // SSB
{
si5351.set_freq(((txcio + freq) * 100ULL), SI5351_CLK0); // VFO
si5351.set_freq((txcio * 100ULL), SI5351_CLK2); // BFO
}
else if (mode == 0) // CW
if ( tx == 0 )
{
si5351.set_freq(((txcio + freq - cwoffset - filteroffset) * 100ULL), SI5351_CLK0); // VFO
si5351.set_freq(((txcio - filteroffset) * 100ULL), SI5351_CLK2); // BFO
}
else if (tx == 1 )
{
si5351.set_freq(((txcio + freq - cwoffset - filteroffset) * 100ULL), SI5351_CLK0); // VFO
si5351.set_freq(((txcio - cwoffset - filteroffset) * 100ULL), SI5351_CLK2); // BFO
}
} // end of sendfrequency()
++++
===== Further Information =====
Page created : 11/07/26 10:09 BST
Page updated : ~~LASTMOD~~
{{tag>radio arduino }}