Код для начинающих, цикл не обнаруживает отключенный контакт

Я учусь на плате Arduno UNO и пытаюсь включить светодиод три раза, когда подключаю контакт 10 к земле, а затем выключаю его. Затем, когда я отсоединяю контактный номер 10, он НЕ должен снова мигать... но он мигает, и я не могу найти проблему.

это весь код:

bool ledBlinked = false;

void setup() {
  // поместите сюда код установки для однократного запуска:
  pinMode(7, OUTPUT);
  pinMode(10, INPUT_PULLUP);  
}

// Включает и выключает цифровой пин несколько раз с определенной задержкой
void blinkLed(int pin, int times, int del){
  // активирует пин несколько раз
  for (int i=0; i<=times; i++){    
    digitalWrite(pin, HIGH);
    delay(del);
    digitalWrite(pin, LOW);
    delay(del);
  }  
}

// Проверяет, подключен ли переданный номер контакта к земле
bool pinIsGround(int pin){
  return (digitalRead(10) == LOW);
}



void loop() {
  // поместите сюда ваш основной код для многократного запуска:
  if(pinIsGround(10) && !ledBlinked){ //если контакт подключен к земле и светодиод не мигает
    blinkLed(7,3, 100); //мигаем пин 7, 3 раза, с задержкой 100мс
    ledBlinked = true; //светодиод уже мигал
  }
  if (!pinIsGround(10) && ledBlinked){ //если вывод не подключен к земле и светодиод не мигал
    digitalWrite(7, LOW); //выключаем светодиод (ненужно?)
    ledBlinked = false; //светодиод еще не мигал
  }

}

, 👍1

Обсуждение

если pinIsGround() возвращает false, а ledBlinked — false, то (false && false) — true, @Chad G

Не уверен, что такое использование ledBlinked bool, но я думаю, что вы должны просто использовать ветку else, @Chad G

гугл "переключить отказ", @jsotola

@ChadG: не путайте нового ученика с плохой логикой. вы путаете его с двойным отрицанием. Если первая операция && возвращает false, то вторая проверяется новее, но выражение отверстия ложно., @Tomas


1 ответ


Лучший ответ:

0

Поскольку я могу комментировать, я должен написать это как ответ. есть два способа понять ваш вопрос:
Если вы не хотите, чтобы он снова мигал, просто удалите ledBlinked = false;

Если вы пытаетесь предотвратить мигание до тех пор, пока кнопка не будет нажата и нажата снова, то сначала подумайте, что я вижу, это ошибка в функции blinkLed как
for (int i=0; i<=times; i++) будет выполняться раз+один раз. потому что он запускается первым со значением i, равным 0
(например, times=4 будет выполняться, если i равно 0,1,2,3,4 -> Пять раз )
Таким образом, исправление for (int i=0; i<times; i++) будет выполняться правильное количество раз (например, times=4 будет выполняться для i, равного 0,1, 2,3 -> четыре раза )

Несмотря на то, что вы не проверяете состояние кнопки во время работы функции blinkLed, если вы отпустите ее во время работы мигания, скрипт не заметит, если только она не будет нажата, когда скрипт вернется к Петля.
Хотя, поскольку аппаратная операция требует больше работы, чем логическая операция, я бы рекомендовал оператор if...else, а не несколько аппаратных операций. Хотя они упрощают чтение кода

if(digitalRead(10) == LOW){
         if(ledBlinked != true)...
   } else { ...}
,

Я намеренно избегал написания полного кода, так как это убило бы смысл вашего обучения., @Tomas