Saturday 2 August 2014

DDS AD9850 with encoder input and LCD display

Here's a sketch to use an AD9850 DDS with input from an encoder and output to an LCD display. This sketch will be further developed to display more parameters and to have inputs to change the scanning speed. The current one, here, increments the frequency by 10, 100, 1kHz or 10kHz per step when you press the encoder knob, not the most practical way to tune a radio.. will have to give this some thought.

Photo 08 06 2014 11 16 42

// DDS AD9850, encoder input
// display on LCD 16 * 2
// encoder A = 2, C (centre) = GND & B = 3

#include "DDS.h"
#include "Wire.h"
#include "LiquidCrystal_I2C.h"

#define ENCA 2
#define ENCB 3
// pin connections
#define RST  4     // Pin  RST
#define DATA 5     // Pin  DATA
#define FQ   6     // Pin  FQ
#define CLK  7     // Pin  CLK

#define BUTTON 8   // pin Button

// frequency change, by df
#define NC 0
#define UP 1
#define DWN 2

// I2C connections
#define SDA A4
#define SCL A5

// DDS object
DDS dds(CLK, FQ, DATA, RST);

// LCD object
LiquidCrystal_I2C lcd(0x27, 16, 2); 

double freq = 3600000L; // start freq Hz
double df = 100; // 100Hz change in frequency per click
byte chg = NC;   // flag NC = no change, UP = add df, DWN = subtract df
byte dsw = 0;    // delta freq = 10Hz

char *dtxt[4] = {
  " 10", "100", " 1K", "10K"}; // delta freq display values

void setup()
{

  pinMode(ENCA, INPUT_PULLUP); // encoder inputs
  pinMode(ENCB, INPUT_PULLUP);

  pinMode(BUTTON, INPUT_PULLUP); // button input
  
  attachInterrupt(0, doEnc, CHANGE); // interrupt on any change of pin 2

  dds.init();
  dds.setFrequency(freq);

  lcd.init();
  lcd.backlight();
  show(freq);
}

void loop()
{  
  int state;
  
  switch (chg)
  {
  case NC:
    break;
  case UP:
    freq += df;
    show(freq);
    break;
  case DWN:
    freq -= df;
    show(freq);
    break;
  }
  chg = NC;
  dds.setFrequency(freq);
  
  if(digitalRead(BUTTON) == LOW) // button pressed?
  {
    if(dsw == 3) dsw = 0;
    else dsw++;
  }
  switch(dsw)
  {
  case 0:
    df = 10;
    break;
  case 1:
    df = 100;
    break;
  case 2:
    df = 1000;
    break;
  case 3:
    df = 10000;
    break;
  }
  while(!digitalRead(BUTTON)); // wait for button release
  showd(dsw);

}

// display freq in MHz
void show(double f)
{
  lcd.setCursor(0, 0);
  lcd.print("VHF"); 

  lcd.setCursor(4, 0);
  lcd.print(f/1000000, 6);
  lcd.setCursor(13,0);
  lcd.print("MHz");
}

// display delta freq
void showd(byte d)
{
  lcd.setCursor(0, 1);
  lcd.print("STEP");
  lcd.setCursor(5,1);
  lcd.print(dtxt[d]);
}

void doEnc()
{
  if(digitalRead(ENCA) == digitalRead(ENCB))
    chg = UP;
  else
    chg = DWN;
}

No comments: