Эксперимент 10. Кнопочный переключатель
В этом эксперименте мы делаем из тактовой кнопки триггер, борясь с «дребезгом».
Список деталей для эксперимента
1 беспаечная макетная плата
1 тактовая кнопка
1 резистор номиналом 220 Ом
5 проводов «папа-папа»
Для дополнительного задания
еще 1 кнопка
еще 2 провода
Принципиальная схема
Схема на макетке
Обратите внимание
Мы могли бы один из контактов кнопки соединить проводом напрямую с одним из входов GND, но мы сначала «раздали» «землю» на длинную рельсу макетки. Если мы работаем с макетной платой, так поступать удобнее, т.к. в схеме могут появляться новые участки, которые тоже нужно будет соединить с «землей»
Также полезно руководствоваться соображениями аккуратности изделия, поэтому катод светодиода мы соединяем с другим входом GND отдельным проводом, который не мешает нам работать в середине макетки.
Скетч
#define BUTTON_PIN 3 #define LED_PIN 13 boolean buttonWasUp = true; // была ли кнопка отпущена? boolean ledEnabled = false; // включен ли свет? void setup() { pinMode(LED_PIN, OUTPUT); pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // определить момент «клика» несколько сложнее, чем факт того, // что кнопка сейчас просто нажата. Для определения клика мы // сначала понимаем, отпущена ли кнопка прямо сейчас. boolean buttonIsUp = digitalRead(BUTTON_PIN); // . если «кнопка была отпущена и (&&) не отпущена сейчас». if (buttonWasUp && !buttonIsUp) { // . может это «клик», а может и ложный сигнал (дребезг), // возникающий в момент замыкания/размыкания пластин кнопки, // поэтому даём кнопке полностью «успокоиться». delay(10); // . и считываем сигнал снова buttonIsUp = digitalRead(BUTTON_PIN); if (!buttonIsUp) { // если она всё ещё нажата. // . это клик! Переворачиваем сигнал светодиода ledEnabled = !ledEnabled; digitalWrite(LED_PIN, ledEnabled); } } // запоминаем последнее состояние кнопки для новой итерации buttonWasUp = buttonIsUp; }
Пояснения к коду
Поскольку мы сконфигурировали вход кнопки как INPUT_PULLUP , при нажатии на кнопку на данном входе мы будем получать 0. Поэтому мы получим значение true («истина») в булевой переменной buttonIsUp («кнопка отпущена»), когда кнопка отпущена.
Логический оператор && («и») возвращает значение «истина» только в случае истинности обоих его операндов. Взглянем на так называемую таблицу истинности для выражения buttonWasUp && !buttonIsUp («кнопка была отпущена и кнопка не отпущена»):
buttonWasUp | buttonIsUp | !buttonIsUp | buttonWasUp && !buttonIsUp |
0 | 0 | 1 | 0 |
0 | 1 | 0 | 0 |
1 | 0 | 1 | 1 |
1 | 1 | 0 | 0 |
Здесь рассмотрены все возможные сочетания предыдущего и текущего состояний кнопки и мы видим, что наш условный оператор if сработает только в случае, когда кнопка нажата только что: предыдущее состояние 1 («была отпущена»), а текущее 0 («не отпущена»).
Через 10 миллисекунд мы проверяем еще раз, нажата ли кнопка: этот интервал больше, чем длительность «дребезга», но меньше, чем время, за которое человек успел бы дважды нажать на кнопку. Если кнопка всё еще нажата, значит, это был не дребезг.
Мы передаем в digitalWrite не конкретное значение HIGH или LOW , а просто булеву переменную ledEnabled . В зависимости от того, какое значение было для нее вычислено, светодиод будет зажигаться или гаситься.
Последняя инструкция в buttonWasUp = buttonIsUp сохраняет текущее состояние кнопки в переменную предыдущего состояния, ведь на следующей итерации loop текущее состояние уже станет историей.
Arduino.ru
Ребята. Решил освоить функции, что бы коды выглядили компактнее, и разборчевее. Но беда в том что у меня не получается))) Пример такой: Хотел написать функцию считывания кнопки, и защиты от дребезга. А потом ее вывести. Отдельная кнопка, Отдельный светодиод. Ошибок компилятор не выдает. А загружаю в ардуино, ничего не работатет.
- Войдите на сайт для отправки комментариев
Пнд, 26/09/2016 — 21:18
Зарегистрирован: 25.05.2015
1. Вы считаете, что после вызова функции Button(ButtonM, BUTTON_PIN1); , переменная ButtonM поменяеет свое значение? Ничуть ни бывало. Функции никогда не изменяютс своих аргуметнов. Они могут изменить кусок памяти, на который указывает аргумент-указатель или ссылка, но сам аргумент функции не меняют никогда.
2. Второй аргумент Вашей функции имеет тип bool, т.е. может примниать значени true и false и никаких других. А передавать Вы пытаетесь номер пина. В результате Ваша функция всезда будет работать с первым пином (ну или с нулевым, если Вы его явно передадите) и никогда ни с каким другим.
3. Ну про передачу глобальных переменных через параметры я молчу — это не запрещено.
- Войдите на сайт для отправки комментариев
Пнд, 26/09/2016 — 21:56
Зарегистрирован: 10.12.2012
Вот моё решение этой проблеммы, а есть ещё титановый лисапед в шапке форума
- Войдите на сайт для отправки комментариев
Boolean buttonwasup это что
Systop —> Меню
- Войти
SYSTOP » Arduino » Программирование на Arduino. Урок 4. «Карманная гирлянда».
Программирование на Arduino. Урок 4. «Карманная гирлянда».
Всем привет! В предыдущей статье мы разбирали циклические операторы, пора применить их на практике! 🙂 У нас сегодня новый урок и новая задачка, над которой зачастую ломают голову новички в программировании Arduino, а к нам она попала благодаря любопытному ученику, который хотел сделать что-то необычное.
Условия задачи таковы:
У нас есть микроконтроллер Arduino, тактовая кнопка (рассмотри два варианта: когда количество кнопок совпадает с количеством режимов, и когда кнопка у нас всего одна, а переключаться нужно между несколькими режимами), несколько светодиодов разного цвета (пусть пока их будет 3).
Приступим к решению этой задачи:
И для начала разберемся как «объяснить» микроконтроллеру, какие элементы мы будем использовать.
Для того чтобы управлять светодиодом, достаточно использовать команду:
digitalWrite (номер пина, к которому подключён светодиод).
Пример:
digitalWrite(5);
Но вот, чтобы горел он как-нибудь необычно, нужно воспользоваться своей фантазией и операциями алгебры логики, но пугайтесь, сейчас обо всем по-порядку:
Этап 1: Подключение тактовой кнопки и считывание с нее сигнала:
Рис. 1 Подключение тактовой кнопки
Этап 2: Включение светодиода по нажатию кнопки:
#define BUTTON_PIN 3 //назначаем пины, которые будут отвечать да работу кнопки и светодиода #define LED_PIN 13 boolean buttonWasUp = true; //задаем начальные значения для переменных boolean ledEnabled = false; void setup() < pinMode(LED_PIN, OUTPUT); //конфигурируем пины, пин кнопки на вход(с него мы будем считывать данные) pinMode (BUTTON_PIN, INPUT_PULLUP); //пин светодиода на выход, на него мы будем подавать сигнал > void loop() < boolean buttonIsUp = digitalRead(BUTTON_PIN); //проверяем, нажата ли кнопка if (buttonWasUp && !buttonIsUp) < //Если нажата, нам нужно подождать 10 миллисекунд delay (10); //чтобы убедиться, что это не случайный дребезг buttonIsUp = digitalRead (BUTTON_PIN); //Убедившись, что все хорошо и кнопка нажималась if (!buttonIsUp) < //Выполняем действие - меняем состояние светодиода на противоположное ledEnabled = !ledEnabled; digitalWrite(LED_PIN, ledEnabled); >> buttonWasUp = buttonIsUp; //Запоминаем, что мы нажимали кнопку > //Теперь при следующем нажатии на нее, мы снова изменим состояние светодиода на противоположное
Программа управления светодиодом с помощью одной кнопки
Для считывания сигнала с кнопки необходимо проверять нажатие дважды с небольшой задержкой (от 5-10 мс) для предотвращения реагирования на дребезг. В примере программы выше описано именно такое считывание: введены две переменных buttonWasUp и buttonIsUp, в которые записываются значения считывания сигнала с кнопки с интервалом в 10 мс. В переменной ledEnabled записано значение, которое передается на светодиод. Изначально переменная имеет значение false, т.е. 0, когда считывается нажатие кнопки, значение переменной ledEnabled меняется на противоположное, т.е true — (1), при следующем считывании нажатия значение снова станет false.
Итак, со считывание сигнала с кнопки мы разобралась.
Этап 3: Количество кнопок равно количеству режимов.
Для увеличения количества элементов, которыми мы будем управлять, мы добавим количество кнопок:
#define BUTTON_PIN_1 3 #define BUTTON_PIN_2 4 #define LED_PIN_1 12 #define LED_PIN_2 13 boolean buttonWasUp_1 = true; boolean buttonWasUp_2 = true; boolean ledEnabled_1 = false; boolean ledEnabled_2 = false; //Здесь у нас практически тоже самое, вот только кнопок у нас теперь две и два светодиода void setup() < pinMode(LED_PIN_1, OUTPUT); pinMode (LED_PIN_2, OUTPUT); pinMode (BUTTON_PIN_1, INPUT_PULLUP); pinMode (BUTTON_PIN_2, INPUT_PULLUP); > void loop() < boolean buttonIsUp_1 = digitalRead(BUTTON_PIN_1); if (buttonWasUp_1 && !buttonIsUp_1) < delay(10); buttonIsUp_1 = digitalRead (BUTTON_PIN_1); if (!buttonIsUp_1) < ledEnabled_1 = !ledEnabled_1; digitalWrite(LED_PIN_1, ledEnabled_1); > > buttonWasUp_1 = buttonIsUp_1; boolean buttonIsUp_2 = digitalRead(BUTTON_PIN_2); if (buttonWasUp_2 && !buttonIsUp_2) < delay(10); buttonIsUp_2 = digitalRead (BUTTON_PIN_2); if (!buttonIsUp_2) < ledEnabled_2 = !ledEnabled_2; digitalWrite(LED_PIN_2, ledEnabled_2); > > buttonWasUp_2 = buttonIsUp_2; >
Теперь здесь две кнопки и два светодиода
Таким способом можно увеличивать количество кнопок и светодиодов до тех пор пока у нас есть свободные пины.
Этап 4: «Новогодняя гирлянда»
Все видели новогодние гирлянды, в которых по нажатию кнопки переключаются режимы: «Бегущий огонек» или, например, гирлянда начинает постепенно зажигаться и гаснуть.
Давайте попробуем повторить.
Теперь у нас есть всего одна кнопка и несколько режимов «гирлянды», между которыми мы будем переключаться.
Основная идея состоит в том, чтобы считать количество нажатий кнопки. Допустим, у нас три светодиода, между которыми мы хотим переключаться. Тогда нам нужно считать количество нажатий кнопки и находить остаток от деления на три (три режима — остаток от деления на три).
Программа объединяет в себе две предыдущих, с небольшим отличием: использование оператора swich-case, который ставит в соответствие каждому остатку от деления определенное действие.
Подробнее о структуре оператора swich-case расскажу в следующей статье.
#define BUTTON_PIN 5 //пин, к которому подключена кнопка #define LED_PIN_1 2 //пин 1 светодиода #define LED_PIN_2 3 //пин 2 светодиода #define LED_PIN_3 4 //пин 3 светодиода int buttonklick = 0; //обнуление переменной-счетчика нажатий кнопки boolean buttonWasUp = true; // переменная, в которую производится запись была ли кнопка отпущена? void setup() < Serial.begin(9600); //подключения монитора порта, для отлаживания программы //в монитор порта будет выводиться количество нажатий кнопки for (int i = LED_PIN_1; i pinMode(i, OUTPUT); //конфигурация пинов с помощью цикла с параметром //i-счетчик параметра //синтаксис цикла //for (int i=начальное значение; i(>) pinMode(BUTTON_PIN, INPUT_PULLUP); //конфигурация пина для считывания сигнала с кнопки //INPUT_PULLUP использование внутренних стабилизаторов //для предотвращения обратного сигнала-дребезга > void loop() < // определить момент «клика» несколько сложнее, чем факт того, // что кнопка сейчас просто нажата //для определения клика мы используем "двойную проверку" boolean buttonIsUp = digitalRead(BUTTON_PIN); //проверяем, была ли кнопкам нажата //если «кнопка была нажата и (&&) не отпустили ли мы нажатие сейчас» if (buttonWasUp && !buttonIsUp) < // может это «клик», а может и ложный сигнал (дребезг), // возникающий в момент замыкания/размыкания пластин кнопки, // поэтому даём кнопке полностью «успокоиться». delay(10); // считываем сигнал снова buttonIsUp = digitalRead(BUTTON_PIN); if (!buttonIsUp) < // если она всё ещё нажата. //считаем количество кликов по кнопке //прибавляя к предыдущему количеству кликов еще одно buttonklick = buttonklick + 1; >> //вводим переменную, значение которой будет связано с количеством нажатий кнопки //ставим в соответствие количеству нажатий определенное действие int action = buttonklick % 3; //в переменную действия записывается остаток от деления //количества нажатий кнопки на количество действий, которые нам необходимо производить //выводим в монитор порта количество нажатий кнопки и остаток от деления Serial.println("buttonklick"); Serial.print(buttonklick); Serial.println("action"); Serial.print(action); //каждому значению переменной действия //ставим в соответствие определённое действие switch (action) < //Если остаток от деления количества кликов нв количество действий равен 0, то: case 0: < digitalWrite(LED_PIN_1, HIGH); //включаем первый светодиод digitalWrite(LED_PIN_3, LOW); //и выключаем предыдущий delay(100); //минимальное время, между последовательными переключениями break; > //Если остаток от деления количества кликов на количество действий равен 1, то: case 1: < digitalWrite(LED_PIN_2, HIGH); digitalWrite(LED_PIN_1, LOW); delay(100); break; > //Если остаток от деления количества кликов на количество действий равен 2, то: case 2: < digitalWrite(LED_PIN_3, HIGH); digitalWrite(LED_PIN_2, LOW); delay(100); break; > > >
Программа для «Новогодней гирлянды»
Готовые программы Вы можете скачать по ссылке здесь:
В следующих статьях ждите еще больше интересных проектов. Будем рады, если Вы напишете свои пожелания, о том, что бы Вы хотели видеть на нашем сайте 🙂
Boolean buttonwasup это что
Скачай курс
в приложении
Перейти в приложение
Открыть мобильную версию сайта
© 2013 — 2023. Stepik
Наши условия использования и конфиденциальности
Public user contributions licensed under cc-wiki license with attribution required