читать состояние с кнопки, чтобы проверить, нажали ли

Я здесь новичок и плохо знаком с платформой Arduino.

Я хочу создать "меню", используя LCD 20*4, поэтому я хочу обнаружить событие "нажатие кнопки".

Я подключил кнопку к контакту 8 и к земле, вот так (пожалуйста, не обращайте внимания на другую проводку):

int leftButton = 8;   

void setup() {
  pinMode(leftButton, INPUT);   
  digitalWrite(leftButton, HIGH);
  Serial.begin(9600);


}
bool leftButtonClicked(){
  return digitalRead(leftButton);
}
void loop(){
  delay(20);
  Serial.println(digitalRead(leftButton));   
}

Я получаю серийный номер 1, пока кнопка не нажата, а при ее нажатии я получаю 0.

В чем проблема? Спасибо вам, ребята.

, 👍0

Обсуждение

Это нормально подключать кнопку так, чтобы при нажатии она замыкалась на землю. Таким образом, вы можете использовать INPUT_PULLUP в своем pinMode, и вам не нужен подтягивающий резистор. Таким образом, в обычных случаях ваш код будет читать нажатую кнопку как 0, если вы подключили ее обычным способом., @Delta_G

Почему вы думаете, что это проблема?, @chrisl

@Delta_G поэтому, согласно вашей поговорке, «1» означает «не нажато», а «0» означает «нажато». это приемлемый способ сделать это? есть предпочтительный метод для изоляции события click?, @itzikb

По моему мнению, это зависит от того, как вы подключите кнопку, но большинство людей предпочитают подключать ее так, чтобы 0 нажимался, а 1 не нажимался. Вы можете подключить его так, чтобы нажималась 1, но для этого потребуется дополнительный резистор., @Delta_G

Также вам нужно изменить свой pinMode на INPUT_PULLUP вместо просто INPUT, иначе вы начнете видеть случайные нажатия фантомных кнопок, поскольку плавающий вход улавливает шум из окружающей среды., @Delta_G

@Delta_G, да, я обновил код. есть предпочтительный метод для изоляции события click?, @itzikb

Что вы подразумеваете под «изолировать событие клика». Вы тестируете так же, как с оператором if. Если digitalRead возвращает false, значит, кнопка была нажата, и вы делаете для этого все, что хотите. Arduino на самом деле не является системой, управляемой событиями. Вы пишете код на более базовом уровне., @Delta_G

@Delta_G да, я обычно программирую на JS и т. Д., Так что для меня это действительно странно, как я думаю таким способом программирования., @itzikb


1 ответ


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

1

Поскольку вы новичок, у вас, похоже, есть некоторые неправильные представления:

  • Чтение состояния кнопки с помощью digitalRead(): вы подумали, что что-то не так, потому что вы думали, что возвращается digitalRead(), если кнопка была нажата (таким образом, 1 будет означать нажатие). Но это не так. digitalRead() возвращает электрическое состояние соответствующего контакта (если напряжение на контакте находится на уровне земли (0) или на уровне Vcc (напряжение питания)) (1)). Это соответствует кнопке в зависимости от вашей проводки. Я думаю, вы скопировали проводку где-то в Интернете. На ней показан наиболее распространенный способ подключения кнопки. Кнопка состоит всего из двух контактов, которые сжимаются вместе при нажатии на кнопку. Таким образом, кнопка может подключать контакт либо к земле, либо к Vcc, но не к обоим. Когда кнопка не нажата, контакт ни к чему не подключен, поэтому он плавает, и значение меняется хаотично. Это решается с помощью подтягивающего или подтягивающего резистора (довольно большой резистор от вывода до Vcc или земли), который устанавливает значение вывода, когда кнопка не нажата. Это означает, что вам нужен 1 резистор для каждой кнопки, которую вы хотите использовать. Хорошая новость: в Arduino уже есть внутренние подтягивающие резисторы, которые можно активировать с помощью pinMode(pin, INPUT_PULLUP). Таким образом, вы можете сэкономить 1 дополнительный компонент. Поскольку это подтягивающий резистор, который соединяет контакт с Vcc, вам необходимо соединить кнопку с землей.

    Это также дает вам перевернутую логику. В конце концов, вы сами определяете, что означает значение digitalRead(). Подумайте об этом с точки зрения электричества.

  • События: В программировании Arduino нет событий. Вы программируете непосредственно аппаратное обеспечение. Не существует ОС или системы с графическим интерфейсом, которая обрабатывала бы события за вас. Программа, которую вы пишете, выполняет команду за командой с определенной скоростью (определяемой тактовой частотой ардуино; 16 МГц для Uno), практически линейно. Хотя есть одно исключение: прерывания. В микроконтроллеры встроены некоторые периферийные устройства (АЦП, коммуникационные интерфейсы, таймеры, ...), и многие из них работают параллельно с основной программой (поскольку их функция не требует кода, а реализована аппаратно). Эти периферийные устройства могут генерировать прерывания (например, для обслуживания периферийных устройств), которые приостанавливают нормальный запуск программы, запускают ISR (подпрограмму обслуживания прерываний) и затем возвращаются к основной программе. Это чем-то похоже на событие, но очень специфичное для аппаратного обеспечения и далеко не такое универсальное, как события на ПК.

  • Чтение нажатия кнопки. В коде вы читаете не "щелчок кнопки", а только состояние кнопки. Таким образом, вы получаете несколько раз 0 для одного достаточно долгого нажатия кнопки. Для реального действия клика вам нужно искать переход от 1 к 0, что в идеале происходит только один раз за нажатие кнопки. Я пишу "в идеале", потому что в реальной жизни кнопки дребезжат. В момент касания значение быстро меняется несколько раз, пока контакты кнопки не улягутся. Так что вам нужно устранить дребезг кнопки. Вы уже выполнили базовое устранение дребезга с помощью delay(20) (потому что кнопке может потребоваться примерно это время для стабилизации). Вы можете увидеть более сложную функцию устранения дребезга в библиотеке Bounce2, которую также легко использовать для чтения щелчков и нажатий кнопок.

,