【问题标题】:Breaking a While loop C++打破 While 循环 C++
【发布时间】:2019-11-01 05:21:56
【问题描述】:

我有一个简单的问题,我认为更有经验的固件开发人员能够帮助我解决这个问题。所以我对这段代码的主要目标是:

  1. 运行一个循环(检测),该循环将“监听”发生的事情,然后在达到该阈值后增加一个变量(在本例中为伏特计数)。一旦在指定时间内达到 voltscount 两次,采样循环内的第一个 while 循环将更仔细地听(通过 FFT)。

  2. 当检测循环中的阈值在特定时间段内(本例中为 3 秒)未达到时,我想退出 while 循环(停止使用 FFT 侦听)。

数字 1 已实现,但数字 2 有问题。代码似乎保留在采样内部的第一个 while 循环中(串行窗口继续显示 FFT 值而不是 0,1 或 2 -voltscount 值)在 3 秒后,该电压阈值仍低于 4.8。

我没有包括我的 void 设置和所有爵士乐,请告诉我是否需要这样才能回答我的问题。

void loop(){
  detect();
  sampling();

}
void detect(){
   unsigned long startMillis= millis();  // Start of sample window

   unsigned int peakToPeak = 0;   // peak-to-peak level

   unsigned int signalMax = 0;
   unsigned int signalMin = 1024;

   // collect data for 50 mS
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(0);
      if (sample < 1024)  // toss out spurious readings
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save just the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save just the min levels
         }
      }
   }
   peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
   volts = (peakToPeak * 5.0) / 1024;  // convert to volts
 Serial.println(voltscount);
}

void sampling(){
unsigned long currentMillis = millis();

if(volts >=4.8){
  voltscount++;

  previousMillis = millis();
}
while(voltscount >= 2){
    /////SAMPLING
    for(int i=0; i<samples; i++)
    {
        microseconds = micros();    /* Overflows after around 70 minutes! */
        vReal[i] = analogRead(0);
        vImag[i] = 0;
        while(micros() < (microseconds + sampling_period_us)){
        }
    }
  double x;
  double v;
  FFT.MajorPeak(vReal, samples, samplingFrequency, &x, &v);
  Serial.print(x, 0);
  Serial.print(", ");
  Serial.println(v, 0);
  delay(10); /* Repeat after delay */ 
/* 
// 3 tests for smoke detector chirps and code to light up the LEDs

    if (x > 4000 and x < 4900 and v > 80) {
        digitalWrite(blueLEDpin, HIGH);
        digitalWrite(uvLEDpin, HIGH);
        delay(blueLEDdelay);
        digitalWrite(blueLEDpin, LOW);
        delay(uvLEDdelay);
        digitalWrite(uvLEDpin, LOW);
    }

    if (x > 1700 and x < 1800 and v > 40) {
        digitalWrite(blueLEDpin, HIGH);
        digitalWrite(uvLEDpin, HIGH);
        delay(blueLEDdelay);
        digitalWrite(blueLEDpin, LOW);
        delay(uvLEDdelay);
        digitalWrite(uvLEDpin, LOW);
    }
*/
    if (v > 1400) {
        digitalWrite(blueLEDpin, HIGH);
        digitalWrite(uvLEDpin, HIGH);
        delay(blueLEDdelay);
        digitalWrite(blueLEDpin, LOW);
        delay(uvLEDdelay);
        digitalWrite(uvLEDpin, LOW);
    }
  if (currentMillis - previousMillis > 3000){
  voltscount = 0;
  break;
  }

 }

}


【问题讨论】:

  • 好吧,如果您的意思是它在while(micros() &lt; (microseconds + sampling_period_us)) 循环中停留超过 3 秒,那么该条件成立超过 3 秒。 micros(), 是什么,以微秒为单位获取当前时间?您的代码未显示分配 sampling_period_us 的位置。看起来sampling_period_us 分配不正确。

标签: c++ while-loop arduino break


【解决方案1】:

假设 voltscount 为 1 的状态。您输入sampling()。您首先将当前工厂设置为当前时间。假设它是 1000(假设因为我不知道该函数返回什么)。然后,由于您的 volts 大于 4.8,您将 voltscount 增加到 2。并且您将 previousMillis 设置为 1500,因为第二次调用 millis()。然后你进入第一个 while 循环,在它的最后,你检查是否currentMillis - previousMillis &gt; 3000。但这从来都不是真的,因为previouslMillis 的价值大于currentMillis。我想你可以做的是在检查差异是否大于 3000 之前阅读currentmillis

if (millis() - previousMillis > 3000){
  voltscount = 0;
  break;
}

【讨论】:

  • 非常感谢。这就是解决方法。我不知道为什么我认为 currentMillis 会更新 millis() 会更新的所有内容。
【解决方案2】:

在 Arduino 编程中,大多数初学者的 while 循环都是错误的。 特别是,如果你觉得有必要以某种方式打破它们。 Arduino环境提供了loop()函数原型,大家应该好好使用。

通常,任何while() {...} 都可以替换为if() {...},在下一次loop() 运行中会再次调用该if() {...}。有时,您需要更多的状态变量,但重要的变化是遵循这样一种范式,即 loop() 不应该花费明显的时间来运行,也不应该通过在 loop() 中一个接一个地列出顺序动作来描述顺序动作。 基本的 BlinkWithoutDelay 示例适用于任何地方,不仅适用于闪烁。重要的部分不仅是调用millis(),而是将草图的状态保存在适当的变量中(比如那些previousmillis

【讨论】:

    猜你喜欢
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 2020-10-21
    • 2011-09-06
    • 2021-11-30
    • 2012-02-14
    • 2021-12-31
    相关资源
    最近更新 更多