0

I am trying to play a tone with a buzzer connected on an arduino nano pin. I have also connected a reed switch with INPUT_PULLUP on INT0 and a led. The program loops continuously (it's an environmental monitor and alarm personal project) until the reed switch is set on HIGH where a function is called and the buzzer should play an one-second high pitch tone.

void doorStateChange() {
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  if (interrupt_time - last_interrupt_time > 1000)
  {
    led_B_state   = !led_B_state;
    digitalWrite(buzzPin, HIGH);
    digitalWrite(led_A_Pin, HIGH);

    if (millis() - interrupt_time <= 1000 ){
        digitalWrite(buzzPin, LOW);
        digitalWrite(led_A_Pin, LOW);
    }

  }
  last_interrupt_time = interrupt_time;
}

The interrupt is called, the Led lights up but I can't make the buzzer sound right. I 've tried with tone(buzzPin, 5000, 1000); but seems that the delay does not work - The sound is heard but after the 1000ms it continuous to work in a different tone (strange?).

The only way I could make it work is with buzzPin_state = ! buzzPin_state; where the buzzer beeps as long as the reed switch is HIGH.

I also need to say that attachInterrupt(0, doorStateChange, CHANGE);.

The information I get from googling this issue is gibberish: some say that delays don't run in interrupts, others call external functions etc.

What is the proper way to achieve this ?

8
  • Can you give a more detailed description about what you expect and what is happening with this code? You just want to pull the buzzer pin to high on a rising edge (when the input pin goes from low to high)? Commented Apr 4, 2015 at 19:06
  • I want to pull the buzzer pin to high on CHANGE for one second.
    – Radolino
    Commented Apr 4, 2015 at 19:13
  • But you don't need tone() then, correct? (Rising/change/falling are really irrelevant in this case) Commented Apr 4, 2015 at 19:14
  • I wanted to hear a high pitch tone rather than the default buzzer (beep) one.
    – Radolino
    Commented Apr 4, 2015 at 19:15
  • But that's not only the point. I can't make it to delay the tone for one second. Only way it works is if the state changes inside the interrupt function which means the sound lasts as much as the reed switch pin is high.
    – Radolino
    Commented Apr 4, 2015 at 19:25

1 Answer 1

4

Don't do delay() calls inside an ISR. In all probability it will hang indefinitely. If you want to play the tone for a second all you need to do in the ISR is set a flag, which you test in the main loop. Turn the buzzer on when the flag changes state. Remember when you did that. When a second is up turn the buzzer off again.

In fact in your case you probably don't need the interrupt at all. Test for the reed switch change in the main loop as well. Don't overcomplicate it.

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.