Как переключаться между циклами while до завершения текущего цикла? ИК-пульт + светодиод
У меня есть проект, который требует вращения протектора танка. Я смоделировал светодиоды, чтобы погаснуть во вращении с помощью ИК-пульта дистанционного управления. Я хочу остановить вращение по часовой стрелке на полпути, чтобы я мог немедленно вращаться против часовой стрелки.
К сожалению, мой код ждет, пока после полного вращения (или полного цикла while/if) не переместится в цикл вращения ccw. Как я закодирую это, чтобы сразу переключаться между циклами?
Вот мой код:
#include <IRremote.h>
int RECV_PIN = 10;
int Switch = 10;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
pinMode(2, OUTPUT);
pinMode(9, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
irrecv.enableIRIn(); // Запуск приемника
}
void loop()
{
if (irrecv.decode(&results))
{
Serial.println(results.value);
irrecv.resume(); // Получить следующее значение
}
while (results.value == 16615543) // кнопка 2: вращение по часовой стрелке
{
digitalWrite(2, HIGH);
delay(500); // Ожидание 500 миллисекунд(с)
digitalWrite(9, LOW);
delay(1000); // Ожидание 1000 миллисекунд(с)
digitalWrite(3, HIGH);
delay(500); // Ожидание 500 миллисекунд(с)
digitalWrite(2, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(4, HIGH);
delay(500); // Ожидание 500 миллисекунд(с)
digitalWrite(3, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(5, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(4, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(6, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(5, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(7, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(6, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(8, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(7, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(9, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(8, LOW);
delay(1000); // Wait for 1000 millisecond(s)
}
while (results.value == 16580863) //power button - break other loops and wait for next IR transmission
{
digitalWrite(2, LOW);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
}
while (results.value == 16619623) // button 8: ccw rotation
{
digitalWrite(9, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(2, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(8, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(9, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(7, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(8, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(6, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(7, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(5, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(6, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(4, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(5, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(3, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(4, LOW);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(2, HIGH);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(3, LOW);
delay(1000); // Wait for 1000 millisecond(s)
}
}
@Nick, 👍-1
Обсуждение2 ответа
Как мне закодировать это так, чтобы сразу переключаться между циклами?
А ты-нет. Вы снимаете петли. Вы не хотите их - они никогда не могут закончиться, так как нет никакого способа для изменения результатов между итерациями.
У вас есть фундаментальное непонимание того, как работают ИК-пульты. Не может быть никакого "в то время как", так как пульт дистанционного управления посылает сигнал либо один раз на нажатие кнопки, либо несколько раз, пока кнопка удерживается, в зависимости от функции, которую должна выполнять кнопка.
Вместо этого все, что вы можете сделать, это "Если кнопка нажата, то сделайте что-нибудь". Там нет "Он в настоящее время нажат" или "Он был выпущен", только "Я получил сигнал, что он нажат".
В дополнение к ответу Маенко, то, что вы должны использовать, - это так называемый State Engine.
Сначала вы определяете перечисление:
enum EState { Off, Clockwise, CounterClockwise };
EState _state;
В программе установки
вы устанавливаете _state
на некоторое значение по умолчанию.
В цикле
вы проверяете наличие изменений кнопок и соответствующим образом устанавливаете их состояние.
Затем вы действуете на состояние:
switch (_state)
{
case EState::Off:
{
// Выключить все
for (int n = 0; n < 9; n++)
{
digitalWrite(n, LOW);
}
}
break;
case EState::Clockwise:
... See below
case EState::CounterClockwise:
... Similar as above
}
Для состояний по часовой стрелке и против часовой стрелки вы должны сохранить переменную, которая увеличивается каждые 100 мс, сбрасывается при переходе в новое состояние.
В зависимости от значения шага вы что-то делаете, например, для первых двух шагов по часовой стрелке:
digitalWrite(2, HIGH);
delay(500); // Ожидание 500 миллисекунд
digitalWrite(9, LOW);
delay(1000); // Ожидание 1000 миллисекунд
вы можете сделать такой переключатель внутри корпуса, который у вас уже есть (или лучше: создать новую функцию):
switch (_step)
{
case 0: // 0 ms
digitalWrite(2, HIGH);
break;
case 5: // 500 ms
delay(1000);
...
Обратите внимание, что это немного более чисто для создания своего рода хэша/массива, но вышесказанное тоже должно работать. Вы можете увеличивать _step
каждые 100 мс или только тогда, когда активны состояния (против)часовой стрелки.
- Я пытаюсь совместить автоматический дверной замок с RFID MFRC522 с программой IR REMOTE.
- Как настроить пул DHCP для ESP-WIFI-MESH?
- Использовать irsend с тем, что является char* , но он этого не примет. Как преобразовать его в то, что ему нужно?
- RF Keyfob простой код кнопки
- Создание активного заднего крыла на радиоуправляемой машине
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
Что касается вашего скобочного комментария в исходном редактировании, то вам не хватало форматирования последовательности из трех обратных ссылок, чтобы процитировать код. Во время редактирования в правом верхнем углу есть встроенная справка с помощью значка (вопросительный знак с кружком). Я прогнал ваш код через автоформат и вручную свернул большую часть двойного интервала., @timemage