ARDUINO 蜂鸣器在不该发出声音时发出声音

ARDUINO Buzzer playing sound when it shouldn't

所以我制作了这种 temperature/humidity 传感器并决定添加火灾传感器功能。所以一切正常,对吧?不,我还决定我想要一个蜂鸣器。测试了它,效果很好,所以我把它扔进了我的项目。 启动它 [项目],点亮打火机,工作正常,LED 闪烁,显示文本,蜂鸣器发出警报。但是,在火熄灭后,即使没有火,蜂鸣器仍会继续播放两种音调中的一种。这是代码,让一切都清楚:

#include <LiquidCrystal.h>
#include <dht.h>

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
dht DHT;

#define FLAME 13
#define DHT11_PIN 8
#define ALARM A5
const int a9 = 9, a10 = 10, a11 = 11, a12 = 12;

byte z[8] = {
  B00100,
  B00000,
  B11111,
  B00001,
  B00010,
  B00100,
  B11111,
  B00000,
};

byte st[8] = {
  0b00110,
  0b01001,
  0b01001,
  0b00110,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
};

void setup(){
  lcd.begin(16, 2);
  lcd.createChar(0, st);
  lcd.createChar(1, z);
  Serial.begin(9600);
  pinMode((a9, a10, a11, a12), OUTPUT);
  pinMode(FLAME, INPUT);
  pinMode(ALARM, OUTPUT);
}

void loop() {
    // Flame sensor code for Robojax.com

  int fire = digitalRead(FLAME);// read FLAME sensor

  if(fire == HIGH)
  {
    analogWrite(a9, 255);
    analogWrite(a10, 255);
    lcd.setCursor(5, 0);
    lcd.print("Po");
    lcd.print(char(1));
    lcd.print("ar!");
    tone(ALARM, 4300);
    delay(150);
    analogWrite(a9, 0);
    analogWrite(a10, 0);
    lcd.clear();
    tone(ALARM, 3500);
    delay(150);
  } else {
    lcd.createChar(0, st);
    int chk = DHT.read11(DHT11_PIN);
    lcd.home();
    lcd.print("Temp.: ");
    lcd.print(DHT.temperature);
    if(DHT.temperature >= 20.00 && DHT.temperature < 25) {
      analogWrite(a11, 255);
      delay(750);
      analogWrite(a11, 0);  
      delay(750);
    } else if(DHT.temperature >= 25 && DHT.temperature < 30) {
      analogWrite(a10, 255);
      delay(250);
      analogWrite(a10, 0);
      delay(250);
    } else if(DHT.temperature >= 30) {
      analogWrite(a9, 255);
    }
    lcd.print(char(0));
    lcd.print("C");
    lcd.setCursor(0, 1);
    lcd.print("Wilg.: ");
    lcd.print(DHT.humidity);
    if(DHT.humidity >= 45.00 && DHT.humidity < 60.00) {
      digitalWrite(a12, HIGH);
      delay(250);
      digitalWrite(a12, LOW);
      delay(250);
    } else if(DHT.humidity >= 60.00) {
      digitalWrite(a12, HIGH);
    }
    lcd.print(" %");
    delay(750);

  }



  delay(200);
}

所以,我的意思是,即使 fireHIGH 更改为 LOW等其他部分代码执行完毕,蜂鸣器继续播放。 我做错了什么?

勾选 documentation for tone:

A duration can be specified, otherwise the wave continues until a call to noTone().

因此,在检查传感器的值(或在 LOW 分支上显式调用 notone)之前,您可能需要在开始的每个循环中重置音调,或者使用 [= 的 3-arg 版本10=].

不过,我不知道 tonedelay 会如何相互作用。

我可能会将实际的音调作为自己的任务。这个想法是您将启动警报任务,然后在适当的时候重置它。但是现在请确保在每个循环开始时重置您的状态,或者如果任务听起来太高级,则每个分支都会显式重置它必须重置的任何内容。

确保您学习了 Arduino 世界中的基本 "print" 调试。可以在 IDE 上阅读的简单 write logging to the serial port 非常宝贵。

最后:使用函数!如果你把所有东西都放在 loop 中,你的程序将随着它们的增长而变得不可读。例如,如果你有一些状态你想每次都重置(例如,运行 任务,如音调、值、标志)然后创建一个 init() 函数,loop 首先调用所以任何给定的循环具有良好的起始状态。