0

希望有人能看到我缺少的东西,因为它必须就在那里盯着我的脸..

我在 ESP32 上设置了这段代码(如下),以生成一个线程,该线程仅监视连接到开关的引脚的状态。本质上,这段代码应该等待按钮被按住 3 秒钟,然后做一些重要的事情。实际输入似乎读得很好,但由于某种原因,一旦我按下按钮,按钮状态在取消按下开关后会卡住 15 秒。

例如,

  1. 按下开关,实际的 BtnState 读数为 1,buttonState 读数为 1(50us 后),btnPressTime 按预期递增。
  2. 释放开关,actualBtnState 读取 0,btnState 读取 1,btnPressTime 停止递增。
  3. 50us 后,期望看到 btnState 读取 0,然后触发 else 或 elseif 块(取决于按住按钮的时间)。实际结果继续显示 btnState = 1 和 btnPressTime = [无论上次保持时间是什么] 持续 15 秒或更长时间。actuyalBtnState 在整个时间内正确读取为 0 并且由于某种原因 lastDebounceTime 不断增加?

我应该注意到这是一个更大的项目的一部分,因此是线程。我似乎也无法在 resetBtnCB 函数中打印任何内容,因为我立即收到“guru mediation error kernel panicwhat-the-error-is”错误并且 esp 重新启动。

代码:

#include <Arduino.h>
#define BUTTON_PIN 27

// Variables will change:
int buttonState;           // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin

unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50;   // the debounce time; increase if the output flickers
unsigned long buttonPressTime = 0; //Amount of time the button has been held down
unsigned long actualBtnState = 0; //The actual reading from the pin without noise filtering

void resetBtnCB(void *pvParameters)
{
  pinMode(BUTTON_PIN, INPUT);

  while (true)
  {
    // read the state of the switch into a local variable:
    int reading = digitalRead(BUTTON_PIN);
    actualBtnState = reading;

    // If the switch changed, due to noise or pressing:
    if (reading != lastButtonState)
    {
      // reset the debouncing timer
      lastDebounceTime = millis();
    }

    unsigned long timeSinceDebounce = millis() - lastDebounceTime;
    if (timeSinceDebounce > debounceDelay)
    {
      // whatever the reading is at, it's been there for longer than the debounce
      // delay, so take it as the actual current state:
      buttonState = reading;

      if (buttonState == HIGH)
      {
        buttonPressTime += timeSinceDebounce;
      }
      else if (buttonPressTime > 300)
      {
        buttonPressTime = 0;
        // SUCCESS! Do something important here as we've held the button for x seconds
      }
      else
      {
        buttonPressTime = 0;
      }
    }

    // save the reading. Next time through the loop, it'll be the lastButtonState:
    lastButtonState = reading;
    vTaskDelay(10);
  }
}

void setup()
{
  Serial.begin(115200);
  xTaskCreate(resetBtnCB, "reset_button", 1024, NULL, 10, NULL);
}

void loop()
{
  char debug[512];
  sprintf(debug, "button state %u, lastD %u, buttonPressTime %u, actualBtnState %u, lastBtnState %u", buttonState, lastDebounceTime, buttonPressTime, actualBtnState, lastButtonState);
  Serial.println(debug);
  delay(50);
  yield();
}
4

0 回答 0