I have a smoke detector with a piezo buzzer. I want to operate the arduino in low power mode so that it will last on a 9V battery. I've attached an interrupt, and when the digital output of the MQ-2 sensor goes high, it switches to a monitor function.
In the while loop, I check to see if the analog sensor has reached the threshold value, and I output to serial to see if I am in the conditional. If I use:
digitalWrite(buzzer, HIGH);
then the piezo sounds, however if I use
tone(buzzer, 1000,200);
delay(200);
it does not. I'm confused as to why this would be the case.
Full code as follows:
#include "LowPower.h"
int redLed = 12;
int greenLed = 11;
int buzzer = 10;
int smokeA0 = A5;
// Your threshold value
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);
}
//This will be updated later to use the analog input
//Using digital to make debugging easier
while (digitalSensor == HIGH) {
int analogSensor = analogRead(smokeA0);
Serial.print("Pin A0: ");
Serial.println(analogSensor);
Serial.print("Pin D0: ");
Serial.println(digitalSensor);
// Checks if it has reached the threshold value
if (analogSensor > sensorThres) {
digitalWrite(buzzer, HIGH);
//tone(buzzer, 1000,200);
Serial.println("here");
delay(1000);
}
else {
// digitalWrite(redLed, LOW);
// digitalWrite(greenLed, HIGH);
noTone(buzzer);
Serial.println("also here?");
}
//delay(100);
digitalSensor = digitalRead(smokeD0);
}
noTone(buzzer);
}
void loop() {
//delay(100);
//LowPower.standby();
attachInterrupt(0, switchToMonitor, CHANGE);
LowPower.powerDown(SLEEP_FOREVER, ADC_ON, BOD_ON);
detachInterrupt(0);
}
-
@Juraj The tone function works when used within void loop() and not switching between low power and operational. It's only not working in the code example givenDavid Bekker– David Bekker01/25/2020 18:06:01Commented Jan 25, 2020 at 18:06
-
connect the buzzer to a battery ... does it make a sound?jsotola– jsotola01/25/2020 18:33:00Commented Jan 25, 2020 at 18:33
1 Answer 1
You can't use delay() or timer based tone() function in interrupt handler. Set a flag in interrupt and run the code in loop() conditionally based on the flag state. Do not forget to have the flag variable volatile.
-
Took it out of the interrupt handler and it worked. ThanksDavid Bekker– David Bekker01/25/2020 19:13:18Commented Jan 25, 2020 at 19:13