Arduino sketch for the Kanga-UK / m0xpd Simple VFO System
/* | |
Kanga_VFO | |
Simple VFO System for the Arduino | |
with AD9850 DDS Sig Gen Module | |
and (16*4) LCD Display | |
m0xpd | |
April 2013 | |
All parts available from Kanga-UK: | |
http://www.kanga-products.co.uk/ | |
For further information: | |
http://m0xpd.blogspot.co.uk/ | |
*/ | |
#include<stdlib.h> | |
// include the LCD display library code: | |
#include <LiquidCrystal.h> | |
// set pin numbers: | |
// AD9850 Module.... | |
const int W_CLK = 2; | |
const int FQ_UD = 3; | |
const int DATA = 4; | |
const int RESET = 5; | |
// Hitachi Interface LCD... | |
const int RS = 6; | |
const int E = 7; | |
const int DB4 = 8; | |
const int DB5 = 9; | |
const int DB6 = 10; | |
const int DB7 = 11; | |
// Rotary Encoder... | |
const int RotEncBPin = 12; | |
const int RotEncAPin = 13; | |
const int RotEncSwPin = A0; | |
// Define and initialise some Rotary Encoder Variables... | |
boolean OldRotEncA = true; | |
boolean RotEncA = true; | |
boolean RotEncB = true; | |
boolean RotEncSw = true; | |
// Band data (just covering CW segments of the 160:20m bands at present) | |
long basefreqs[] = {1810000, 3500000, 7000000, 10100000, 14000000}; | |
long widths[] = {1838000, 3580000, 7040000, 10140000, 14070000}; | |
// start in 40m band... | |
int band = 2; | |
// start at QRP freq... | |
double basefreq = 7030000; | |
double freq = basefreq; | |
unsigned deltaf[] = {1, 10, 100}; | |
unsigned dfindex = 0; | |
long freqValue = 0; | |
long oldfreqValue = 0; | |
// set up an instance of an LDCD display, with name "lcd"... | |
LiquidCrystal lcd(RS, E, DB4, DB5, DB6, DB7); | |
// Subroutine to generate a positive pulse on 'pin'... | |
void pulseHigh(int pin) { | |
digitalWrite(pin, HIGH); | |
digitalWrite(pin, LOW); | |
} | |
// subroutine to clear a line on the Kanga 16*4 display... | |
void LCD_Clear_Line(int line) { | |
switch (line) { | |
case 0: | |
lcd.setCursor(0, 0); | |
lcd.print(" "); | |
break; | |
case 1: | |
lcd.setCursor(0, 1); | |
lcd.print(" "); | |
break; | |
case 2: | |
lcd.setCursor(16, 0); | |
lcd.print(" "); | |
break; | |
case 3: | |
lcd.setCursor(16, 1); | |
lcd.print(" "); | |
break; | |
default: | |
int t=1; | |
} | |
} | |
// subroutine to display the frequency... | |
void LCD_Display_Freq(double frequency) { | |
lcd.setCursor(18, 0); | |
lcd.print(frequency/1e6,6); lcd.print(" MHz"); | |
// establish the cursor position | |
int c_position=24-dfindex; | |
if (band>2) { | |
c_position=c_position+1; | |
} | |
// set up blinking cursor... | |
lcd.setCursor(c_position, 0); | |
lcd.blink(); | |
} | |
// calculate and send frequency code to DDS Module... | |
void sendFrequency(double frequency) { | |
int32_t freq = frequency * 4294967295/125000000; | |
for (int b=0; b<4; b++, freq>>=8) { | |
shiftOut(DATA, W_CLK, LSBFIRST, freq & 0xFF); | |
} | |
shiftOut(DATA, W_CLK, LSBFIRST, 0x00); | |
pulseHigh(FQ_UD); | |
} | |
void setup() { | |
pinMode(FQ_UD, OUTPUT); | |
pinMode(W_CLK, OUTPUT); | |
pinMode(DATA, OUTPUT); | |
pinMode(RESET, OUTPUT); | |
pinMode(RotEncAPin, INPUT); | |
pinMode(RotEncBPin, INPUT); | |
pinMode(RotEncSwPin, INPUT); | |
/* | |
If you're using an older Arduino UNO, | |
or an Arduino MEGA 2560, | |
you must add a 2k2 pull-up on the D13 pin | |
to overcome the loading from the un-buffered LED. | |
If you're using an Arduino UNO R3 or MEGA 2560 R3 | |
you can use the internal pull-up, | |
by un-commenting the following line... | |
*/ | |
//digitalWrite(RotEncAPin,HIGH); | |
digitalWrite(RotEncBPin,HIGH); | |
digitalWrite(RotEncSwPin,HIGH); | |
pulseHigh(RESET); | |
pulseHigh(W_CLK); | |
pulseHigh(FQ_UD); // this pulse enables serial mode | |
freq = basefreq+10*freqValue; | |
sendFrequency(freq); | |
// set up the LCD's number of columns and rows: | |
lcd.begin(16, 4); | |
// Print header message to the LCD. | |
lcd.print(" KANGA-UK "); | |
LCD_Display_Freq(freq); | |
} | |
void loop(){ | |
// read the state of the inputs: | |
RotEncA = digitalRead(RotEncAPin); | |
RotEncB = digitalRead(RotEncBPin); | |
RotEncSw = digitalRead(RotEncSwPin); | |
if ((RotEncA == HIGH)&&(OldRotEncA == LOW)){ | |
if (RotEncB == LOW) { | |
freqValue=freqValue+deltaf[dfindex]; | |
} | |
else { | |
freqValue=freqValue-deltaf[dfindex]; | |
} | |
freq = basefreq+10*freqValue; | |
if (freq > widths[band]) { | |
band = band+1; | |
if (band>4) { | |
band = 4; | |
} | |
basefreq=basefreqs[band]; | |
freq=basefreq; | |
freqValue=0; | |
LCD_Clear_Line(2); | |
} | |
else if (freq < basefreqs[band]) { | |
band = band-1; | |
if (band < 0){ | |
band = 0; | |
} | |
basefreq=widths[band]; | |
freq=basefreq; | |
freqValue=0; | |
LCD_Clear_Line(2); | |
} | |
sendFrequency(freq); | |
LCD_Display_Freq(freq); | |
oldfreqValue = freqValue; | |
} | |
OldRotEncA=RotEncA; | |
if (RotEncSw == LOW) { | |
dfindex=dfindex+1; | |
if (dfindex>2) { | |
dfindex=0; | |
} | |
delay(250); | |
LCD_Display_Freq(freq); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment