【问题标题】:Collecting from arduino pin for specific time interval从 arduino pin 收集特定时间间隔
【发布时间】:2013-06-28 22:21:23
【问题描述】:

我想运行我的 Arduino 一段特定的时间(比如 60 秒)并收集 来自具有特定采样率的模拟引脚的数据(例如每秒四个样本)。 我得到了在 matlab 中工作的代码......但我想使用 arduino 环境。 请帮我转换一下。

a_pin = 0;

fs = 4;   % sampling frequency (samplings per second)
mt = 20;  % time for measurements

ind = 1;
nind = 1;
last_beep = 0;
tic;
while toc < mt

    time(ind) = toc;
    v(ind) = a.analogRead(a_pin);

    % wait for appropriate time for next measurement
    while( nind == ind )
        nind = floor(toc*fs) + 1;
    end
    ind = nind;

end

好的,这就是我目前的草图。这个测量 10 秒可以吗 每 5 次读数?

int sensePin = 0;
unsigned long starttime = 0;
unsigned long endtime = 0;
int i = 0;
int n;
const int sizeofv = 50;
int v[sizeofv];

void setup(){
    pinMode(sensePin, INPUT);
    Serial.begin(9600);
}

void loop() {
    starttime = millis();
    endtime = starttime; 

    while ((endtime - starttime) <= 10000) // do this loop for up to 1000mS
    {
        i = i + 1;
        v[i] = analogRead(sensePin);
        endtime = millis();
        delay(5000);
    }  

    for(n=0; n < sizeofv; n++)
    {
        Serial.print(v[n]);
        Serial.print('\n');
    }
    while(1) { }
}

【问题讨论】:

  • 如果您尝试自己先转换它并在遇到困难时返回,这可能是最好的。从 arduino ide 附带的示例草图之一开始,并确保在 arduino.cc 上查看良好的语言参考
  • 好的,我分享了我目前所拥有的。不知道它是否在做我想做的事
  • 如果不运行它,我认为你所拥有的或多或少会起作用。几个小 cmets... 实际上,您可以在 setup() 函数中完成所有这些操作,并在最后省略 while(1) 循环。您还可以用 Serial.println() 替换您的第二个 Serial.print。为了帮助调试/测试代码,您可以在每次模拟读取之前添加一个 Serial.println 调试语句。然后检查您所期望的时间。
  • 还有一个......您应该在调用 delay() 后移动更新 endtime 的位置
  • 有没有一种快速的方法可以将我的数组“v”导出为 .mat 文件?

标签: loops time arduino sampling


【解决方案1】:

我推荐使用 SimpleTimer 库,它可以为您完成所有工作,并且经过验证。

【讨论】:

    【解决方案2】:
    • 您的代码中有一个错误,您在分配第一个值之前增加了i。因此,当您循环遍历 v[] 数组时,您最终会打印出具有未定义值的 v[0],并且您将永远不会打印最后记录的 v 值(如果您没有结束溢出缓冲区并写入其边界之外)。

    • 你的代码有一个小问题,就是你做了一个条件,你需要在 10000 结束它,然后你做了两次 5000 的延迟。理论上看起来没问题,但在实践中,你可能会得到一个惊喜只有一个值。那是因为代码执行需要时间,而analogRead() 特别慢。

    我认为在loop() 函数中使用循环会使事情变得更加复杂,并且几乎没有增加灵活性。所以在这里你可以尝试另一种方法,仅通过跟踪循环的状态来使用loop(),基于一些简单的计算:

    #define TIME_WINDOW 10000
    #define NB_STEPS 2
    
    void setup() {
        // ...
        endtime = millis();
    }
    
    bool over = false;
    void loop() {
        if (!over) {
            curtime = endtime - millis();
    
            // get in this block for up to 1000mS
            if (curtime <= TIME_WINDOW) {
                v[i] = analogRead(sensePin);
                // increments only once when 5000 has been reached.
                if ((curtime / (TIME_WINDOW/NB_STEPS)) != i)
                    i = (curtime / (TIME_WINDOW/NB_STEPS));
            } else {
                for(n=0; n < NB_STEPS; n++)
                    Serial.println(v[n]);
                over = true;
            }
        }
    }
    

    我没有测试我的代码,所以它可能会失败或有错别字,但想法如下:

    • 我们定义时间窗口和测量步骤数
    • 当时间窗口未结束时:
      • 将测量值存储在当前数组中的当前索引处
      • 如果 time_window 上所用时间的整数除法与当前索引不同
        • 将新值存储到当前索引中
        • 例如:i = 4000/(10000/2) &lt;=&gt; i = 4000/5000 &lt;=&gt; i = 0i = 6000/(10000/2) &lt;=&gt; i = 1
    • 时间窗口结束时:
      • 打印出每个结果
      • 设置为 true,因此我们不会再次进入循环

    但对您来说更简单(不灵活)的解决方案是:

    void setup() {
        int value1, value2, value3, value4;
        value1 = analogRead(sensePin);
        delay(2500);
        value2 = analogRead(sensePin);
        delay(2500);
        value3 = analogRead(sensePin);
        delay(2500);
        value4 = analogRead(sensePin);
        Serial.println("first value: %d", value1);
        Serial.println("second value: %d", value2);
        Serial.println("third value: %d", value3);
        Serial.println("fourth value: %d", value4);
    }
    

    你得到了你的解决方案!

    HTH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多