如何从 Arduino 中的 DDS 模块读取最大值和最小值?

How do I read the max and min value from DDS module in Arduino?

我目前正在使用从亚马逊购买的 DDS module 输出正弦波信号。 我使用 Arduino uno 下载了一个库到 运行 DDS 模块。我想测量两个不同频率下 DDS 的最大值和最小值。如何读取循环中的最大值和最小值?我得到一个没有帮助的单一值模拟读取。

#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();
}

您应该可以进行一些额外的设置,然后根据需要替换 min/max 值,例如:


// 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();
}

如果你需要在每个频率做很多采样,那是一个稍微修改的版本,可以用 loop 函数中的状态机来完成:


// 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;
    }
}

只需要添加process(const char *freq, double minVal, double maxVal)函数即可输出结果


为了以更具描述性的方式查看该代码,请考虑 Arduino 处理循环连续调用 loop 函数,其功能为:

int main() {
    setup();
    while (true) {
        loop();
    }
}

还要考虑那些在loop(和setup之外定义的变量在随后调用[=13=时保持它们最后设置的值].

因此,第一次调用 loop 时,状态为 ST_INIT,它将执行 switch 语句的那部分。那将:

  • 设置为使用第一个频率;
  • 将样本计数初始化为所需值;
  • 读取第一个值,将其分配给最小值和最大值;
  • 将状态更改为ST_FREQ_1;和
  • 中断,导致函数最终退出。

loop 的后续调用具有状态 ST_FREQ_1,因此将执行 switch 的第二部分。这个:

  • 减少样本计数。如果已达到零,则:
    • 输出第一组样本的结果;
    • 设置为使用第二个频率;
    • 将样本计数初始化为所需值;
    • 读取第一个值,将其分配给最小值和最大值;和
    • 将状态更改为 ST_FREQ_2
  • 如果它还没有达到零,它只是读取另一个样本并据此调整当前 min/max。
  • 无论哪种方式,它都会中断,导致函数最终退出。

对第二个频率进行采样时会发生完全相同的事情,只是最后我们只需将状态更改为ST_DONE,而不必为第三个频率设置任何东西(所以我们关闭下 DDS)。

loop 函数将继续被调用,但在最终状态下,它只执行 return。