Arduino-Kumod.php 30363 Bytes 02-04-2021 19:55:09
Arduino/Genuino Kumod
A versatile Dual DDS Synthesiser with the AD 9958
The assembled prototype
✈ Motivation
As the
Polarmod
worked nicely, we decided to create some kind of 'Spin-Off'. This Synthesiser can also be locked to a
10 MHz Reference, can be programmed via USB and offers many modes of operation.
It can serve as an I-Q-Source, a Two Tone generator, a Sweep Oscillator and can work in an IF-Offset Mode.
A website on calculating IP3 can be found
here .
"Ku" [in Thai :
คู่ ] is the classificator for a 'pair' (e.g. a pair of boots, a couple, ...).
✈ Block Diagam Kumod
Block Diagram of the Kumod - a nifty little device
This device (Version 1, picture below) uses a free running XCO which is multiplied by a factor of 10 by the
internal VCO/PLL of the AD9958. This allows for a Reference Clock of 500 MHz.
Version 3 (see placement, below) can be populated with any 7 x 5 mm crystal oscillator or with our
100 MHz Ref Clock Module .
Two internal Amplifier (GALI-51+, approx. 17 dB) boost the signal to + 10 dBm. In order to
achieve a much lower cut-off (as when using the standard TCBT-14) we use two inductors in series,
both damped with a resistor. Simulation (and measurement) show, that 1 MHz is by far not the end.
The upper limit is somewhere in the region of 200 MHz, depending on your demands for image
suppression. (An SCLF-190 lowpass-filter could be used here as well !)
Specifications :
FREQUENCY RANGE 1 MHz ... 200 MHz in 1 kHz steps (Software limited)
AMPLITUDE RANGE - 20 ... + 10 dBm in 0.1 dB steps
PHASE RANGE 0 ... 359.9° in 0.1° steps
REMOTE USB (Arduino), not isolated
SUPPLY + 7.5 V ... 9 V approx. 399 mA
Inside View of Version 1 - with a 50 MHz XCO
Simulation indicates a much lower cut-off
100 MHz, 0 dBm. SYNC_CLK visible @ 125 MHz
✈ Amplitude Setting
The Amplitude can be controlled manually by writing the amplitude scale factor directly.
For this action to be successful, you need to set ACR[12] = 1 and ACR[11] = 0.
We measured the overall (inclusive GALI-51+ Amplifier) Setpoint (ASF) versus Power characteristics :
Our spreadsheet program was so kind to deliver a function which approximates
the behaviour quite nicely. All which was left, was to solve for ASF (= Amplitude Scale Factor).
You'll find this in the code below, lines 242 and 255.
✈ Test Sketch for Arduino/Genuino Nano Every
Double click on code to select ...
/* //////////////////////////////////////////////////////////////////
ARDUINO/Genuino Project "KUMOD", an DDS SYNTHESISER AD9958
https://www.changpuak.ch/electronics/Arduino-Kumod.php
Software Version 1.0 - 02.04.2021 by ALEXANDER SSE FRANK,
on the auspicious occasion of
HRH Princess Maha Chakri Sirindhorn's Birthday
HELPFUL:
randomnerdtutorials.com/guide-for-oled-display-with-arduino/
////////////////////////////////////////////////////////////////// */
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
// DISPLAY
#define OLED_MOSI A2
#define OLED_CLK A3
#define OLED_DC A0
#define OLED_CS 13
#define OLED_RESET A1
// ROTARY ENCODER
const int RotaryEncoder1 = A7 ; // PRESSED
const int RotaryEncoder2 = 2 ;
const int RotaryEncoder3 = 3 ;
volatile boolean LEFT = false ;
volatile boolean RIGHT = false ;
volatile boolean READY = true ;
int PRESSCNT = 0 ;
// DDS VARIABLES
double FREQA = 100.0 ;
double FREQB = 120.0 ;
double PHASEA = 0.0 ;
double PHASEB = 199.0 ;
double AMPLA = 10.2 ;
double AMPLB = 10.2 ;
const double FREQ_MAX = 200.001 ;
const double FREQ_MIN = 0.999 ;
const double PHASE_MIN = 0.0 ;
const double PHASE_MAX = 359.9 ;
const double AMPL_MIN = -20.1 ;
const double AMPL_MAX = 10.1 ;
// {Fa, Fb, Aa, Ab, Pa, Pb} ;
int CPos[] = {4,4,3,3,3,3} ;
int MinCPos[] = {0,0,3,3,2,2} ;
int MaxCPos[] = {6,6,5,5,5,5} ;
int DotCPos[] = {3,3,4,4,4,4} ;
int MenuI = 0 ;
int MaxMenuI = 5 ;
const double REF = 500.000000 ;
Adafruit_SH1106 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
#if (SH1106_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SH1106.h!");
#endif
// /////////////////////////////////////////////////////////////
// Serial Communication Routines : EEPROM & DDS
// /////////////////////////////////////////////////////////////
#define EEPROM_24C01_I2CADDR 0x50
// Single-bit serial 2-wire mode
int DDS_RESET = 5 ; // Active High Reset Pin
int DDS_SYNCIO = 6 ;
int DDS_SDIO2 = 7 ;
int DDS_SDIO1 = 8 ;
int DDS_SDAT = 9 ;
int DDS_SCLK = 10 ;
int DDS_CS = 11 ;
int DDS_IO_UPDATE = 12 ;
// ///////////////////////////////////////
void ResetDDS()
// ///////////////////////////////////////
{
digitalWrite(DDS_RESET, HIGH) ;
delay(9) ;
digitalWrite(DDS_RESET, LOW) ;
delay(9) ;
}
// //////////////////////////////////////////////////////////
void Energy()
// //////////////////////////////////////////////////////////
{
digitalWrite(DDS_IO_UPDATE, HIGH) ;
delay(1) ;
digitalWrite(DDS_IO_UPDATE, LOW) ;
}
// //////////////////////////////////////////////////////////
void WriteDDS1(byte instruct,byte data)
// //////////////////////////////////////////////////////////
{
digitalWrite(DDS_CS, LOW) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, instruct ) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, data) ;
digitalWrite(DDS_CS, HIGH) ;
}
// //////////////////////////////////////////////////////////
void WriteDDS2(byte instruct,byte d1,byte d2)
// //////////////////////////////////////////////////////////
{
digitalWrite(DDS_CS, LOW) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, instruct ) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, d1) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, d2) ;
digitalWrite(DDS_CS, HIGH) ;
}
// //////////////////////////////////////////////////////////
void WriteDDS3(byte instruct,byte d1,byte d2,byte d3)
// //////////////////////////////////////////////////////////
{
digitalWrite(DDS_CS, LOW) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, instruct ) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, d1) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, d2) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, d3) ;
digitalWrite(DDS_CS, HIGH) ;
}
// //////////////////////////////////////////////////////////
void WriteDDS4(byte instruct,byte d1,byte d2,byte d3,byte d4)
// //////////////////////////////////////////////////////////
{
digitalWrite(DDS_CS, LOW) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, instruct ) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, d1) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, d2) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, d3) ;
shiftOut(DDS_SDAT, DDS_SCLK, MSBFIRST, d4) ;
digitalWrite(DDS_CS, HIGH) ;
}
// //////////////////////////////////////////////////////////
void UpdateFTW()
// //////////////////////////////////////////////////////////
{
// DATASHEET PAGE 18
// fout = FTW * fs / 2^32
// fs / 2^32 is constant. = 0.000000116415321826934814453125
// 2^32 / fs is constant. = 8’589’934.592
// ///////////////////////////////////////////////////////
// CHANNEL 0
// ///////////////////////////////////////////////////////
unsigned long FTW = (unsigned long)(FREQA * 8589934.592 ) ;
int Byte1 = (0xFF000000 & FTW) >> 24 ;
int Byte2 = (0x00FF0000 & FTW) >> 16 ;
int Byte3 = (0x0000FF00 & FTW) >> 8 ;
int Byte4 = (0x000000FF & FTW) ;
WriteDDS1(0x00, 0x70) ;
WriteDDS4(0x04, Byte1, Byte2, Byte3, Byte4) ;
Energy() ;
// ///////////////////////////////////////////////////////
// CHANNEL 1
// ///////////////////////////////////////////////////////
FTW = (unsigned long)(FREQB * 8589934.592 ) ;
Byte1 = (0xFF000000 & FTW) >> 24 ;
Byte2 = (0x00FF0000 & FTW) >> 16 ;
Byte3 = (0x0000FF00 & FTW) >> 8 ;
Byte4 = (0x000000FF & FTW) ;
WriteDDS1(0x00, 0xB0) ;
WriteDDS4(0x04, Byte1, Byte2, Byte3, Byte4) ;
Energy() ;
}
// //////////////////////////////////////////////////////////
void UpdatePTW()
// //////////////////////////////////////////////////////////
{
// CHANNEL 0 : CSR = 0x70
// CHANNEL 1 : CSR = 0xB0
// DATASHEET PAGE 18
// pout = POW * 360 / 2^14
// POW = pout * 2^14 / 360
// 360 / 2^14 is constant. = 0.02197265625
// 2^14 / 360 is constant. = 16384 / 360 = 45.511111111
// ///////////////////////////////////////////////////////
// CHANNEL 0
// ///////////////////////////////////////////////////////
int POW = (int)( PHASEA * 45.51111111111111 ) ;
int EMSB = (POW & 0x3F00) >> 8 ;
int ELSB = (POW & 0x00FF) ;
WriteDDS1(0x00, 0x70) ;
WriteDDS2(0x05, EMSB, ELSB) ;
Energy() ;
// ///////////////////////////////////////////////////////
// CHANNEL 1
// ///////////////////////////////////////////////////////
POW = (int)( PHASEB * 45.51111111111111 ) ;
EMSB = (POW & 0x3F00) >> 8 ;
ELSB = (POW & 0x00FF) ;
WriteDDS1(0x00, 0xB0) ;
WriteDDS2(0x05, EMSB, ELSB) ;
Energy() ;
}
// //////////////////////////////////////////////////////////
void UpdateASF()
// //////////////////////////////////////////////////////////
// Manual mode allows the user to directly control the output
// amplitude by manually writing to the amplitude scale factor
// value in the ACR (Register 0x06). Manual mode is enabled
// by setting ACR[12] = 1 and ACR[11] = 0. Line 247, 261
{
// CHANNEL 0 : CSR = 0x70
// CHANNEL 1 : CSR = 0xB0
// AMAX 2^10 - 1 = 1023 approx. 10.23 dBm
// AMIN = 100 ;
// ///////////////////////////////////////////////////////
// CHANNEL 0
// ///////////////////////////////////////////////////////
unsigned int ASF = pow(2.71828182846, (( AMPLA + 50.062 )/8.712)) ;
// Serial.print("ASF #A : ");
// Serial.println(ASF,DEC);
int ONE = 0x00 ;
int TWO = (ASF & 0x000300) >> 8 ;
TWO |= 0x14 ;
int TRI = (ASF & 0x0000FF) ;
WriteDDS1(0x00, 0x70) ;
WriteDDS3(0x06, ONE, TWO, TRI) ;
Energy() ;
// ///////////////////////////////////////////////////////
// CHANNEL 1
// ///////////////////////////////////////////////////////
ASF = pow(2.71828182846, (( AMPLB + 50.062 )/8.712)) ;
// Serial.print("ASF #B : ");
// Serial.println(ASF,DEC);
// Serial.println("------------------");
ONE = 0x00 ;
TWO = (ASF & 0x000300) >> 8 ;
TWO |= 0x14 ;
TRI = (ASF & 0x0000FF) ;
WriteDDS1(0x00, 0xB0) ;
WriteDDS3(0x06, ONE, TWO, TRI) ;
Energy() ;
}
// /////////////////////////////////////////////////////////////
// ANALOG INPUTS
// /////////////////////////////////////////////////////////////
double SUPPLY = 0.0 ;
int SUPPLY_ARD_PIN = A6 ;
void UpDateSupplyVoltage()
{
SUPPLY = map(analogRead(SUPPLY_ARD_PIN),0,1023,0,2048)/100.0 ;
}
// /////////////////////////////////////////////////////////////
// SUBROUTINES DISPLAY.
// /////////////////////////////////////////////////////////////
void UpdateDisplay()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0); display.print("****");
display.setCursor(48,0); display.print("KUMOD");
display.setCursor(104,0); display.print("****");
display.drawLine(0, 12, 128, 12, WHITE);
// --------------------------------------------
// FREQUENCY CHANNEL A + CHANNEL B
// --------------------------------------------
if((MenuI == 0) || (MenuI == 1))
{
display.setTextSize(2) ;
display.setCursor(0, 21);
if (FREQA < 100.000) display.print(" ");
if (FREQA < 10.000) display.print(" ");
display.print(FREQA,3);
display.setCursor(90, 21); display.print("MHz");
// --------------------------------------------
display.setCursor(0, 45);
if (FREQB < 100.000) display.print(" ");
if (FREQB < 10.000) display.print(" ");
display.print(FREQB,3);
display.setCursor(90, 45); display.print("MHz");
}
// --------------------------------------------
// AMPLITUDE CHANNEL A + CHANNEL B
// --------------------------------------------
if((MenuI == 2) || (MenuI == 3))
{
display.setTextSize(2) ;
display.setCursor(0, 21);
display.print(" ");
if ((AMPLA < 9.99) && (AMPLA > -9.99)) display.print(" ");
if (AMPLA == 0.000) display.print(" ");
if (AMPLA > 0.000) display.print("+");
display.print(AMPLA,1);
display.setCursor(90, 21); display.print("dBm");
// --------------------------------------------
display.setCursor(0, 45);
display.print(" ");
if ((AMPLB < 9.99) && (AMPLB > -9.99)) display.print(" ");
if (AMPLB == 0.000) display.print(" ");
if (AMPLB > 0.000) display.print("+");
display.print(AMPLB,1);
display.setCursor(90, 45); display.print("dBm");
}
// --------------------------------------------
// PHASE CHANNEL A + CHANNEL B
// --------------------------------------------
if((MenuI == 4) || (MenuI == 5))
{
display.setTextSize(2) ;
display.setCursor(0, 21);
display.print(" ");
if (PHASEA < 100.000) display.print(" ");
if (PHASEA < 10.000) display.print(" ");
display.print(PHASEA,1);
display.setCursor(90, 21); display.print("Deg");
// --------------------------------------------
display.setCursor(0, 45);
display.print(" ");
if (PHASEB < 100.000) display.print(" ");
if (PHASEB < 10.000) display.print(" ");
display.print(PHASEB,1);
display.setCursor(90, 45); display.print("Deg");
}
// CURSOR VERTICAL
if(MenuI == 0) display.setCursor(0, 25) ; // FREQ A
if(MenuI == 1) display.setCursor(0, 49) ; // FREQ B
if(MenuI == 2) display.setCursor(0, 25) ; // AMPL A
if(MenuI == 3) display.setCursor(0, 49) ; // AMPL B
if(MenuI == 4) display.setCursor(0, 25) ; // PHASE A
if(MenuI == 5) display.setCursor(0, 49) ; // PHASE B
// CURSOR HORIZONTAL
if(CPos[MenuI] == 0) display.print("");
if(CPos[MenuI] == 1) display.print(" ");
if(CPos[MenuI] == 2) display.print(" ");
if(CPos[MenuI] == 3) display.print(" ");
if(CPos[MenuI] == 4) display.print(" ");
if(CPos[MenuI] == 5) display.print(" ");
if(CPos[MenuI] == 6) display.print(" ");
display.print("_");
display.display();
}
// /////////////////////////////////////////////////////////////
// S E T U P
// /////////////////////////////////////////////////////////////
void setup()
{
Serial.begin(115200) ;
Wire.begin() ;
// INIT OLED
display.begin(SH1106_SWITCHCAPVCC);
// SHOW STARTUP SCREEN
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0); display.print("****");
display.setCursor(48,0); display.print("KUMOD");
display.setCursor(104,0); display.print("****");
display.drawLine(0, 12, 128, 12, WHITE);
display.setTextSize(1);
display.setCursor(0, 21);
display.println("A DUAL DDS GENERATOR");
display.setCursor(0, 33);
display.println("WITH THE AD9958. ");
display.setCursor(0, 45);
display.println("(C) ETH QUANTUMOPTICS");
display.setCursor(0, 57);
display.println("BUILT 02.04.2021");
display.display();
delay(999) ;
pinMode(RotaryEncoder1, INPUT_PULLUP);
pinMode(RotaryEncoder2, INPUT_PULLUP);
pinMode(RotaryEncoder3, INPUT_PULLUP);
// YELLOW
attachInterrupt(digitalPinToInterrupt(RotaryEncoder2),
RotaryEncoderISR2, FALLING);
// GREEN
attachInterrupt(digitalPinToInterrupt(RotaryEncoder3),
RotaryEncoderISR3, FALLING);
delay(1999);
pinMode(DDS_RESET, OUTPUT) ;
pinMode(DDS_SYNCIO, OUTPUT) ;
digitalWrite(DDS_SYNCIO, LOW) ;
pinMode(DDS_SDIO2, INPUT) ;
pinMode(DDS_SDIO1, INPUT) ;
pinMode(DDS_SDAT, OUTPUT) ;
pinMode(DDS_SCLK, OUTPUT) ;
pinMode(DDS_CS, OUTPUT) ;
digitalWrite(DDS_CS, HIGH) ;
pinMode(DDS_IO_UPDATE, OUTPUT) ;
digitalWrite(DDS_IO_UPDATE, LOW) ;
// INIT DDS
ResetDDS() ;
// Channel Select Register (CSR) (0x00) = BOTH
WriteDDS1(0x00, 0xF0) ;
// Function Register 1 (FR1) (0x01)
WriteDDS3(0x01, 0xA8, 0x00, 0x00) ;
// Function Register 2 (FR2) (0x02)
WriteDDS2(0x02, 0x00, 0x00) ;
// Channel Function Register (CFR) (0x03)
WriteDDS3(0x03, 0x00, 0x03, 0x00) ;
// Channel Frequency Tuning Word (CFTW0) (0x04)
UpdateFTW() ;
// PHASE TUNING WORD (0x05) ... OMITTED
// Amplitude Control Register (ACR) (0x06)
// MANUAL CONTROL, PAGE 28
WriteDDS3(0x06, 0x00, 0x17, 0xFF) ;
Energy() ;
UpdatePTW() ;
// CHECK SUPPLY
UpDateSupplyVoltage() ;
Serial.print("Supply : ") ;
Serial.print(SUPPLY,2);
Serial.println(" Volts");
}
// /////////////////////////////////////////////////////////////
// M A I N L O O P
// /////////////////////////////////////////////////////////////
void loop()
{
// KEY ROTATED ?
// //////////////////////////////////
if(LEFT)
// //////////////////////////////////
{
switch (MenuI)
{
case 0:
// FREQUENCY A -
switch (CPos[0])
{
case 0:
FREQA -= 100.0 ;
if(FREQA < FREQ_MIN) FREQA += 100.0 ; // UNDO :-)
break; // ---------------
case 1:
FREQA -= 10.0 ;
if(FREQA < FREQ_MIN) FREQA += 10.0 ;
break; // ---------------
case 2:
FREQA -= 1.0 ;
if(FREQA < FREQ_MIN) FREQA += 1.0 ;
break; // ---------------
case 4:
FREQA -= 0.1 ;
if(FREQA < FREQ_MIN) FREQA += 0.1 ;
break; // ---------------
case 5:
FREQA -= 0.01 ;
if(FREQA < FREQ_MIN) FREQA += 0.01 ;
break; // ---------------
case 6:
FREQA -= 0.001 ;
if(FREQA < FREQ_MIN) FREQA += 0.001 ;
break; // ---------------
}
break ;
case 1:
// FREQUENCY B -
switch (CPos[1])
{
case 0:
FREQB -= 100.0 ;
if(FREQB < FREQ_MIN) FREQB += 100.0 ; // UNDO :-)
break; // ---------------
case 1:
FREQB -= 10.0 ;
if(FREQB < FREQ_MIN) FREQB += 10.0 ;
break; // ---------------
case 2:
FREQB -= 1.0 ;
if(FREQB < FREQ_MIN) FREQB += 1.0 ;
break; // ---------------
case 4:
FREQB -= 0.1 ;
if(FREQB < FREQ_MIN) FREQB += 0.1 ;
break; // ---------------
case 5:
FREQB -= 0.01 ;
if(FREQB < FREQ_MIN) FREQB += 0.01 ;
break; // ---------------
case 6:
FREQB -= 0.001 ;
if(FREQB < FREQ_MIN) FREQB += 0.001 ;
break; // ---------------
}
break;
// ----------------------------
case 2:
// AMPLITUDE A -
switch (CPos[2])
{
case 3:
AMPLA -= 1.0 ;
if(AMPLA < AMPL_MIN) AMPLA += 1.0 ; // UNDO :-)
break; // ---------------
case 5:
AMPLA -= 0.1 ;
if(AMPLA < AMPL_MIN) AMPLA += 0.1 ;
break; // ---------------
}
break;
// ----------------------------
case 3:
// AMPLITUDE B -
switch (CPos[3])
{
case 3:
AMPLB -= 1.0 ;
if(AMPLB < AMPL_MIN) AMPLB += 1.0 ; // UNDO :-)
break; // ---------------
case 5:
AMPLB -= 0.1 ;
if(AMPLB < AMPL_MIN) AMPLB += 0.1 ;
break; // ---------------
}
break;
// ----------------------------
case 4:
// PHASE A -
break;
// ----------------------------
case 5:
// PHASE B -
break;
}
UpdateFTW() ;
UpdatePTW() ;
UpdateASF() ;
READY = true ;
LEFT = false ;
RIGHT = false ;
}
// //////////////////////////////////
if(RIGHT)
// //////////////////////////////////
{
switch (MenuI)
{
case 0:
// FREQUENCY A +
switch (CPos[0])
{
case 0:
FREQA += 100.0 ;
if(FREQA > FREQ_MAX) FREQA -= 100.0 ; // UNDO :-)
break; // ---------------
case 1:
FREQA += 10.0 ;
if(FREQA > FREQ_MAX) FREQA -= 10.0 ;
break; // ---------------
case 2:
FREQA += 1.0 ;
if(FREQA > FREQ_MAX) FREQA -= 1.0 ;
break; // ---------------
case 4:
FREQA += 0.1 ;
if(FREQA > FREQ_MAX) FREQA -= 0.1 ;
break; // ---------------
case 5:
FREQA += 0.01 ;
if(FREQA > FREQ_MAX) FREQA -= 0.01 ;
break; // ---------------
case 6:
FREQA += 0.001 ;
if(FREQA > FREQ_MAX) FREQA -= 0.001 ;
break; // ---------------
}
break ;
case 1:
// FREQUENCY B +
switch (CPos[1])
{
case 0:
FREQB += 100.0 ;
if(FREQB > FREQ_MAX) FREQB -= 100.0 ; // UNDO :-)
break; // ---------------
case 1:
FREQB += 10.0 ;
if(FREQB > FREQ_MAX) FREQB -= 10.0 ;
break; // ---------------
case 2:
FREQB += 1.0 ;
if(FREQB > FREQ_MAX) FREQB -= 1.0 ;
break; // ---------------
case 4:
FREQB += 0.1 ;
if(FREQB > FREQ_MAX) FREQB -= 0.1 ;
break; // ---------------
case 5:
FREQB += 0.01 ;
if(FREQB > FREQ_MAX) FREQB -= 0.01 ;
break; // ---------------
case 6:
FREQB += 0.001 ;
if(FREQB > FREQ_MAX) FREQB -= 0.001 ;
break; // ---------------
}
break;
// ----------------------------
case 2:
// AMPLITUDE A +
switch (CPos[2])
{
case 3:
AMPLA += 1.0 ;
if(AMPLA > AMPL_MAX) AMPLA -= 1.0 ; // UNDO :-)
break; // ---------------
case 5:
AMPLA += 0.1 ;
if(AMPLA > AMPL_MAX) AMPLA -= 0.1 ;
break; // ---------------
}
break;
// ----------------------------
case 3:
// AMPLITUDE B +
switch (CPos[3])
{
case 3:
AMPLB += 1.0 ;
if(AMPLB > AMPL_MAX) AMPLB -= 1.0 ; // UNDO :-)
break; // ---------------
case 5:
AMPLB += 0.1 ;
if(AMPLB > AMPL_MAX) AMPLB -= 0.1 ;
break; // ---------------
}
break;
// ----------------------------
case 4:
// PHASE A +
break;
// ----------------------------
case 5:
// PHASE B +
break;
}
UpdateFTW() ;
UpdatePTW() ;
UpdateASF() ;
READY = true ;
LEFT = false ;
RIGHT = false ;
}
// //////////////////////////////////
// KEY PRESSED ?
// //////////////////////////////////
if(digitalRead(RotaryEncoder1) == LOW) PRESSCNT += 1 ;
UpdateDisplay() ; // 50 ms
delay(149) ;
// WAIT FOR KEY RELEASED
if(digitalRead(RotaryEncoder1) == HIGH)
{
// THAT WAS A SHORT ONE : ADVANCE CURSOR
if((PRESSCNT > 0) && (PRESSCNT < 3))
{
CPos[MenuI] += 1 ;
if(CPos[MenuI] == DotCPos[MenuI]) CPos[MenuI] += 1 ;
if(CPos[MenuI] > MaxCPos[MenuI]) CPos[MenuI] = MinCPos[MenuI];
PRESSCNT = 0 ;
}
// THAT WAS A LONG ONE : CHANGE MENUE ITEM
if(PRESSCNT > 3)
{
MenuI += 1 ;
if(MenuI > MaxMenuI) MenuI = 0 ;
PRESSCNT = 0 ;
}
}
}
// /////////////////////////////////////////////////////////////
// INTERRUPT SERVICE ROUTINES
// /////////////////////////////////////////////////////////////
void RotaryEncoderISR2()
{
// YELLOW
if(READY)
{
LEFT = false ;
RIGHT = false ;
byte autre = digitalRead(RotaryEncoder3) ;
if (autre > 0) RIGHT = true ;
if (autre < 1) LEFT = true ;
}
}
void RotaryEncoderISR3()
{
// GREEN
if(READY)
{
LEFT = false ;
RIGHT = false ;
byte autre = digitalRead(RotaryEncoder2) ;
if (autre > 0) LEFT = true ;
if (autre < 1) RIGHT = true ;
}
}
// /////////////////////////////////////////////////////////////
// END OF FILE.
// /////////////////////////////////////////////////////////////
✈ Downloads
✈ Output Spectrum
As with digital systems, there is a lot of spurious garbage visible.
Read more
here .
Output Spectrum, two tones added up with a ADP-2-1 from MiniCircuits.
Care must be taken, that no spurious signals are there, where the intermodulation products
are to be expected (when measuring IP3).
✈ Share your thoughts
The webmaster does not read these comments regularely. Urgent questions should be send via email.
Ads or links to completely uncorrelated things will be removed.