Приостановка выполнения программы с помощью кнопки

У меня есть программа, которая бесконечно мигает тремя светодиодами подряд. Как запрограммировать кнопку для приостановки программы в середине кода?

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

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

Вот мой код на данный момент (извините, он не очень чистый):

int ledpins[]   = {4, 5, 6};
int buttonpin   = 3;
int buttonstate = 0;

void setup() {
  Serial.begin(9600);

  for (int pin = 6; pin > 3; pin--) {
    pinMode(ledpins[pin], OUTPUT);
  }
  pinMode(buttonpin, INPUT);
}

void loop() {
  buttonstate = digitalRead(buttonpin);
  if (buttonstate == HIGH) {
    digitalWrite(ledpins, HIGH);
  }
  if (buttonstate == LOW) {
    for (int pin = 4; pin < 7; pin++) {
      digitalWrite(pin, HIGH);
      delay(200);
      digitalWrite(pin, LOW);
    }
    for (int pin = 6; pin > 3; pin--) {
      digitalWrite(pin, HIGH);
      delay(200);
      digitalWrite(pin, LOW);
    }
  }
}

, 👍0

Обсуждение

Взгляните на фильм «Моргай без промедления»., @tttapa

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

1) В setup() вы обращаетесь к ledpins[6], что выходит за пределы диапазона. 2) В loop() digitalWrite(ledpins, HIGH) не имеет смысла, так как ledpins не является целым числом., @Edgar Bonet


3 ответа


-1

Думаю, можно использовать прерывание для кнопки. В обработчике можно задать переменную состояния, например, buttonPressed.

В обработчике это может выглядеть так:

....
if(buttonPressed != true){
buttonPressed = true;   //Это только в первый раз
}
else if(buttonPressed){
buttonPressed = false; //Удалить первый флаг
speedTime = xxx;       //Это только для второго нажатия
}
....

В цикле это может выглядеть так (вы можете установить его в начале или в конце кода):

....

while(buttonPressed){
// Ничего не делать (приостановить программу)
}

....

Перед настройкой запишите это и замените 200 в цикле на speedTime:

....
int speedTime = 200;
....

Чтобы приостановить выполнение кода, вам нужно дождаться момента, когда вы достигнете точки while(buttonPressed). Например, вверху или внизу. Повторное нажатие до достижения этой точки изменит только время.

Если вы не хотите ждать какое-то время для паузы, то замените эту функцию delay(200) на что-то лучшее.

,

Поскольку вам всё равно приходится ждать начала цикла, чтобы проверить эту переменную, как именно это меняет ситуацию? Вы по-прежнему находитесь в той же ситуации: вам приходится ждать, чтобы отреагировать на нажатие кнопки, и к тому же у вас есть дополнительные накладные расходы на прерывание., @Delta_G


-1

Я бы просто использовал прерывание от контакта, и при нажатии кнопки процедура прерывания устанавливает флаг (т.е. flag=1). Затем в вашем цикле просто добавьте оператор, который вызывает функцию, которая представляет собой цикл while, ожидающий, пока переменная flag снова не станет равной 0. Функция прерывания просто переключает переменную flag каждый раз при нажатии кнопки. Таким образом, при первом нажатии кнопки программа зацикливается, а при втором — выполнение программы возвращается к циклу loop().

,

1

Проблема в этом коде заключается в том, что циклы for блокируются с задержкой в 1,2 секунды, и только по её завершении код возвращается к проверке кнопки. Вместо этого следует использовать саму функцию цикла для управления циклом и метод синхронизации Blink Without Delay. Таким образом, выполнение функции цикла никогда не блокируется, и она может выполняться тысячи раз в секунду, не пропуская ни одного нажатия кнопок. Кроме того, таким образом вы сможете приостановить программу в любой момент, а не только каждые 1,2 секунды.

,