Проблема с переключателем устранения дребезга

Я пытаюсь использовать LDR для контроля уровня освещенности, и если LDR закрыт и нажата кнопка, светодиод должен включиться. Я нахожусь в процессе добавления дебуширования, но каждый раз, когда я запускаю код, он входит в часть if (val > 421), светодиод горит, но кнопка не нажата, и код останавливается.

Я подозреваю, что это может быть логическая проблема с состояниями. Я использую функцию millis для устранения дребезга, поэтому код должен игнорировать первые 200 мс после нажатия кнопки. Я просто помогаю в отношении устранения дребезга, поэтому, когда LDR закрыт и нажат переключатель, светодиод должен включиться.

Код показан ниже:

const int buttonPin = 8;
const int ldrPin = 0;
const int LEDPin = 13;

boolean buttonState = 0;
boolean NEWbuttonState = 0;
boolean LEDState = 0;
int bounce_time = 200;
unsigned long my_time;

boolean on;

int val = 0;

void showValue(float myval)
{
  Serial.print(myval);
  Serial.print(" lightstatus ");
  Serial.println(LEDState);
}

void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(LEDPin, INPUT_PULLUP);
  on = false;
  analogReference(DEFAULT);
  pinMode(ldrPin, INPUT);
  Serial.begin(9600);
  my_time = millis();
}

void loop()
{

  val = analogRead(ldrPin);

  NEWbuttonState = digitalRead(buttonPin);


  if ((millis() - my_time) > bounce_time)
  {
    digitalWrite(LEDPin, LOW);


    if (buttonState != NEWbuttonState)
    {
      buttonState = NEWbuttonState;

      //if button is pressed
      if (NEWbuttonState == 1 && LEDState == 0)
      {
        buttonState = NEWbuttonState;

        if (val > 421)
        {
          my_time = millis();

          digitalWrite(LEDPin, 1);
          LEDState = 1;
          showValue(val);
          Serial.print("button press");
        }

        if (val < 420)
        {
          my_time = millis();

          digitalWrite(LEDPin, 0);
          LEDState = 0;
          showValue(val);
        }
        buttonState = 1;
      }
      else
      {
        if (NEWbuttonState == 0)
        {
          buttonState = 0;

        }
      }
    }
  }
}

, 👍0

Обсуждение

Найдите библиотеку Bounce2 в диспетчере библиотек IDE., @VE7JRO

вы описали что должно происходить при нажатии на кнопку, но забыли сказать что должно происходить при отпускании кнопки, @jsotola

Если ваш Arduino — это uno, nano или аналогичный, const int ldrPin = 0; конфликтует с Serial. Или, если он предназначен для аналогового чтения, вам следует избегать pinMode(ldrPin, INPUT); Лучше использовать const byte ldrPin = A0;, @DataFiddler

Пожалуйста, покажите нам, как вы подключили LDR к Arduino., @VE7JRO


1 ответ


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

0

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

Итак, для вашей задачи вам не нужно никакого устранения дребезга.

В описании или вашей задаче отсутствует то, что должно произойти, "если нет". Я предполагаю, что светодиод должен светиться, пока нажаты обе кнопки и ldr закрыт. Если какая-либо кнопка не нажата или горит индикатор ldr, индикатор должен оставаться выключенным.

Это слишком просто:

void loop() {
  bool ldrDark = analogRead(A0) < MAX_LDRBRIGHT;  
  digitalWrite(led, ldrDark && digitalRead(buttonPin));
}  

Добавить задержку (светодиод загорается только при нажатии кнопки некоторое время) также легко.

const byte LED = LED_BUILTIN; // 13 на УНО

const byte BUTTON = 8;  // Кнопка подключается к GND
const byte PRESSED = LOW; // из-за INPUT_PULLUP
const int DELAY = 300; // РС
bool btnState; // true = HIGH при нажатии

const byte LDR = A0; // LDR на 5 В, резистор на GND: низкие значения в темноте
const int MIN_LDRBRIGHT= 420; // зависит от резистора и LDR

void setup() {
   pinMode (LED, OUTPUT);
   pinMode (BUTTON, INPUT_PULLUP);
}

void loop() {
  static unsigned long lastOpen;
  if (digitalRead(BUTTON) == PRESSED) {
    if (millis() - lastOpen > DELAY)  
      btnState = HIGH;
    else btnState = LOW;
  } else {
      lastOpen = millis(); // чтобы запомнить последний момент, когда кнопка была отпущена
      btnState = LOW; 
  }

  bool ldrDark = analogRead(A0) < MIN_LDRBRIGHT;

  digitalWrite(LED, ldrDark && btnState);
}  
,

Вы должны увидеть, что светодиод следует за закрытым ldr (пока кнопка остается нажатой) быстрее, чем меняется кнопка. Если это цель этого упражнения., @DataFiddler