Как заставить переключатель работать до тех пор, пока не будет обнаружен другой последовательный вход?

Я пытаюсь создать контроллер светофора.
Контроллер имеет три режима:
Режим 1 - светофор работает КРАСНЫЙ-ЖЕЛТЫЙ-ЗЕЛЕНЫЙ-ЖЕЛТЫЙ и должен повторять
* (Другие режимы не обязательны, кроме знания того, что пользователь может выбрать режим.) *

Я хочу зациклить функцию режима до тех пор, пока не получу входной сигнал от последовательного монитора. Если ввод не обнаружен, следует продолжить работу в текущем режиме.
На данный момент я использую Serial.read() в начале функции основного цикла перед оператором переключения, чтобы выбрать режим. Однако для этого нужен ввод, но я хочу, чтобы случаи переключения выполнялись до тех пор, пока ввод не будет получен.

Вся помощь будет очень признательна.

, 👍1

Обсуждение

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

Покажите нам эскиз, который у вас есть на данный момент. Знаете ли вы, что такое конечный автомат? https://majko.co.uk/blog/finite-state-machine, @Jot


2 ответа


1

Используйте что-то вроде этого (это псевдокод, поэтому преобразуйте его в свой скетч):

enum EState { NORMAL, SPECIAL } _state; // Состояния
enum ENormalState { RED, YELLOW1, GREEN, YELLOW2 } _normalState; // Состояние действительно только тогда, когда _state == NORMAL
unsigned long _time; // _time действует только тогда, когда _state == NORMAL

void loop() 
{
   if ('serial input available')
   {
      if ('input == ...')
      {
         _state = NORMAL;
      }
      else if ('input == ...')
      {
         _state = SPECIAL;
      }
      ...
   }

   switch (_state)
   {
   case NORMAL:
       if (_time + ... > time())
       {
          // Переходим в следующее состояние
          switch (_normalState)
          {
          case RED:
              _normalState = YELLOW1;
              _time = time();
              break;

          case YELLOW1:
              _normalState = GREEN;
              _time = time();
              break;
          ...
          }

       setLight(_normalState); // Изменяем свет в соответствии с _normalState
       break;



   case SPECIAL:
       ...
       break;

   ...
   }
}

Идеи для улучшения/объяснения:

  • Попробуйте сделать какие-то конкретные функции для настройки света в соответствии с текущим состоянием.
  • Вам не нужна задержка.
  • Разделить функции (как указано выше, создать отдельные функции для нормального состояния и конкретного состояния).
,

1

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

while ((Serial.peek() == -1)){
          regularMode(ledRed, ledYellow, ledGreen);
}

Serial.peek() получает следующий элемент из последовательного стека. Если там ничего нет, он возвращает «-1», чтобы я мог проверить это, как показано выше.

,

Да, вам нужна неблокирующая операция, чтобы проверить, есть ли в потоке ожидающие символы. `peek()` верен, но [`Serial.available()`](https://www.arduino.cc/reference/en/language/functions/communication/serial/available /) больше связан с потоком., @caligari