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

Я пытаюсь следовать уроку 6 уроков Arduino Adafruit по цифровым входам, которые можно найти здесь.

У меня один и тот же код, и настройки платы точно такие же, и код, который работает точно так, как должен. Я просто не могу понять, ПОЧЕМУ.

Правление:

Код:

    /*
Adafruit Arduino - Lesson 6. Inputs
*/

int ledPin = 5;
int buttonApin = 9;
int buttonBpin = 8;

byte leds = 0;

void setup() 
{
  pinMode(ledPin, OUTPUT);
  pinMode(buttonApin, INPUT_PULLUP);  
  pinMode(buttonBpin, INPUT_PULLUP);  
}

void loop() 
{
  if (digitalRead(buttonApin) == LOW)
  {
    digitalWrite(ledPin, HIGH);
  }
  if (digitalRead(buttonBpin) == LOW)
  {
    digitalWrite(ledPin, LOW);
  }
}

Почему свет включается при однократном нажатии одной из кнопок и выключается при однократном нажатии другой кнопки? Я не понимаю механизма того, как запоминается пресса.

Похоже, в коде нет ничего, что могло бы объяснить, почему кнопка остается включенной, даже если она больше не нажата, так что это должен быть какой-то компонент? Но что?

Может ли кто-нибудь помочь объяснить, почему это работает?

, 👍2

Обсуждение

вы попадаете в ловушку, думая об этом ... `если кнопка нажата и свет включается, то свет должен погаснуть, если кнопка отпущена"... какая часть кода указывает, чтобы свет выключался, когда кнопка отпущена?, @jsotola

Внимательно посмотрите на код - Если кнопка A находится на низком уровне, включите светодиод, и только если кнопка B находится на низком уровне, он выключится, поэтому, если вы нажмете кнопку B, он выключится, @Coder9390

Порт, управляемый "digitalWrite", поддерживает состояние, похожее на переменную., @timemage


4 ответа


1

Если вы прочитаете урок под первой картинкой и над частями, в нем говорится: "Нажатие кнопки ближе к верхней части макета включит светодиод, нажатие другой кнопки выключит светодиод". Попробуйте нажать и ожидайте, что индикатор погаснет.

,

1

О прессе не вспоминают. Вместо этого выходной контакт "запоминает" свое состояние: digitalWrite(HIGH) устанавливает контакт на высокий, и контакт будет оставаться высоким до тех пор, пока вы не вызовете digitalWrite(НИЗКИЙ).

,

1

Может быть интересно взглянуть на причины, по которым вывод запоминает свое состояние (как описано в других ответах).

Каждый цифровой вывод имеет специальное оборудование для цифрового вывода, которое может привести вывод к ВЫСОКОМУ (Vcc, напряжение питания) или НИЗКОМУ (заземление) значению. Это выходное оборудование внутренне привязано к SFR (регистру специальных функций). Регистр-это часть специального аппаратного обеспечения памяти в микроконтроллере Arduino. Оборудование цифрового вывода электрически подключено к некоторым из этих специальных функциональных регистров. Таким образом, его состояние зависит от того, что сохраняется в этих регистрах. Поскольку регистры сохраняют свое состояние во время работы Arduino (в конце концов, они являются памятью), оборудование цифрового выхода также не изменится, пока вы не измените соответствующие регистры (выполнив digitalWrite()).

Вы даже можете напрямую манипулировать SFR. Это может помочь с программированием кода, зависящего от времени, или установкой/считыванием нескольких контактов одновременно. Все цифровые контакты отсортированы по так называемым портам, которые могут вместить до 8 контактов. Для каждого порта существуют следующие SFR (x обозначает символ соответствующего порта, например PORTA, PORTB, ...), где биты в этих регистрах (размером 1 байт) соответствуют одному выводу в каждом:

  • DDRx: Этот регистр является регистром направления данных. Он контролирует, установлены ли соответствующие контакты в качестве цифрового выхода или входа.
  • PORTx: Этот регистр задает состояние вывода. digitalWrite(pin, HIGH) запишет 1 в соответствующий бит этого регистра, который затем установит вывод на ВЫСОКИЙ. Если соответствующий вывод установлен в качестве входного, установка 1 в соответствующем разряде регистра ПОРТОВ включит внутреннее сопротивление съема этого вывода.
  • PINx: Этот регистр содержит текущее состояние соответствующих выводов, поэтому вы можете использовать его для считывания цифрового вывода.

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

,

2

Я хотел бы добавить еще два цента. Это замечательное объяснение уже от @chrisl Вот скриншот моделирования для вашего примера:

если вы рассмотрите механические выключатели, они действительно отключат соединение, так что свет будет выключен. Когда вы хотите, чтобы свет был включен, вы переместите переключатель в положение "ВКЛЮЧЕНО" (в этом примере удерживайте кнопку).

В случае с микроконтроллерами и в данном примере это больше похоже на общение двух людей.

  1. 1 - й человек смотрит на переключатели. 2-й человек управляет светодиодом
  2. 1-му лицу дается указание уведомить второго человека о том, что кто-либо нажимает на переключатели
  3. всякий раз, когда нажата кнопка ВКЛЮЧЕНИЯ, 1-й человек немедленно скажет второму человеку включить светодиод
  4. Всякий раз, когда нажата кнопка выключения, 1-й человек скажет 2-му человеку выключить светодиод

Поведение программы во многом зависит от требований.


если вы хотели бы видеть, как светодиод выключается, когда вы этого хотите, вы можете попробовать этот пример

Код:

/*
  Adafruit Arduino - Урок 6. Входные
*/

int ledPin = 5;
int buttonApin = 9;
//int buttonBpin = 8;

byte leds = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonApin, INPUT_PULLUP);
  pinMode(buttonBpin, INPUT_PULLUP);
}

void loop()
{
  digitalWrite(ledPin, !digitalRead(buttonApin));
}
,