I have just received a new display shield and here is the AD9850 controlled by the Arduino and a display of amateur band and frequency. As the shield has only 5 buttons for user input (the sixth is a Reset button). I have chosen to use them for:
1 Select band - step through the amateur bands, on each band the band edges are known and when selected a mid band frequency is programmed
2 Left/right +/-10KHz and up/down +/-10Hz buttons. this make tuning a bit arduous as you have to push the buttons many times to tune a band, but you can tune to the nearest 10Hz.
The display shield has a series of resistors that mean the buttons output various voltages, these are measured by the analog input as digital 0-1023 data.
Code
#include "LiquidCrystal.h"
// DDS-9850 module programmer, with LCD display and button inputs
#define RESET 0 // Pin RST
#define DATA 1 // Pin DATA
#define FQ_UD 2 // Pin FQ
#define W_CLK 3 // Pin CLK
#define D4 4 // LCD data pins
#define D5 5
#define D6 6
#define D7 7
#define RS 8 // LCD RS * EN pins
#define EN 9
#define BUTTONS A0 // button sensor
// short high pulse
#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
// names of bands
char bandName[][5] = {"160", "80", "60", "40", "30", "20", "17", "15", "12", "10"};
// array lookup of lower, current and upper band limits
#define LOWER 0
#define CURRENT 1
#define UPPER 2
// band limits
double freqRange[10][3] = {
{1810000, 1900000, 2000000},
{3500000, 3600000, 3800000},
{5258000, 5100000,5406500},
{7000000, 7100000, 7200000},
{10100000, 10300000, 10150000},
{14000000, 14200000, 14350000},
{18068000, 18050000, 18168000},
{21000000, 21250000, 21450000},
{24890000, 24700000, 24990000},
{28000000, 28500000, 29700000}
};
// LCD object
LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
// band number
int band;
// actual frequency
float frequency;
void setup()
{
pinMode(FQ_UD, OUTPUT);
pinMode(W_CLK, OUTPUT);
pinMode(DATA, OUTPUT);
pinMode(RESET, OUTPUT);
pulseHigh(RESET);
pulseHigh(W_CLK);
pulseHigh(FQ_UD); // this pulse enables serial mode
lcd.begin(16, 2);
band = 0; // 160m band 0
frequency = freqRange[band][CURRENT]; // init frequency mid-band
}
void loop()
{
int x;
x = analogRead(BUTTONS);
if (x < 100)
{
while(analogRead(BUTTONS) < 100);
if(frequency < freqRange[band][UPPER]) frequency += 10000;
}
else if (x < 200)
{
while(analogRead(BUTTONS) < 200);
if(frequency < freqRange[band][UPPER]) frequency += 10;
}
else if (x < 400)
{
while(analogRead(BUTTONS) < 400);
if(frequency > freqRange[band][LOWER]) frequency -= 10;
}
else if (x < 600)
{
while(analogRead(BUTTONS) < 600);
if(frequency > freqRange[band][LOWER]) frequency -= 10000;
}
else if (x < 800)
{
while(analogRead(BUTTONS) < 800);
freqRange[band][CURRENT] = frequency; // save rpvious band freq
if(band < 9) band++;
else band = 0;
frequency = freqRange[band][CURRENT]; // load current band last freq
}
lcdDisplay(bandName[band], frequency);
sendFrequency(frequency); // freq Hz
}
// display LCD band & freq
void lcdDisplay(char* b, double f)
{
lcd.setCursor(0,0); // write band & freq
lcd.print("Band = ");
lcd.setCursor(0, 1);
lcd.print("Freq = ");
delay(100); // stop flicker
lcd.setCursor(7,0); // clear band data
lcd.print(" ");
lcd.setCursor(7,0); // write band data
lcd.print(b);
lcd.setCursor(7, 1); // clear freq data
lcd.print(" ");
lcd.setCursor(7, 1); // write freq data
lcd.print(f/1000);
}
// frequency calc = * /2^32
void sendFrequency(double frequency)
{
int32_t freq = frequency * 4294967295/125000000; // note 125 MHz clock on 9850
for (int b=0; b<4; b++, freq>>=8)
{
tfr_byte(freq & 0xFF);
}
tfr_byte(0x000); // Final control byte, all 0
pulseHigh(FQ_UD);
}
// transfers a byte, a bit at a time, LSB first via serial DATA line
void tfr_byte(byte data)
{
for (int i=0; i<8; i++, data>>=1)
{
digitalWrite(DATA, data & 0x01);
pulseHigh(W_CLK); //after each bit sent, CLK is pulsed high
}
}
No comments:
Post a Comment