Если условие когда-либо выполняется, я хочу постоянно запускать цикл

Я пытаюсь запустить светодиод для подачи сигнала SOS азбукой Морзе, если температура превышает 20 C и обнаружено движение, но я хочу, чтобы он продолжал выполнять сигнал SOS даже после того, как движение исчезнет или температура снизится.

Сейчас он просто делает SOS 1 раз и останавливается.

(извините, если кодирование беспорядочное)

   int counter;
   int motion = 0;


   void setup()
  {

    {Serial.begin(9600);
     pinMode(4, INPUT);
     pinMode(0, OUTPUT);
     pinMode(2, OUTPUT);
     pinMode(1, INPUT);
     digitalWrite(0, HIGH);

     }
  }

    void loop()
   {

   int sensorA0Value = analogRead(A0);
   float voltage = sensorA0Value * (5.00 / 1023.00);
   Serial.print("Voltage: ");
   Serial.print(voltage);



   float temp = (voltage -.5)*100;
   Serial.print("| Temp: ");
   Serial.print(temp);
   Serial.println(" Celcius|");

   motion = digitalRead(4);

   if(motion == HIGH)
    {Serial.println("Motion Detected");}
   if(motion == LOW)
     {Serial.println("No Motion");}


   if(motion == HIGH && temp > 30) 
     {
     digitalWrite(2, HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(300);
     digitalWrite(2,HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(300);

     digitalWrite(2, HIGH);
     delay(600);
     digitalWrite(2, LOW);
     delay(600);
     digitalWrite(2, HIGH);
     delay(600);
     digitalWrite(2, LOW);
     delay(600);
     digitalWrite(2, HIGH);
     delay(600);
     digitalWrite(2, LOW);

     delay(600);
     digitalWrite(2, HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(300);
     digitalWrite(2,HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(300);
     digitalWrite(2,HIGH);
     delay(300);
     digitalWrite(2, LOW);
     delay(1000);

   }
     else {
     digitalWrite(2, LOW);

     }
   delay(1000);
    }

, 👍0


3 ответа


Лучший ответ:

0

Вы можете использовать цикл while следующим образом:

if(motion == HIGH && temp > 20) {
  while(true){
   SosMethod();
   }
}

чтобы все очистить, затем вне вашего void цикла() вы объявляете свой SOSMethod()

void loop() {
 ... .
 }

 void SosMethod(){
 your-led-code-with-delays 
 }
,

0

Кажется, это ваш SOS-код:

if(motion == HIGH && temp > 30) 
{
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);

 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);
 delay(600);
 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);
 delay(600);
 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);

 delay(600);
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(1000);
}

Шаг 1. Я думаю, вы хотите отправить первую S (.-.-.-.-) как 3 последовательности вместо 2, поэтому код:

if(motion == HIGH && temp > 30) 
{
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);

 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);
 delay(600);
 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);
 delay(600);
 digitalWrite(2, HIGH);
 delay(600);
 digitalWrite(2, LOW);

 delay(600);
 digitalWrite(2, HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(300);
 digitalWrite(2,HIGH);
 delay(300);
 digitalWrite(2, LOW);
 delay(1000);
}

Шаг 2. Уменьшите дублирующийся код (каждые 6 последовательностей цифровой записи и задержки), вы получите:

if(motion == HIGH && temp > 30) 
{
  send(300);
  send(600);
  send(300);
  delay(1000);
}

void send(int delayTime)
{
   for (length = 0; length < 3; length++)
   {
      digitalWrite(2, HIGH);
      delay(delayTime);
      digitalWrite(2, LOW);
      delay(600);
   }
}

Тогда вы хотите решить свою проблему, чтобы она продолжала отправляться Вместо

if(motion == HIGH && temp > 30) 
{
  send(300);
  send(600);
  send(300);
  delay(1000);
}

Использовать

while ((motion == HIGH) && (temp > 30))
{
  send(300);
  send(600);
  send(300);
  delay(1000);
}

Для удобства чтения я всегда использую круглые скобки вокруг условного оператора равенства (например, ==, >). Переменные motion и temp не будут изменены в цикле while, поэтому здесь можно использовать while. Предполагается, что переменные не изменяются во время прерывания.

,

В этом случае while (condition) действительно эквивалентно if (condition) while (true). Однако последнее ясно раскрывает намерения программиста, тогда как первое, скорее всего, вызовет путаницу., @Edgar Bonet


0

Это может быть не связано с реальным вопросом, но... ваше время Морзе полностью запутались. Стандартное время:

element         duration
------------------------
dot                 1
dash                3
interelement gap    1
intercharacter gap  3
interword gap       7

где единицей времени является длительность точки. Правильно рассчитанный сигнал SOS может быть реализовано следующим образом:

const uint32_t DOT_TIME = 150;  // 8 слов в минуту

void dot() {
    digitalWrite(2, HIGH);
    delay(1 * DOT_TIME);
    digitalWrite(2, LOW);
    delay(1 * DOT_TIME);
}

void dash() {
    digitalWrite(2, HIGH);
    delay(3 * DOT_TIME);
    digitalWrite(2, LOW);
    delay(1 * DOT_TIME);
}

void send_sos() {
    dot(); dot(); dot();
    dash(); dash(); dash();
    dot(); dot(); dot();
    delay(6 * DOT_TIME);  // пробел между словами
}

Обратите внимание, что в SOS нет пробелов между символами, поскольку это процедурный сигнал, передаваемый без границ букв. Это не слово из трех букв. Последняя задержка записывается как 6 * DOT_TIME, так как в конце уже есть одна задержка DOT_TIME. функция dot().

,