Debounce из книги
- Войдите на сайт для отправки комментариев
Поскажите пожалуйста. Почему при загрузке кода Debounce из книги Изучаем Ардуино сразу загорается светодиод, хотя кнопка не нажималась. По идее, вроде как светодиод должене загореться только после первого нажатия на кнопку.
const int LED=9;
const int BUTTON=2;
boolean lastButton = LOW;
boolean currentButton = LOW;
boolean ledOn = false;
void setup ()
{
pinMode (BUTTON, INPUT);
pinMode (LED, OUTPUT);
}
/*
* Функция сглаживания дребезга
* принимает в качестве аргумента предыдущее состояние кнопки
* и выдает фактическое.
*/
boolean debounce(boolean last)
{
boolean current = digitalRead(BUTTON);
if (last != current)
{
delay(5);
return current;
}
}
void loop()
{
currentButton = debounce(lastButton);
if (lastButton == LOW && currentButton == HIGH)
{
ledOn = !ledOn;
}
lastButton = currentButton;
digitalWrite(LED, ledOn);
}
Поскажите пожалуйста.
Возможно, и "поскажем", но для начала, изучите правила этого форума, и вставьте код как положено. Заодно, и схема включения светодиода не помешает.
Трофим, вам ведь про схему не зря написали. И кнопку, и светодиод можно подключить к пину двумя правильными способами и х.з сколькими неправильными. Вот как конкретно у вас (не в книжке).
Кстати, программа, как я понимаю, из книги Блума? Причём из издания на русском языке. Правильно? Я вижу здесь одну из тех самых ошибок, о которых писал вот здесь.
Почитайте ту, тему, найдите сайт книги, скачайте архив примеров, возьмите там правильный код этого примера, разберитесь в чём разница и постарайтесь понять в чём ошибка. Это очень полезное упражнение для Вашего обучения.
Кнопка подключена через PULLDOWN резистор к pin 2. Таким образом вход pin 2 срабатывает от высокого уровня на кнопке. Приведенный мною код полностью соответствует коду из книги Джереми Блума на английском языке. Как ни странно симуляция этого кода на Tinkercard работает правильно, т.е. светодиод не загорается при включении, а в реальности, загорается. Непонятно.
Что должна возвращать функция debounce?
Что должна возвращать функция debounce?
Не надо. Эта та самая ошибка в книге, о которой я говорю. Пусть скачает правильный текст и разберётся. Пользы на порядок больше будет.
ТС, Вы нашли архив со всеми скетчами из книги? Скачали? Разницу увидели?
Я смотрел урок Джереми Блума на английском языке в Youtube, где он пишет этот скетч на экране и у него при загрузке точно так же загорается светодиод. Хотя судя по программе этого не должно быть. Архив я не скачал.
Дак я не показываю ошибку,а намекаю куды смотреть.
Архив я не скачал.
Ну, так, качайте и сравнивайте. Там элементарная опечатка.
Да и в ролике на ютюбе Джереми функцию debounce без опечаток пишет.
Возможно, но я человек старый и предпочитаю книги. А ролики на ютубе - это для тех, кто читать не умеет, по-моему.
Не могли бы дать ссылку на архив. Я не могу найти. Тогда бы я и сравнил.
Посмотрел библиотеку. Здесь изначально в глобальной переменной задается
int ledState = HIGH;
В предыдущем коде
ledOn = false.
Как в процессе загрузки ledOn меняется на true мне непонятно.
*/
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// Variables will change:
int ledState = HIGH; // the current state of the output pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers
void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
// set initial LED state
digitalWrite(ledPin, ledState);
}
void loop() {
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited long enough
// since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer than the debounce
// delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == HIGH) {
ledState = !ledState;
}
}
}
// set the LED:
digitalWrite(ledPin, ledState);
// save the reading. Next time through the loop, it'll be the lastButtonState:
lastButtonState = reading;
}
После нажатия кнопки ф-ция Debounce по идее должна возвратить новое состояние кнопки (current) те HIGH, с которым и сравнивается предыдущее состояние. Только после этого должен загореться светодиод. Но почему он загорается сразу после загрузки скетча? Ведь все переменные объявлены как LOW!!!
В строке 21+ ошибка - Вы правы!
Уже какую-то библиотеку приплели, она тут причём?
https://www.exploringarduino.com/content/ch2/ внизу страницы большая кнопка Download, а ещё чуть ниже ссылка на гитхаб.
Или, как я уже написал, даже в ролике, который Вы якобы смотрели, правильный текст.
В строке 21 пробел. Где ошибка?
digitalWrite(LED, LOW); в 22 добавьте следом, может поможет.
int
ledState = LOW; или в 8 заменить.
В строке 21+ ошибка - Вы правы!
Это был сарказм по поводу того, что Вы неправильно вставили программу. Но Вы очень быстро исправились. Приношу извинения и, посоветовавшись с коллегами, советую Вам сменить библиотеку.
Не помогает.
Не помогает.
Тоесть светодиод не выключается?
Не помогает.
Тогда начинаем изучать Serial.print() и выдаем на консоль состояние всех переменных перед их использованием. Чудес не бывает бывает или неправильная схема или неправильная программа. Значит будем локализовать ошибку.
Как нам поможет Serial.print(), если все переменные забиты в памяти? Почему-то при загрузке Debounce происходит инверсия ledOn. И на выходе 9 pin сразу HIGH. Замерял мультиметром сразу после загрузки.
Наверное потому что не все переменные, объявлены как LOW. Можете убедиться в этом Serial.print-ом.
Как нам поможет Serial.print(), если все переменные забиты в памяти? Почему-то при загрузке Debounce происходит инверсия ledOn. И на выходе 9 pin сразу HIGH. Замерял мультиметром сразу после загрузки.
А где у вас в скетче написано, что вначале должно быть LOW?
9 строчка
boolean ledOn = false;
9 строчка
boolean ledOn = false;
Так это присвоение значения переменной, а не подача логического уровня на выход.
Как нам поможет Serial.print(), если все переменные забиты в памяти? Почему-то при загрузке Debounce происходит инверсия ledOn. И на выходе 9 pin сразу HIGH. Замерял мультиметром сразу после загрузки.
Вы не поверите, но даже самые крутые программисты используют консоль (или иже с ней) для нахождения своих ошибок. Ну если Вы круче крутого, то я промолчу, наверное...
Просто я не знаю как в данном случае использовать консоль. Если подскажите - буду благодарен.
Да, но если мы не написали команду digitalWrite (9, HIIH); (а мы этого не делали), то высокий уровень там не должен появиться. А он появляется.
9 строчка
boolean ledOn = false;
Обсуждается самый последний скетч, а не тот, о котором Вы думаете.
Мы же инвертируем ledOn только после нажатия кнопки и после того подаем на 9pin обратное значение ledOn те TRUE
Изначально мы говорили о скетче из книги (самый первый). В котором для меня и происходят непонятные явления с зажиганием LED без нажатия кнопки сразу после загрузки. Вот это длz меня и не понятно тк изначально объявлен статус светодиода FALSE
Просто я не знаю как в данном случае использовать консоль. Если подскажите - буду благодарен.
Вот тут могу помочь Вам. Например перед 21 строчкой написать Serial.print("ledstate: "); Serial.println(ledState);
И так при любом изменении пинов.
Изначально мы говорили о скетче из книги (самый первый). В котором для меня и происходят непонятные явления с зажиганием LED без нажатия кнопки сразу после загрузки.
В нём есть опечатка, которая и приводит к странным явлениям.
Да, но если мы не написали команду digitalWrite (9, HIIH); (а мы этого не делали), то высокий уровень там не должен появиться. А он появляется.
А вы попробуйте написать digitalWrite (9, LOW); и если высокий уровень появится то завтра я попробую на Ардуине проверить сам :)
Можете указать на эту опечатку, потому что из логики написанного (если проанализировать код), так не должно происходить
Можете указать на эту опечатку, потому что из логики написанного (если проанализировать код), так не должно происходить
Когда-то мы с другом писали достаточно большую программу (где-то 2т строк). И она тоже делала не то, что казалось изначально. В итоге мы локализовали эту ошибку. Я уверен, что в программе в 20 строк это можно сделать намного быстрее. Особенно, когда Вам дают дельные советы.
Пробовал много раз. В void setup() специально указывал digitalWrite (9, LOW); Все равно после загрузки LED горит. Причем если для проверки указывал дополнительно pinMode (10, OUTPUT); то на 10 pin устанавливалось после загрузки LOW как и положено. Похоже, что все дело в ф-ции Debounce. Почему то она инвертирует состояние светодиода.
Пробовал много раз. В void setup() специально указывал digitalWrite (9, LOW); Все равно после загрузки LED горит. Причем если для проверки указывал дополнительно pinMode (10, OUTPUT); то на 10 pin устанавливалось после загрузки LOW как и положено. Похоже, что все дело в ф-ции Debounce. Почему то она инвертирует состояние светодиода.
Ну вот и эксперимент - венец истины :), значит дальше надо смотреть.
Возможно это не для программистов. Почему Вы боитесь косоль? Почитайте
:) на всякий случай в сетап поставьте делай секунд 10, ну чтоб окончательно убедиться что не горит сначала, а потом горит.
Единственное к какому выводу я пришел, что Debounce инвертирует состояние светодида (ledOn). Но почему так происходит мне не понять. Это значит, что логика работы ф-ции Debounce мне до конца непонятна.
Не могли бы дать ссылку на архив. Я не могу найти. Тогда бы я и сравнил.
https://drive.google.com/open?id=0B9r7cRXQ4DU4XzVLeUVkNHdiaVU
Ставил. Принципиально никаких различий. Все то же самое.
Единственное к какому выводу я пришел, что Debounce инвертирует состояние светодида (ledOn). Но почему так происходит мне не понять. Это значит, что логика работы ф-ции Debounce мне до конца непонятна.
Вам всё на тарелочке выложили в посте #6 подумайте в этом направлении.
Вам всё на тарелочке выложили в посте #6 подумайте в этом направлении.
Евгений - опять всю интригу убили. Тут еще флуда страниц на пять было :)
И будет, куда денется. Если уж Сэдмен не убил, то куда мне!
А темка-то пятничная - только графа не хватает, а так уже "вся безумная больница" :)))