Мой Arduino пропускает оператор?

Итак, я создал этот код (я довольно новичок в этом). Единственное, что должен делать Arduino, - это когда я нажимаю кнопку на выводе 2, включаю светодиод на выводе 4 и эмулирую CTRL + R на клавиатуре компьютера. Затем, если индикатор горит и я снова нажимаю кнопку, выключите его и нажмите пробел на моем компьютере. Но как только я нажимаю кнопку в первый раз, он действительно нажимает CTRL + R, и индикатор включается, но после задержки он сразу пропускает проверку, нажимаю ли я кнопку, и предполагает, что я нажимаю кнопку. Таким образом, он видит, что индикатор горит, и выключает его, нажимая клавишу пробела. Есть какие-нибудь предложения?

#include <Keyboard.h> int buttonPin = 2; int ledPin = 4; int val = 0; void setup() { // поместите свой установочный код здесь, чтобы запустить его один раз: pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT_PULLUP); Keyboard.begin(); } void loop() { val = digitalRead(buttonPin); // проверьте, нажата ли кнопка. Если это так, то состояние кнопки ВЫСОКОЕ: if ((val == LOW) && (digitalRead(ledPin) == LOW)) { // включите светодиод: digitalWrite(ledPin, HIGH); Keyboard.press(KEY_LEFT_CTRL); Keyboard.press('r'); delay(100); Keyboard.release(KEY_LEFT_CTRL); Keyboard.release('r'); delay(500); } if ((val == LOW) && (digitalRead(ledPin) == HIGH)) { digitalWrite(ledPin, LOW); Keyboard.write(32); } if ((val == HIGH) && (digitalRead(ledPin) == LOW)) { digitalWrite(ledPin, LOW); } if ((val == HIGH) && (digitalRead(ledPin) == HIGH)) { digitalWrite(ledPin, HIGH); } }

, 👍0

Обсуждение

подумайте о том, какова последовательность состояний кнопки, когда вы нажимаете кнопку дважды ... вы проверяете все штаты?, @jsotola

Вы объявили ledPin как выход, а затем в цикле проверяете его состояние с помощью digitalRead(ledPin). Это не сработает так, как вы намереваетесь сделать. Как контакт предназначен для источника тока, считывания собственного напряжения? Для этого вам нужен флаг, представляющий его состояние, а не электрическое состояние., @Daniel Melendrez


2 ответа


0

Ваш код не проверяет наличие кнопки. Он проверяет значение в val. Это обновляется только один раз за цикл. Допустим, код вводит первый оператор if, потому что значение val НИЗКОЕ, а индикатор также НИЗКИЙ. Это устанавливает светодиод на МАКСИМУМ. Теперь следующее утверждение if, val по-прежнему НИЗКОЕ, а теперь СВЕТОДИОД ВЫСОКИЙ, так что одно из них также верно.

Я думаю, что вы хотите использовать "еще, если", чтобы он пропустил остальное, как только найдет истинное.

void loop() {
  val = digitalRead(buttonPin);
  // проверьте, нажата ли кнопка. Если это так, то состояние кнопки HIGH:
  if ((val == LOW) && (digitalRead(ledPin) == LOW)) {
    // включите светодиод:
    digitalWrite(ledPin, HIGH);
    Keyboard.press(KEY_LEFT_CTRL);
    Keyboard.press('r');
    delay(100);
    Keyboard.release(KEY_LEFT_CTRL);
    Keyboard.release('r');
    delay(500);
  }
  else if ((val == LOW) && (digitalRead(ledPin) == HIGH)) {
    digitalWrite(ledPin, LOW);
    Keyboard.write(32);
  }
  else if ((val == HIGH) && (digitalRead(ledPin) == LOW)) {
    digitalWrite(ledPin, LOW);
  }
  else if ((val == HIGH) && (digitalRead(ledPin) == HIGH)) {
    digitalWrite(ledPin, HIGH);  
  }
}
,

Хм, если я попробую это сделать, светодиод останется твердым после первого нажатия, и он еще не попадет в мой пробел. Но когда я нажимаю кнопку во второй раз, она выполняет как CTRL + R, так и пробел, и светодиод остается сплошным. Я думаю, что мы на правильном пути, но все еще есть некоторые проблемы., @Hendriks3D

Ну, после действия в этом втором операторе if нет никакой задержки или чего-то еще, как в первом. Держу пари, что петля возвращается и видит, что кнопка все еще нажата, и снова ловит первое "если". Посмотрите на пример изменения состояния в IDE, чтобы узнать, как реагировать на изменение состояния кнопки, а не только на то, что она удерживается нажатой. Обнаружьте края. Реагируйте только один раз на нажатие., @Delta_G

Ты вывел меня на правильный путь. Теперь я использовал подсчет прессы. После этого его CTRL + R он устанавливает счетчик нажатия кнопки на 2, и если значение становится 3 (т. Е. Нажатие кнопки 2-го фактического времени), он нажимает пробел, выключает светодиод и устанавливает счетчик нажатия обратно на 0. Работает безупречно. Большое вам спасибо!, @Hendriks3D


1

Попробуйте что-нибудь в этом роде.

Код не использует состояния кнопок при принятии решений.

Вместо этого он ищет переход между состояниями кнопки, поэтому удержание кнопки не создает событий.

void loop() {

  val = digitalRead(buttonPin);

  if (val != oldButtonState) {      // button state transition
    oldButtonState = val;
    if (val == LOW) {               // transition from "released" to "pressed"
      buttonClicked = true;         // set click flag
    }
  }



  if ( buttonClicked ) {

    buttonClicked = false;                // clear click flag

    if (digitalRead(ledPin) == LOW) {
      digitalWrite(ledPin, HIGH);         // turn LED on
      Keyboard.press(KEY_LEFT_CTRL);      // send CTRL-R
      Keyboard.press('r');
      delay(100);
      Keyboard.release(KEY_LEFT_CTRL);
      Keyboard.release('r');
      delay(500);
    }

    else {
      digitalWrite(ledPin, LOW);          // turn LED off
      Keyboard.write(32);                 // send space
    }
  }
}
,