Разорвать цикл while C ++ - PullRequest
       38

Разорвать цикл while C ++

0 голосов
/ 01 ноября 2019

У меня быстрый вопрос, и я думаю, что более опытный разработчик прошивок сможет мне помочь. Таким образом, основная цель, которую я имею с этим кодом:

  1. Запустить цикл (обнаружить), который будет «прослушивать» что-то происходящее, а затем увеличивать переменную (в данном случае voltscount) один разэтот порог достигнут. После того, как вольт-счетчик будет дважды нажат в течение указанного времени, 1-й цикл while внутри цикла сэмплирования будет слушать более внимательно (через FFT).

  2. Я хочу затем выйти из цикла while (прекратить прослушивание с помощью БПФ), когда порог в цикле обнаружения не достигнут в определенный период времени (3 секунды в этомпример).

Номер 1 достигнут, но у меня проблемы с номером 2. Кажется, код остается в 1-м цикле while внутри выборки (в последовательном окне продолжает отображаться БПФ)значения вместо значения 0,1 или 2-вольтового счета) через 3 с после того порога вольт, оставшегося ниже 4,8.

Я не включил мои настройки пустоты и весь этот джаз, дайте мне знать, если это необходимо, чтобы ответить на мой вопрос.

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

 }

}


Ответы [ 2 ]

1 голос
/ 01 ноября 2019

Предположим, что состояние вольт-счетчика равно 1. Вы вводите sampling(). Сначала вы устанавливаете текущие мельницы на текущее время. Предположим, это 1000 (гипотетически, так как я не знаю, что возвращает эта функция). Затем, поскольку ваш volts больше 4,8, вы увеличиваете voltscount до 2. И вы устанавливаете previousMillis на что-то вроде 1500, потому что millis() вызывается во второй раз. Затем вы вводите первый цикл while и в конце его проверяете, если currentMillis - previousMillis > 3000. Но это никогда не так, поскольку previouslMillis имеют большее значение, чем currentMillis. Я думаю, что вы могли бы сделать, это прочитать currentmillis прямо перед проверкой, если разница больше 3000.

if (millis() - previousMillis > 3000){
  voltscount = 0;
  break;
}
0 голосов
/ 01 ноября 2019

В программировании Arduino большинство циклов while новичка просто неверны. Особенно, если вы чувствуете необходимость как-то их сломать. Среда Arduino предоставляет прототип функции loop (), который вы должны использовать правильно.

Как правило, любой while() {...} может быть заменен на if() {...}, который снова вызывается при следующем запуске loop (). Иногда вам нужно еще несколько переменных состояния, но важное изменение состоит в том, чтобы следовать парадигме, что loop () не должен занимать заметное время для запуска и не должен описывать последовательные действия, перечисляя их одну за другой в loop (). Базовый образец BlinkWithoutDelay применяется везде, не только для мигания. Важной частью является не только вызов millis(), но и сохранение состояния вашего эскиза в соответствующих переменных (например, previousmillis)

...