Эксперимент 45. Работа с кнопкой как с объектом

Раньше мы работали с кнопкой в процедурном стиле. Чтобы понять была ли нажата кнопка мы создавали переменную со старым состоянием кнопки сравнивали с новым. Теперь попробуем сделать это все по- другому. Создадим класс кнопки и объекты для конкретных кнопок.

Соберем простую схему для работы с кнопкой. Пусть при нажатии на кнопку светодиод загорается на 1 секунду.

Схема эксперимента

Рисунок 1. Электрическая принципиальная схема эксперимента

Рисунок 2. Монтажная схема эксперимента

Программный код эксперимента

Теперь напишем программный код.

Exp45.ino
  1. #define LED_PIN 0
  2.  
  3. class Button {
  4. private:
  5. int pin;
  6. bool pressState;
  7. bool oldState;
  8.  
  9. public:
  10. Button(int _pin, bool _pressState) {
  11. pin = _pin;
  12. pinMode(pin, INPUT);
  13. pressState = _pressState;
  14. oldState = not _pressState;
  15. }
  16.  
  17. bool onPress() {
  18. bool state = digitalRead(pin);
  19. if (state != oldState){
  20. oldState = state;
  21. if (state == pressState) return true;
  22. }
  23. return false;
  24. }
  25. };
  26.  
  27. Button btn(16, HIGH);
  28.  
  29. void setup() {
  30. pinMode(LED_PIN, OUTPUT);
  31. }
  32.  
  33. void loop() {
  34. if (btn.onPress()) {
  35. digitalWrite(LED_PIN, HIGH);
  36. delay(1000);
  37. digitalWrite(LED_PIN, LOW);
  38. }
  39. }

Разберем класс кнопки. У него есть конструктор Button():

  1. Button(int _pin, bool _pressState) {
  2. pin = _pin;
  3. pinMode(pin, INPUT);
  4. pressState = _pressState;
  5. oldState = not _pressState;
  6. }

Здесь настраивается вывод микроконтроллера, записывается какое состояние считать нажатым — логический 0 или логическую 1. Ведь это зависит от схемотехники. Если кнопка подтянута к питанию, а при нажатии соединяется с землей, то в нажатом состоянии на выводе будет 0. А если наоборот, то 1.

И у кнопки есть метод определения факта нажатия:

  1. bool onPress() {
  2. bool state = digitalRead(pin);
  3. if (state != oldState){
  4. oldState = state;
  5. if (state == pressState) return true;
  6. }
  7. return false;
  8. }

Здесь считывается текущее состояние кнопки и сравнивается со старым. Состояние сохраняется как старое. Проверяется соответствие состояния кнопки состоянию нажатой кнопки, которое было задано при создании объекта. Если совпадает — значит кнопка нажата, возвращаем True, иначе False.

Создаем объект кнопки. Она на 16 выводе и нажатым будем считать состояние логической 1.

  1. Button btn(16, HIGH);

Использование кнопки стало предельно простым. Нам больше не нужна переменная для хранения прошлого состояния кнопки и вычисление события нажатия. Все это реализовано в классе кнопки. Мы просто создали объект кнопки, передали ей в качестве параметра номер пина и состояние которое считается нажатым. В нашем случае состояние логической единицы когда кнопка нажата. И обращаемся к методу onPress(), чтобы узнать было ли событие нажатия.

  1. if (btn.onPress()) {

Мы могли бы создать несколько таких кнопок и работать с ними также легко.

Дополнительное задание

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