【问题标题】:How do I read the max and min value from DDS module in Arduino?如何从 Arduino 中的 DDS 模块读取最大值和最小值?
【发布时间】:2021-06-02 16:16:46
【问题描述】:

我目前正在使用从亚马逊购买的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();
}

【问题讨论】:

    标签: max min arduino-uno


    【解决方案1】:

    您应该能够进行一些额外的设置,然后根据需要替换最小/最大值,例如:

    
    // 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) 函数即可输出结果。


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

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

    还要考虑在loop(和setup)的外部定义的那些变量在后续调用loop时保持其最后设置的值。

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

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

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

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

    对第二个频率进行采样的情况完全相同,只是最后我们只需将状态更改为ST_DONE,并且不必为第三个频率设置任何内容(因此我们关闭了 DDS)。

    loop 函数将继续被调用,但在最终状态下,它只会返回。

    【讨论】:

    • 老实说,我正忙着理解代码。
    • @Sam,我添加了更多描述,可能有助于您理解。
    猜你喜欢
    • 2022-01-21
    • 2019-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多