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

Я могу избежать этого, просто игнорируя первый кнопочный переключатель, но кажется странным, что это происходит, и я не могу найти никаких объяснений тому, что происходит.

, 👍1

Обсуждение

Пожалуйста, включите не только ваш установочный код, но и весь код целиком., @chrisl

Мы тоже не можем, так как не можем видеть ваш код ;) Нет никакой особой причины, по которой запись в последовательный порт могла бы "вызвать чтение кнопки". Однако последовательная запись является асинхронной, и добавление вызова Serial.println увеличивает (а) время, потраченное на "настройку", и (б) время, потраченное на выполнение "вещей" до того, как последовательный буфер будет записан. Кажется более вероятным, что в логике debounce есть недостаток, *особенно* если "lastDebounceTime" инициализируется как " 0 " (давным-давно для контроллера)., @Dave Newton

Добавил свой код цикла. @DaveNewton - Я изменил настройки, чтобы сбросить lastDebounceTime до последней операции перед входом в цикл, но все равно печатаю "A" при каждом сбросе., @Marc

Вы пробовали переместить PIN-режим, чтобы избежать периода плавающего?, @Dave Newton

Я пробовал поставить его первым и последним в своей настройке, но безрезультатно. Будет ли какой-то период времени, необходимый для того, чтобы цифровое считывание "осело" или что-то в этом роде?, @Marc

Проблема заключалась в том, что buttonState никогда не инициализировался в примерах сценариев, поэтому он начинается != с чтения, таким образом, срабатывая, как только таймер превышает задержку отмены. Я смог исправить это, просто инициализировав значение так, чтобы оно совпадало со значением lastButtonState., @Marc

На самом деле я не обращал особого внимания на этот вопрос; я просто заметил, что вы решили свою собственную проблему. Если то, что вы написали выше, является ответом, который следует из информации в вопросе, и вы думаете, что все это будет полезно кому-то еще, вы можете опубликовать свой собственный ответ на него. В противном случае вопрос, скорее всего, навсегда останется в системе без ответа, если вы его не удалите., @timemage


2 ответа


Лучший ответ:

1

Вам нужно инициализировать buttonState до текущего состояния сигнала и инициализировать lastDebounceTime до текущего времени, что-то вроде этого:

int buttonState = digitalRead(buttonPin);
unsigned long lastDebounceTime = millis();

Сравните с этим очень простым дебоунсером, который я поставил на GitHub.

,

Вы абсолютно правы! Я не уверен, почему я этого не уловил или почему скетч Arduino не инициализирует переменные., @Marc


1

Инициализация моего buttonState решила мою проблему:

int buttonState = LOW;    
,

В любом случае имейте в виду, что последовательная запись приостанавливает работу микроконтроллера на несколько миллисекунд!, @alessandromrc

@alessandromrc: На несколько микросекунд. Если буфер TX не заполнен, в этом случае он действительно может занять миллисекунды., @Edgar Bonet

@EdgarBonet Ты прав!, @alessandromrc