Написать условие для выполнения 2 функций с переключателями?

Я новичок в программировании и использовании продуктов Arduino, и мне было интересно, не будет ли кто-нибудь не против помочь мне с проектом, которым я пытаюсь заняться?

Если вы просмотрите мой код ниже, у меня есть 3 условия в моем случае "простоя", и программа постоянно ищет любое из этих 3 условий. Если выполняется первое условие, то вызывается случай 1; если выполняется второе условие, то вызывается случай 2; если выполняется третье условие, то вызывается случай 3. Все 3 случая возвращаются к "простаивающему" случаю после завершения работы.

Что я хотел бы сделать, так это найти способ вставить случай "предупреждение", если выполнено какое-либо из условий, ПРЕЖДЕ чем переходить к случаю 1, случаю 2 или случаю 3, не записывая функции случая "предупреждение" каждый раз для каждого из остальных 3 случаев. По сути, поток будет выглядеть следующим образом:

условие 1 --> предупреждение -->> случай 1 -->>> случай простоя;>>>

условие 2 --> предупреждение -->> случай 2 -->>> случай простоя;>>>

условие 3 --> предупреждение -->> случай 3 -->>> случай простоя:>>>

void loop() {
  static byte theState = idle;
  switch (theState)
  {
    case idle:
      if (voltageA0 > 1.0) {
        theState = case1;
      }

      if (voltageA1 < 2.0) {
        theState = case2;
      }

      if (voltageA2 > 3.5) {
        theState = case3;
      }
      break;
    case warning:
      digitalWrite(7, HIGH);
      delay(5000);
      digitalWrite(7, LOW);
      delay(0);
      break;
    case 1:
      digitalWrite(8, HIGH);
      delay(2000);
      digitalWrite(8, LOW);
      delay(0);
      theState = idle;
      break;
    case 2:
      digitalWrite(9, HIGH);
      delay(2000);
      digitalWrite(9, LOW);
      delay(0);
      theState = idle;
      break;
    case 3:
      digitalWrite(10, HIGH);
      delay(2000);
      digitalWrite(10, LOW);
      delay(0);
      theState = idle;
      break;
  }
}

Кроме того, если есть более эффективный способ сделать это с помощью кода, я весь внимание!

, 👍2

Обсуждение

Упрощение кода перед его публикацией, как правило, хорошо. Но если вы измените его так сильно, что он станет в основном не связан с первоначальным, то правильный ответ на этот вопрос может быть неприменим к вашей реальной проблеме. Судя по вашим комментариям к ответу Look Alterno, это именно то, что произошло. Код _blocking_, который вы опубликовали, сильно отличается от неблокирующего кода, который вы используете. Пожалуйста, отредактируйте вопрос, чтобы он соответствовал вашей реальной проблеме. Это было бы более полезно, чем пытаться объяснить в комментариях степень различия кодов., @Edgar Bonet


2 ответа


0
case idle:
  if (voltageA0 > 1.0 || voltageA1 < 2.0 || voltageA2 > 3.5) {
     digitalWrite(7, HIGH);
     delay(5000);
     digitalWrite(7, LOW);
     delay(0);     

     if (voltageA0 > 1.0) {
        theState = case1;
        }

    if (voltageA1 < 2.0) {
       theState = case2;
       }

    if (voltageA2 > 3.5) {
       theState = case3;
       }
   }

Редактировать: Чтобы уточнить исходный ответ, я вставил код "предупреждение" и удалил "предупреждение о случае", так как очевидно, что это состояние больше не требуется.

,

Большое спасибо за вашу помощь, ребята! Полагаю, мне следовало бы объяснить, почему я использую конечный автомат для кода. Код, который я привел в качестве примера, опускает функции millis (), которые на самом деле есть в моем реальном коде. Я переписал пример без функций millis() просто на то, что я пытаюсь сделать, но случаи "предупреждение", "1", "2", и "3" все используют функции millis() для запуска светодиодов и реле. Извините, что не объяснил этого. Эдгар, спасибо, что указал на избыточность "delay(0);", которая у меня была... Я подумал, что это может быть излишним, но не был уверен. Исходя из того, что мне это нужно..., @Andrew

..вызовите другой набор функций после функции "предупреждение", специфичной для выполненного условия, я не верю, что предложенный вами пример сработает. Хотя я могу ошибаться, поэтому, пожалуйста, дайте мне знать, если я что-то пропустил :) Послушай, Альтерно, спасибо тебе и за помощь. Что-то еще, что я не объяснил, заключается в том, что состояние/функция "предупреждение" также исправляет условия, вызывая реле для отключения напряжения на некоторых устройствах. Последовательные случаи (1, 2, 3) просто используются в качестве индикатора, чтобы сказать мне, какое условие было только что выполнено, после того как состояние предупреждения устраняет проблему., @Andrew

Так что думайте об этом так... условие 1 вызовет предупреждающий случай, затем перейдите к случаю 1, где светодиод будет мигать 5 раз, указывая на то, что условие 1 только что было выполнено. условие 2 вызовет предупреждающий случай, затем перейдите к случаю 2, где светодиод будет мигать 10 раз, указывая на то, что условие 2 только что было выполнено. условие 3 вызовет предупреждающий случай, затем перейдите к случаю 3, где светодиод будет мигать 10 раз, указывая на то, что условие 3 только что было выполнено. Опять же, моя вина в том, что я не разработал все это изначально. Имеет ли это больше смысла?? Еще раз большое спасибо за помощь!, @Andrew

Спасибо! Но да, состояние предупреждения исправит любое из 3-х условий, поэтому проверка состояния ПОСЛЕ состояния предупреждения, к сожалению, не принесет никакой пользы. Лучший способ думать об этом-предположим, напряжение на выводе A0 увеличивается по мере того, как кастрюля с водой нагревается. Как только кастрюля с водой достигает определенной температуры (напряжения), функция "предупреждение" загорается светодиодом, скажем, на 10 минут, одновременно отключая источник тепла от кастрюли с водой. По истечении этих 10 минут корпус, связанный с условием (1, 2 или 3), будет мигать светодиодом определенное количество раз, указывая, какое условие было выполнено, @Andrew

Если температура воды падает ниже определенной температуры/напряжения, то срабатывает предупреждающий сигнал, а затем срабатывает сигнал 2, чтобы светодиод мигал разное количество раз, указывая на то, что сработало условие 2. Это не самые разумные примеры, но объяснить это проще, чем то, что и как я действительно контролирую входы на аналоговых выводах. Надеюсь, это имеет больше смысла, и еще раз спасибо!! :), @Andrew


1

В вашем коде есть что-то бессвязное. Он структурирован как конечный автомат, и все же вы используете в нем функцию delay (). В такого рода сценариях вся цель конечного автомата состоит в том, чтобы избежать использования delay(), так что ваша программа никогда не блокируется. Если вашей программе нечем заняться, кроме как откладывать, вы можете отказаться от конечного автомат и написать гораздо более простой код. Например:

void warn_and_flash(byte pin)
{
    // Flash the "warning" LED.
    digitalWrite(7, HIGH);
    delay(5000);
    digitalWrite(7, LOW);

    // Flash the requested LED.
    digitalWrite(pin, HIGH);
    delay(2000);
    digitalWrite(pin, LOW);
}

void loop()
{
    if (voltageA0 > 1.0) warn_and_flash(8);
    if (voltageA1 < 2.0) warn_and_flash(9);
    if (voltageA2 > 3.5) warn_and_flash(10);
}
,

Я согласен. Представьте, что вы пишете код для автомобиля, а водитель надевает левый индикатор, который должен мигать раз в секунду. Вы действительно хотите, чтобы автомобиль игнорировал другие входы (тормоза, акселератор, кондиционер) в течение целой секунды, в то время как вы "задерживаетесь" на одну секунду? Думаю, нет., @Nick Gammon