Программа должна при каждом нажатии кнопки менять состояние светодиода, т.е. включать и выключать его. В этой программе надо:
- считать состояние кнопки;
- сравнить его с предыдущим состоянием;
- если предыдущее состояние было отжата, а текущее состояние нажата – инвертировать состояние светодиода.
Т.е. программа должна отлавливать фронт кнопки или перепад состояния сигнала. Есть два фронта сигнала:
- с высокого состояния в низкое ( --_ );
- с низкого состояния в высокое (_--).
Нажатие кнопки будет соответствовать перепаду сигнала из высокого в низкое. Это событие мы и должны выделить.
/* Программа sketch_6_1 урока 6
* На каждое нажатие кнопки инвертирует состояние светодиода
* Работает неправильно из-за дребезга контактов */
#define LED_PIN 13 // номер вывода светодиода равен 13
#define BUTTON_PIN 12 // номер вывода кнопки равен 12
* На каждое нажатие кнопки инвертирует состояние светодиода
* Работает неправильно из-за дребезга контактов */
#define LED_PIN 13 // номер вывода светодиода равен 13
#define BUTTON_PIN 12 // номер вывода кнопки равен 12
boolean buttonState; // состояние кнопки
boolean buttonPrevState; // предыдущее состояние кнопки
boolean ledState; // состояние светодиода
boolean buttonPrevState; // предыдущее состояние кнопки
boolean ledState; // состояние светодиода
void setup() {
pinMode(LED_PIN, OUTPUT); // определяем вывод 13 (светодиод) как выход
pinMode(BUTTON_PIN, INPUT_PULLUP); // определяем вывод 12 (кнопка) как вход
}
pinMode(LED_PIN, OUTPUT); // определяем вывод 13 (светодиод) как выход
pinMode(BUTTON_PIN, INPUT_PULLUP); // определяем вывод 12 (кнопка) как вход
}
void loop() {
buttonState= digitalRead(BUTTON_PIN); // записываем состояние кнопки в переменную buttonState
if ( (buttonPrevState == HIGH) && (buttonState == LOW) ) {
// предыдущее состояние кнопки - отжата, а текущее - нажата
ledState= ! ledState; // инверсия состояния светодиода
digitalWrite(LED_PIN, ledState); // запись состояния светодиода из переменной нв выход
}
buttonPrevState= buttonState; // предыдущее состояние кнопки = текущему
}
if ( (buttonPrevState == HIGH) && (buttonState == LOW) ) {
// предыдущее состояние кнопки - отжата, а текущее - нажата
ledState= ! ledState; // инверсия состояния светодиода
digitalWrite(LED_PIN, ledState); // запись состояния светодиода из переменной нв выход
}
buttonPrevState= buttonState; // предыдущее состояние кнопки = текущему
}
Выделение события происходит в конструкции
if ( (buttonPrevState == HIGH) && (buttonState == LOW) )
&& это логическое И, производимое над условными выражениями. В результате его применения будет выработано условие истинно, если оба выражения истинны. В данном случае блок оператора if будет выполнен, если одновременно предыдущее состояние кнопки = HIGH и текущее состояние кнопки = LOW. Т.е. если кнопка была отжата в предыдущей проверке, а сейчас нажата.
По этому условию инвертируется состояние светодиода.
В принципе, несложная программа. Но загрузите ее в плату Ардуино и проверьте, как она работает.
Неправильно она работает. Иногда, на нажатие кнопки, она инвертирует состояние светодиода, иногда нет. Часто светодиод мерцает в момент нажатия. Происходит это потому, что сигнал с кнопки совсем не такой, как мы его представляем.
по материалам http://mypractic.ru/urok-6-obrabotka-drebezga-kontaktov-knopki-interfejs-svyazi-mezhdu-programmnymi-blokami.html
Проанализируем в ИС ДРАКОН предложенный вариант (функцию void loop()) так как предложенный выше вариант рассчитан скорее на работу программы с компьютером, чем с контроллером.
альтернативный вариант предусматривает защиту от долгого нажатия кнопки, которое может перевести к миганию светодиода. Кроме того экономиться оперативная память, что для контроллера очень значимо.
программный код представлен ниже
// Y:\home\deniska\Документы\др длкр\Новый_17.drt
// 33. Схема - Гном, Изменение 09.12.2018 13:41:08
// 37. Модуль, Начало
void setup()
{
pinMode(13, OUTPUT); // определяем вывод 13 (светодиод) как выход
pinMode(12, INPUT); // определяем вывод 12 (кнопка) как вход
pinMode(13, INPUT); // определяем вывод 13 (светодиод) как вход
}
// Y:\home\deniska\Документы\др длкр\Новый_17.drt
// 4. Схема - процедура, Изменение 09.12.2018 14:52:18, Начало
void loop()
{
// ==================== Шампур
// 5. Заголовок / альтернатива
// 38. Вопрос / digitalRead(12) == HIGH == Да
// -19. Левый комментарий / предыдущее состояние кнопки - отжата, а текущее - нажата
if (digitalRead(12) == HIGH) goto L42; // 6. Конец / Конец
goto L_end4;
// ==================== Шампур
L42: ;
// 42. Вопрос / digitalRead(13)== LOW == Да
if (digitalRead(13)== LOW && digitalRead(12) == HIGH) goto L20;
// 21. Полка / запись состояния светодиода на выход / digitalWrite(13, LOW);
digitalWrite(13, LOW);
L40: ;
// 40. Вопрос / digitalRead(12) == HIGH == Да
// -24. Левый комментарий / пока конопка нажата
if (digitalRead(12) == HIGH) goto L_end4;
goto L_end4;
// ==================== Шампур
L20: ;
// 20. Полка / запись состояния светодиода на выход / digitalWrite(13, HIGH);
digitalWrite(13, HIGH);
goto L40;
// 4. Схема, Конец
L_end4: ;
//
}
// 37. Модуль, Конец
//
тоже самое в скретче виртуальной лаборотории
void setup()
{
pinMode(12, INPUT);
pinMode(13, INPUT);
pinMode(13, OUTPUT);
}
void loop()
{
if (digitalRead(12) == HIGH) {
if (digitalRead(13) == LOW) {
digitalWrite(13, HIGH);
} else {
digitalWrite(13, LOW);
}
while (digitalRead(12) == HIGH) {
}
}
}