0

誰かが私が欠けているものを見ることができることを願っています.

スイッチに接続されたピンの状態を単に監視するスレッドを生成するために、ESP32 にこのコード (以下) をセットアップしました。基本的に、このコードは、ボタンが 3 秒間保持されるのを待ってから、重要な処理を行うことになっています。実際の入力は問題ないように見えますが、何らかの理由でボタンを押すと、スイッチを離した後、ボタンの状態が 15 秒間スタックします。

例えば、

  1. スイッチを押すと、actualBtnState が 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 panic anything-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