Friday, 22 August 2014

Response plotter

I had a quick idea yesterday. To take an AD9850, set a start and end frequencies, and a step frequency. Then drive it to step from start to end.

The output would then be fed to a tuned circuit, and the response measured by an RF probe and fed to the analog input of the Arduino.

The Analog input would be plotted against frequency to show the tuned circuit's response curve.

Here's the setup:

Photo 08 21 2014 14 49 37

The control is the rotary encoder. First turn it to select the start frequency, then push the button, now select the end frequency. A further push starts the scan. Like this

Photo 08 21 2014 14 43 29

Photo 08 21 2014 14 43 43

The result is shown on the Monitor, like this

Screen Shot 2014 08 21 at 14 41 59

Code

// CONNECTIONS
// A5-A0 side
// ------
// encoder KY-040
// o Grey 2 CK
// o White 3 DT
// o Blue 8 SW
// o Violet +5
// o Black GND
//
// display I2C LCD 16 * 2
// o Green A5 SCL
// o Yellow A4 SDA
// o Red GND
// o Orange +5
// ------
// D0-D13 side
//
// RF bus hardware output
// o GND
// o DSB out
// o I to SDR
// o Q to SDR
// o S0 to DSB in
// o S1 to TX (selectable S1 ad9850 or DSB out)
//
// selector output to S1: CW-S1-DSB 

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

// encoder pin connections and +5V & GND
#define CK 2
#define DT 3
#define BUTTON 8   // pin Button

// DDS pin connections
#define RST  4     // Pin  RST
#define DATA 5     // Pin  DATA
#define FQ   6     // Pin  FQ
#define CLK  7     // Pin  CLK

// input connection
#define IN A0

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

// commands
#define SF 0 // set start freq
#define EF 1 // set end freq
#define SC 2 // scan start

// output print scale factor
#define FACTOR 2 

// Encoder object
Encoder enc(DT, CK);

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

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

double freq; // scan frequency
double freq1 = 6500000L; // init start & end
double freq2 = 7500000L;
long tune = 10000L; // fix button tune step and scan delta steps
long delta = 50000L;
long pos = 0; // enc positions
long newpos;
byte act = 0; // init set freq1

void setup()
{
  pinMode(BUTTON, INPUT_PULLUP); // button input

  Serial.begin(9600); // serial comms

  enc.write(0); // init encoder

  dds.init(); // init DDS
  dds.setFrequency(freq1); // set start freq

  lcd.init(); // init LCD
  lcd.backlight();
}

void loop()
{  
  byte tag;

  if(digitalRead(BUTTON) == LOW) // button pressed?
  {
    while(!digitalRead(BUTTON)); // wait for button release
    if(act == 2) act = 0; // chose actions
    else act++;
  }
  switch(act) // change delta freq
  {
  case SF: // change start freq1 in 100kHz steps
    tag = 0;
    freq1 = change(freq1);
    break;
  case EF: // change end freq2 in 100kHz steps
    tag = 1;
    freq2 = change(freq2);
    break;
  case SC: // start scan
    tag = 2;
    for(freq = freq1; freq <= freq2; freq += delta)
    { 
      delay(50);
      dds.setFrequency(freq); // output freq
      show(tag, freq1, freq); // display scan freq
      volts(freq, analogRead(IN)); // output to monitor
    }
    act = 0;
    break;
  }
  show(tag, freq1, freq2);
}

// change freq, returns new freq
long change(long f)
{
  // encoder read, updates freq
  newpos = enc.read();
  if(newpos != pos)
    f += tune * (newpos - pos) / 4; // enc gives 4 pulses per click!
  pos = newpos;
  return f;
}

// display start & end freqs in MHz
void show(byte t, double f1, double f2)
{ 
  if(t == 0) // line 1 delete ">", line 0 put ">"
  {
    lcd.setCursor(0,1);
    lcd.print(" ");
    lcd.setCursor(0,0);
    lcd.print(">");
  }
  if(t == 1) // line 0 delete ">", line 1 put ">"
  {
    lcd.setCursor(0,0);
    lcd.print(" ");
    lcd.setCursor(0,1);
    lcd.print(">");
  }

  if(t == 0 || t == 1) // line 0 f1 or "SCAN"
  {
    lcd.setCursor(4,0);
    lcd.print(f1/1000000, 6);
    lcd.setCursor(13,0);
    lcd.print("MHz");
  }
  else if(t == 2)
  {
    lcd.setCursor(4,0);
    lcd.print("SCAN         ");
  }

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

// output freq & A0 to monitor
void volts(long f, int in)
{  
  int n;

  Serial.print(f);
  n = in/FACTOR;
  while(n-- > 0)
  {
    Serial.print(" ");
  }
  Serial.println("X");
}

No comments: