Serial.print() Inferferes с моим digitalRead()
Я столкнулся с проблемой правильного чтения кнопки, подключенной к цифровому выводу ввода-вывода на устройстве Adafruit Feather HUZZAH ESP8266.
Я реализовал сценарий debouncing точно так, как показывает приведенный пример Arduino, но если я добавлю инструкцию print в свой цикл настройки:
void setup() {
Serial.begin(230400);
Serial.println("Starting");
pinMode(buttonPin, INPUT_PULLUP);
}
Я запускаю считывание переключателя при каждом цикле сброса. Закомментировав инструкцию print, вы избежите этой проблемы, поэтому она не будет связана со сценарием отмены.
Кроме того, я могу воспроизвести проблему на любом цифровом выводе ввода-вывода, даже если он не подключен. Как только я пройду функцию настройки, все будет работать так, как задумано. Вот весь мой установочный код (опять же, скопированный из примера):
const int buttonPin = 13;
int buttonState;
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
void setup() {
Serial.begin(230400);
Serial.println("Starting");
pinMode(buttonPin, INPUT_PULLUP);
lastDebounceTime = millis();
}
void loop() {
int reading = digitalRead(buttonPin);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
Serial.println("A");
}
}
lastButtonState = reading;
}
А вот вывод моего последовательного монитора (без задержек при сбросе):
Starting
A
Я могу избежать этого, просто игнорируя первый кнопочный переключатель, но кажется странным, что это происходит, и я не могу найти никаких объяснений тому, что происходит.
@Marc, 👍1
Обсуждение2 ответа
Лучший ответ:
Вам нужно инициализировать buttonState
до текущего состояния сигнала и инициализировать lastDebounceTime
до текущего времени, что-то вроде этого:
int buttonState = digitalRead(buttonPin);
unsigned long lastDebounceTime = millis();
Сравните с этим очень простым дебоунсером, который я поставил на GitHub.
Вы абсолютно правы! Я не уверен, почему я этого не уловил или почему скетч Arduino не инициализирует переменные., @Marc
Инициализация моего buttonState решила мою проблему:
int buttonState = LOW;
В любом случае имейте в виду, что последовательная запись приостанавливает работу микроконтроллера на несколько миллисекунд!, @alessandromrc
@alessandromrc: На несколько микросекунд. Если буфер TX не заполнен, в этом случае он действительно может занять миллисекунды., @Edgar Bonet
@EdgarBonet Ты прав!, @alessandromrc
- Устранение дребезга кнопки с помощью прерывания
- Хорошая кнопка debouncing/Библиотека StateChange
- Прерывание при нажатии кнопки + устранение дребезга
- Кнопка переключения переключает между операторами обращения с разблокированием кнопки
- Код проверки продолжительности нажатия кнопки
- Как добавить индикаторы на скетч кнопки
- Проблемы с определением цифрового состояния кнопки
- Программное обеспечение, устраняющее дребезг кнопки при отпускании
Пожалуйста, включите не только ваш установочный код, но и весь код целиком., @chrisl
Мы тоже не можем, так как не можем видеть ваш код ;) Нет никакой особой причины, по которой запись в последовательный порт могла бы "вызвать чтение кнопки". Однако последовательная запись является асинхронной, и добавление вызова
Serial.println
увеличивает (а) время, потраченное на "настройку", и (б) время, потраченное на выполнение "вещей" до того, как последовательный буфер будет записан. Кажется более вероятным, что в логике debounce есть недостаток, *особенно* если "lastDebounceTime" инициализируется как " 0 " (давным-давно для контроллера)., @Dave NewtonДобавил свой код цикла. @DaveNewton - Я изменил настройки, чтобы сбросить lastDebounceTime до последней операции перед входом в цикл, но все равно печатаю "A" при каждом сбросе., @Marc
Вы пробовали переместить PIN-режим, чтобы избежать периода плавающего?, @Dave Newton
Я пробовал поставить его первым и последним в своей настройке, но безрезультатно. Будет ли какой-то период времени, необходимый для того, чтобы цифровое считывание "осело" или что-то в этом роде?, @Marc
Проблема заключалась в том, что buttonState никогда не инициализировался в примерах сценариев, поэтому он начинается != с чтения, таким образом, срабатывая, как только таймер превышает задержку отмены. Я смог исправить это, просто инициализировав значение так, чтобы оно совпадало со значением lastButtonState., @Marc
На самом деле я не обращал особого внимания на этот вопрос; я просто заметил, что вы решили свою собственную проблему. Если то, что вы написали выше, является ответом, который следует из информации в вопросе, и вы думаете, что все это будет полезно кому-то еще, вы можете опубликовать свой собственный ответ на него. В противном случае вопрос, скорее всего, навсегда останется в системе без ответа, если вы его не удалите., @timemage