Синтаксис остановки цикла до тех пор, пока условие не станет ложным

Я считываю данные с датчика температуры и из этих данных. Мне нужно управлять тремя светодиодами. Давайте рассмотрим LED1, LED2, LED3.

If temperature range between 0-20
   I have to HIGH LED2.
   else if temperature range between 20-30 
I have to HIGH LED1; HIGH LED3; LOW LED1; 

мой набросок примерно такой:-

while(1)
{
if(temp>=0&&temp<=20)
{
digitalWrite(2,HIGH);
}
else if (temp>=20&&temp<=30)
{
digitalWrite(1,HIGH);
digitalWrite(3,HIGH);
digitalWrite(1,LOW);
}
}

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

, 👍0

Обсуждение

Не понимаю вашего «Я должен ВЫСОКИЙ LED1; ВЫСОКИЙ LED3; НИЗКИЙ LED1;» ? Что вы хотите для LED1?, @DataFiddler

Я хочу сначала включить LED1, затем включить LED2, затем выключить LED1., @anupam verma

когда условие2 выполнено, и остановите цикл, пока условие 2 не станет ложным, @anupam verma

Если температура ровно 20, какие светодиоды должны гореть/выключаться? Разве LED2 не должен быть где-то в этом утверждении: «У меня есть ВЫСОКИЙ LED1; ВЫСОКИЙ LED3; НИЗКИЙ LED1;»., @VE7JRO

да, извините, брат, я должен упомянуть LED3 вместо 2 ... как вы говорите, @anupam verma

позвольте мне еще раз объяснить, если температура находится в пределах 20-30, условие 2 будет выполнено как LED1 HIGH; LED3 ВЫСОКИЙ; LED1 НИЗКИЙ. после выполнения я должен остановить цикл до тех пор, пока условие 2 не станет ложным, т.е. температура превысит 30 или упадет ниже 20. при остановке цикла мы также должны постоянно снимать показания с датчика температуры –, @anupam verma

если светодиод должен быть выключен, то почему вы его не выключите?, @jsotola


2 ответа


2

Ваш код не имеет смысла. У вас есть оператор while (1), который будет выполняться вечно. Внутри тела этого оператора вы никогда не изменяете значение temp.

Функция loop() скетча Arduino работает непрерывно. У вас не должно быть цикла while (1) внутри вашей функции цикла. У вас должна быть примерно такая функция цикла:

void loop() {
  temp = //как-то прочитать временное значение
  if(temp>=0&&temp<=20)
  {
    digitalWrite(2,HIGH);
  }
  else if (temp>=20&&temp<=30)
  {
    digitalWrite(1,HIGH);
    digitalWrite(3,HIGH);
    digitalWrite(1,LOW);
  }
}   

С помощью этой функции цикла вы будете получать новое значение температуры при каждом проходе цикла, а затем решать, какие светодиоды загорятся.

,

Я отредактировал код, как вы сказали, но я столкнулся с проблемой, я должен остановить LED1, пока условие 2 не станет ложным ... но он постоянно включен, @anupam verma

Я должен остановить цикл, пока условие 2 не станет ложным, а также постоянно снимать показания температуры., @anupam verma

Это намного лучше, чем набросок исходного вопроса, но все же очень сомнительно: 2 никогда не будет НИЗКИМ, если оно было установлено ВЫСОКИМ; 3 никогда не станет НИЗКИМ, если он был установлен ВЫСОКИМ; 1 значительно тускнеет, если температура находится в диапазоне от 20 до 30 (затемнение зависит от времени, необходимого для считывания температуры), @DataFiddler

@DataFiddler Логика ОП неполна, и я не пытался решить эти проблемы. Я просто пытался объяснить, как писать код, который вызывается постоянно., @Duncan C

"Я должен остановить цикл..." Нет. Полная остановка. Не следует писать скетч, который замораживает цикл до тех пор, пока не наступит какое-то условие. Это очень плохая идея. Вам нужно придумать другой подход., @Duncan C


2

Вы не хотите останавливать цикл! Вы хотите, чтобы он работал быстро и часто.

В конце концов вы хотите, чтобы текущее состояние светодиода не менялось, но в вашем случае я не вижу достаточно определенных состояний светодиодов.

Я хочу сначала включить светодиод 1, затем включить светодиод 2, а затем выключить светодиод 1"

если then означает количество времени, помните, что цикл выполняется быстро и сам по себе не требует времени. Вам нужно будет отметить начальную точку во времени и сравнить ее с текущим временем и желаемыми интервалами. (И вы не упомянули, что должно произойти с LED2 после второго тогда )

const unsigned int LED1_DURATION=500;
const unsigned int LED3_DURATION=1000;
bool c2 = false;  // верно, пока выполняется условие2
unsigned long start2;  // время запуска условия2
void loop() {
  int temp = analogRead(A0); // как-то прочитать временное значение
  if(temp<=20)
  {
    digitlaWrite(1, LOW);
    digitalWrite(2,HIGH);
    digitlaWrite(3, LOW);
    c2 = false;
  }
  else if (temp >20 && temp <= 30)
  {
     digitalWrite(2, LOW);

     if (c2 == false) { c2 = true; start2=millis(); } // определить время начала

     if ((millis() - start2 < LED1_DURATION) ||
         (millis() - start2 > LED3_DURATION)   )
          digitalWrite(1,HIGH);
     else digitalWrite(1, LOW); 

     if ((millis() - start2 > LED1_DURATION) &&
         (millis() - start2 < LED3_DURATION)    )
          digitalWrite(3,HIGH);
     else digitalWrite(3,LOW);
  }
  else
  {
    digitlaWrite(1, LOW);
    digitalWrite(2, LOW);
    digitlaWrite(3, LOW);
    c2 = false;
  }
} 

Этот код содержит пару предположений о состояниях, которые вы не упомянули, и немного другое поведение (извините), но я надеюсь, что вы поняли...

,

Светодиод 2 должен быть выключен, если условие 1 не соответствует действительности..., @anupam verma

позвольте мне еще раз объяснить, если температура находится в пределах 20-30, условие 2 будет выполнено как LED1 HIGH; LED3 ВЫСОКИЙ; LED1 НИЗКИЙ. после выполнения я должен остановить цикл до тех пор, пока условие 2 не станет ложным, т.е. температура превысит 30 или упадет ниже 20. при остановке цикла мы также должны постоянно снимать показания с датчика температуры., @anupam verma

Извините, у меня ошибка в месте LED2, должно быть LED3, @anupam verma

«при остановке цикла мы также должны постоянно снимать показания с датчика температуры». Так что не называйте это _остановкой_. Вы просто находитесь в части «Условие2», но время превысило оба «тогда» и ваши светодиоды находятся в желаемом состоянии. ., @DataFiddler

я не понимаю, что ты сказал, @anupam verma

предположим, тогда будет задержка в 1 секунду, @anupam verma

см. мой добавленный пример кода с 2 * 500 мс, @DataFiddler

Arduino: 1.8.9 (Windows Store 1.8.21.0) (Windows 10), плата: «Arduino/Genuino Uno» C:\Users\ashwa\AppData\Local\Temp\cc3u0raS.ltrans0.ltrans.o: В функции main': C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino/main.cpp:43: неопределенная ссылка на setup' collect2.exe: ошибка: ld вернул 1 статус выхода статус выхода 1 Ошибка компиляции для платы Arduino/Genuino Uno. В этом отчете будет больше информации с "Показать подробный вывод во время компиляции" опция включена в Файл -> Настройки., @anupam verma

показывает ошибку, @anupam verma

Не пытайтесь копировать/вставлять код, опубликованный DataFiddler, и жаловаться, когда он выдает ошибки компиляции. Он предназначен для использования в качестве руководства, а не точного кода для вашей проблемы. Изучите подход, который они рекомендуют, а затем примените этот подход к своей проблеме. Идея состоит в том, что вы не «останавливаете цикл», вы используете комбинацию флагов для отслеживания состояния и таймеров для отслеживания возникновения событий. Затем вы пишете код, который проверяет текущее значение millis() при каждом проходе цикла, ожидая, пока пройдет желаемое количество времени., @Duncan C

я не получаю код datafiddler, @anupam verma

можно ли отправить компилятор обратно ..back в смысле отправки оператора 2-3 компилятора обратно, @anupam verma

1. В коде ответа отсутствует функция setup(), где нужно установить pinMode для выходных пинов. Вы должны быть в состоянии добавить это самостоятельно. 2. Вы должны знать и понимать основной принцип BlinkWithoutDelay, а также уметь применять этот принцип ко всему, что требует определенного количества времени, не «останавливая» loop(), @DataFiddler

Я не понимаю " _отправка оператора компилятора 2-3 назад_ ", @DataFiddler