0

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); 
}
asked Jan 25, 2020 at 17:45
2
  • @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 given Commented Jan 25, 2020 at 18:06
  • connect the buzzer to a battery ... does it make a sound? Commented Jan 25, 2020 at 18:33

1 Answer 1

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.

answered Jan 25, 2020 at 18:13
1
  • Took it out of the interrupt handler and it worked. Thanks Commented Jan 25, 2020 at 19:13

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.