Поведение tone() не соответствует ожидаемому в цикле while

У меня есть детектор дыма с пьезоизлучателем. Я хочу использовать Arduino в режиме пониженного энергопотребления, чтобы он работал от батареи 9 В. Я подключил прерывание, и когда цифровой выход датчика MQ-2 становится высоким, он переключается на функцию мониторинга.

В цикле while я проверяю, достиг ли аналоговый датчик порогового значения, и вывожу в последовательный порт, чтобы убедиться, что я нахожусь в условном выражении. Если я использую:

digitalWrite(buzzer, HIGH);

затем звучит пьезо, но если я использую

tone(buzzer, 1000,200);
delay(200);

это не так. Я не понимаю, почему это так.

Полный код выглядит следующим образом:

#include "LowPower.h"

int redLed = 12;
int greenLed = 11;
int buzzer = 10;
int smokeA0 = A5;
// Ваше пороговое значение
int sensorThres = 50;
int smokeD0 = 2;

void setup() {
  pinMode(redLed, OUTPUT);
  digitalWrite(redLed, LOW);
  pinMode(greenLed, OUTPUT);
  digitalWrite(greenLed, HIGH);
  pinMode(buzzer, OUTPUT);
  pinMode(smokeA0, INPUT);
  pinMode(smokeD0, INPUT);


}
void switchToMonitor() {
  Serial.begin(9600);
  int digitalSensor = digitalRead(smokeD0);
  if (digitalRead(smokeD0) == HIGH)
  {
    digitalWrite(redLed, HIGH);
    digitalWrite(greenLed, LOW);
  }
  else {
    digitalWrite(redLed, LOW);
    digitalWrite(greenLed, HIGH);
  }
  //Это будет обновлено позже, чтобы использовать аналоговый вход
  // Использование цифровых технологий для облегчения отладки
  while (digitalSensor == HIGH) {
    int analogSensor = analogRead(smokeA0);
    Serial.print("Pin A0: ");
    Serial.println(analogSensor);
    Serial.print("Pin D0: ");
    Serial.println(digitalSensor);
    // Проверяем, достиг ли он порогового значения
    if (analogSensor > sensorThres) {
      digitalWrite(buzzer, HIGH);
      // тон (зуммер, 1000,200);
      Serial.println("here");
      delay(1000);
    }
    else {
// digitalWrite(redLed, LOW);
// digitalWrite(greenLed, HIGH);
      noTone(buzzer);
      Serial.println("also here?");
    }
    // задержка (100);
    digitalSensor = digitalRead(smokeD0);
  }
  noTone(buzzer); 
}

void loop() {
  // задержка (100);
  //Низкая мощность.ожидание();
  attachInterrupt(0, switchToMonitor, CHANGE);
  LowPower.powerDown(SLEEP_FOREVER, ADC_ON, BOD_ON); 
  detachInterrupt(0); 
}

, 👍0

Обсуждение

@Juraj Функция тона работает, когда используется в цикле void() и не переключается между режимом малой мощности и режимом работы. Это не работает только в приведенном примере кода, @David Bekker

подключите зуммер к аккумулятору... он издает звук?, @jsotola


1 ответ


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

1

Вы не можете использовать функцию delay() или функцию tone() на основе таймера в обработчике прерывания. Установите флаг в прерывании и запустите код в цикле () условно на основе состояния флага. Не забудьте сделать переменную флага volatile.

,

Вынул из обработчика прерываний и все заработало. Спасибо, @David Bekker