0

My problem lies in the fact that I can not stop the "void loop" function and more accurately "StatInDoor". I have to make sure that the "ButtonOpenDoor" works independently of "ButtonCall". If someone presses the "ButtonCall" button then the "ButtonOpenDoor" button must work in progress, and if the "ButtonCall" button is pressed, the "ButtonOpenDoor" button must stop playing the melody.

My idea for this this:

int StatOutDoor = digitalRead(ButtonCall && ButtonOpenDoor);

or:

if(StatOutDoor == LOW && StatInDoor = LOW){
   PlayMelody();
}

But it does not work :(

Full code:

#include "pitches.h"

int melody[] = {
  NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};
int noteDurations[] = {
  4, 8, 8, 4, 4, 4, 4, 4
};
int ButtonCall = 4;
int buzzer = 8;
int ButtonOpenDoor = 7;
int RelayModule = 12;

void PlayMelody() {
  for (int thisNote = 0; thisNote < 8; thisNote++) {
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(buzzer, melody[thisNote], noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(buzzer);
  }
}

void setup(){
  pinMode(ButtonCall, INPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(ButtonOpenDoor,INPUT);
  pinMode(RelayModule,OUTPUT);
}

void loop() {
  int StatOutDoor = digitalRead(ButtonCall); 
  if(StatOutDoor == LOW){
    PlayMelody();    
  }  
  int StatInDoor = digitalRead(ButtonOpenDoor);
  if (StatInDoor == HIGH) {
    digitalWrite(RelayModule, HIGH);
  } else {
    digitalWrite(RelayModule, LOW);
    delay(3300);
  }
}

Can someone help with this? (Sorry for my bad English).

8
  • && is logical AND. & is Bitwise AND. Use the right one, it might help.
    – Majenko
    Jun 11 '17 at 16:39
  • Unfortunately both methods do not work
    – zuczek
    Jun 11 '17 at 16:41
  • Unfortunately I don't speak your language, and I find those variable names almost impossible to read. Please use English (or English-like) variable names (and function names) and ideally something to break up the words within them, such as camelCase.
    – Majenko
    Jun 11 '17 at 16:42
  • przyciskzadzwon=ButtonOutDoor ; przyciskotworz=ButtonInDoor ; przekaznik=RelayModule ; muzyczka=PlayMelody ; stanwew=StateInDoor ; stanzew=StateOutDoor
    – zuczek
    Jun 11 '17 at 16:48
  • 1
    That doesn't help me decipher a string of seemingly random consonants in my head...
    – Majenko
    Jun 11 '17 at 16:50
1

I'm not quite sure I understand the logic of what you're asking. Your description is a little vague. Maybe if you provided more information about what the signals are, what they mean, and where they come from, it may help.

However - if you want the melody to play when both inputs are LOW you should change:

if(StatOutDoor == LOW && StatInDoor = LOW){
      PlayMelody();    
} 

to:

if(StatOutDoor == LOW && StatInDoor == LOW){
      PlayMelody();    
} 

Note the use of == not = to denote equality (= is assignment).

Also the use of a 3.3 second delay in your else will show everything down to a crawl when StatInDoor is HIGH.

4
  • I want to make an intercom. There are two buttons - one to ring from the outside, the other to open from the inside. If outside someone pushed the call button and play the melody I want to open the door, for this moment problem is that I can only open when the melody is over. if(StatOutDoor == LOW && StatInDoor == LOW){ PlayMelody(); } not working too...
    – zuczek
    Jun 11 '17 at 18:16
  • Ah, I see. Well for that you need to rethink your entire program. You need to learn how to write non-blocking code. Start with the BlinkWithoutDelay example in the IDE.
    – Majenko
    Jun 11 '17 at 18:18
  • ohh... sure. How to transform it?
    – zuczek
    Jun 11 '17 at 19:16
  • State machine(s) and using millis() instead of delay().
    – Majenko
    Jun 11 '17 at 19:16
0

The Arduino doesn't multitask. So when you execute PlayMelody() the loop() function can't do anything else until the song ends.

You could use interrupts to play the song, but to keep things simple, here's a way to do it without interrupts.

// Struct to hold the song data (simpler than 2 arrays)
struct note {
    int pitch;
    int duration;
};

// Class to play songs
class song_player {
protected:
    note *melody;   // Array of all the notes
    int note_count;  // How many notes in song
    int current_note;
    bool am_playing;  // Playing song?
    unsigned long last_event;  // Time of last note
    unsigned long next_event;  // Time to play next note
    byte speaker_pin;

    // is it time to play the next note?
    bool elapsed()
    {
        unsigned long m = millis();
        if (m >= next_event) {
            last_event = m;
            return true;
        }
        return false;
    }

    // play one note
    void play_next_note() {
        if (elapsed()) {
            // Play next note unless at end of song
            if (current_note < note_count) {
                unsigned long duration = 1000 / melody[current_note].duration;
                tone(speaker_pin, melody[current_note].pitch, duration);
                next_event = millis() +  1.3 * duration;
                current_note += 1;
            }
            else {
                // Finished...
                noTone(speaker_pin);
                am_playing = false;
            }
        }
    }
public:
    // ctor
    song_player(byte speaker_pin, note *melody, int note_count) :
        am_playing(false),
        speaker_pin(speaker_pin),
        note_count(note_count),
        melody(melody)
    {
        // Note: does not make local copy, so array should be
        // valid for lifetime of this object
    }

    // Start the song
    void start() {
        // Initialize
        current_note = 0;
        am_playing = true;
        last_event = millis();
    }

    // Call this every loop()
    void loop() {
        if (am_playing) {
            play_next_note();
        }
    }
};

Then you would change the rest of the program to something like:

// Song data
note the_song[] = {
  {NOTE_C4, 4},
  {NOTE_G3, 8},
  {NOTE_G3, 8},
  {NOTE_A3, 4},
  {NOTE_G3, 4},
  {0, 4},
  {NOTE_B3, 4},
  {NOTE_C4, 4}
};
// Create a player object
song_player player(9, the_song, sizeof(the_song) / sizeof(the_song[0]));

//....

void loop()
{
    // other stuff .....

    if(StatOutDoor == LOW && StatInDoor == LOW) {
        // Start the song
        player.start();
    }
    // Important: Call this every time
    player.loop();

    // Other stuff here....
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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