I am currently outputting a sine wave signal using a DDS module that I bought from Amazon. I downloaded a library to run the DDS module using Arduino uno. I want to measure max and min value coming off the DDS at two different frequency. How do I read the max and min in the loop? I get a single value Analog read which is not helpful.
#include <AD9850SPI.h>
#include <SPI.h>
const int W_CLK_PIN = 13;
const int FQ_UD_PIN = 8;
const int RESET_PIN = 9;
double freq = 10000000;
double trimFreq = 124999500;
int phase = 0;
void setup(){
DDS.begin(W_CLK_PIN, FQ_UD_PIN, RESET_PIN);
DDS.calibrate(trimFreq);
}
void loop(){
DDS.setfreq(freq, phase);
double num = analogRead(A0); // Measure max and min ?
DDS.setfreq(freq + 500, phase);
double num1 = analogRead(A0); // Measure max and min ?
DDS.down();
}
You should be able to do some extra setup then replace min/max values as needed, something like:
// To store/calc minima/maxima.
double minNum, maxNum, minNum1, maxNum1;
bool first = true;
void loop(){
DDS.setfreq(freq, phase);
double num = analogRead(A0);
DDS.setfreq(freq + 500, phase);
double num1 = analogRead(A0);
if (first) {
// First reading is min/max by definition.
minNum = maxNum = num;
minNum1 = maxNum1 = num1;
first = false;
} else {
// Otherwise set min/max based on comparisons.
if (num < minNum) minNum = num;
else if (num > maxNum) maxNum = num;
if (num1 < minNum1) minNum1 = num1;
else if (num1 > maxNum1) maxNum1 = num1;
}
// At this point, you have to (up-to-date) min/max for each variable,
// process it as you see fit.
DDS.down();
}
If you need to do a lot of samples at each frequency, that's a slightly modified version, which can be done with a state machine in the loop
function:
// Samples for each frequency and things for state machine.
#define SAMPLES 10000
#define ST_INIT 0
#define ST_FREQ_1 1
#define ST_FREQ_2 2
#define ST_DONE 3
double minNum, maxNum;
int samples, state = ST_INIT;
void loop () {
switch (state) {
case ST_INIT:
// Initial setup for state FREQ_1.
samples = SAMPLES;
DDS.setfreq(freq, phase);
minNum = maxNum = analogRead(A0);
state = ST_FREQ_1;
break;
case ST_FREQ_1:
// Collect samples until done, then output and set up for FREQ_2.
if (--samples < 1) {
process("Freq # 1", minNum, maxNum);
samples = SAMPLES;
DDS.setfreq(freq + 500, phase);
minNum = maxNum = analogRead(A0);
state = ST_FREQ_2;
} else {
double num = analogRead(A0);
if (num < minNum)
minNum = num;
else if (num > maxNum)
maxNum = num;
}
break;
}
case ST_FREQ_2:
// Collect samples until done, then output and stop.
if (--samples < 1) {
process("Freq # 2", minNum, maxNum);
DDS.down();
state = ST_DONE;
} else {
double num = analogRead(A0);
if (num < minNum)
minNum = num;
else if (num > maxNum)
maxNum = num;
}
break;
case ST_DONE:
default:
// Infinite looping with no action when all samples collected
// for both frequencies.
break;
}
}
You just need to add the process(const char *freq, double minVal, double maxVal)
function to output results.
For a more descriptive way of looking at that code, consider that the loop
function is simply called continuously by the Arduino processing loop, which is functionally:
int main() {
setup();
while (true) {
loop();
}
}
Also consider that those variable defined outside of loop
(and setup
) maintain their last-set values on subsequent calls to loop
.
So, the first time loop
is called, the state is ST_INIT
and it will execute that part of the switch
statement. That will:
ST_FREQ_1
; andSubsequent calls to loop
have the state ST_FREQ_1
so will execute the second part of the switch
. This:
ST_FREQ_2
.Exactly the same thing happens for sampling the second frequency except, at the end, we simply change the state to ST_DONE
, and don't have to set up anything for a third frequency ( so we shut down DDS).
The loop
function will continue to be called but, in the final state, it does nothing but return.