Using sensor to play a sequence

Hello to all.
I'm using an SRF02 to begin a musical sequence that is sent to another arduino. My issue currently is that when the sensor picks up an object between the two set distances, it plays the entire sequence 3 times before stopping. Why is it playing through specifically 3 times and not just once?
What I would like is that the sequence plays through only once before stopping. Any help would be appreciated :slightly_smiling_face:

#include "Wire.h"
#include "SRF02.h"

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

SRF02 sensor(0x70, SRF02_CENTIMETERS);



// Two things need to be created: the array for the notes of the melody (in order)
// and the duration of each (think of it like sheet music in two parts)

// BOTH ARRAYS MUST BE THE SAME SIZE!

// The melody array
int melody[] = {
  //intro glockenspiel

  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,

  // drum saw canjo

  60, 65, 62, 60, 94, 62, 64, 69, //60, 64, 62, 60, 64, 62, 64, 69,
  60, 91, 62, 64, 60, 89, 62, 64, //60, 64, 62, 64, 60, 64, 62, 64,
  60, 87, 62, 60, 64, 84, 64, 69, //60, 64, 62, 60, 64, 62, 64, 69,
  60, 64, 62, 82, 60, 64, 79, 64, //60, 64, 62, 64, 60, 64, 62, 64,

  // glockenshpiel
  94, 91, 89, 91, 94, 91, 89, 87, //94, 91, 89, 91, 94, 91, 89, 87,
  94, 91, 89, 91, 94, 91, 89, 87, //94, 91, 89, 91, 94, 91, 89, 87,

  84, 87, 89, 91, 84, 87, 89, 91, //84, 87, 89, 91, 84, 87, 89, 91,
  84, 87, 89, 91, 94, 91, 89, 87, //84, 87, 89, 91, 94, 91, 89, 87,

  84, 62, 64, 82, 79, 82, 84, 60, //84, 87, 84, 82, 79, 82, 84, 87,
  84, 62, 64, 82, 79, 82, 79, 77, //84, 87, 84, 82, 79, 82, 79, 77,
  84, 62, 64, 82, 79, 82, 79, 77, //84, 87, 84, 82, 79, 82, 79, 77,
  60, 72, 75, 77, 79, 82, 84, 87, //75, 72, 75, 94, 91, 89, 87, 84,

  72, 75, 77, 79, 82, 84, 87, 89, //72, 75, 77, 79, 82, 84, 87, 89,
  91, 94, 91, 89, 87, 84, 82, 79, //91, 94, 91, 89, 87, 84, 82, 79,
  77, 75, 72, 75, 77, 79, 82, 84, //77, 75, 72, 75, 77, 79, 82, 84,
  87, 60, 91, 94, 60, 94, 91, 60, //87, 89, 91, 94, 91, 94, 91, 94,
  91, 60, 91, 94, 60, 94, 91, 60,  //91, 94, 91, 94, 91, 94, 91, 94,
  91, 94, 91, 94, 91, 94, 91, 94

};

// The note duration, 8 = 8th note, 4 = quarter note, etc.
int durations[] = {
  // intro glockenspiel
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,


  // drum saw canjo
  16, 16, 16, 16, 16, 16, 16, 16,
  8, 8, 8, 16, 16, 16, 16, 8,
  16, 16, 8, 8, 16, 16, 8, 8,
  16, 16, 16, 16, 16, 16, 16, 16,

  // glockenspiel
  8, 8,  8, 8, 8, 8, 8, 8,
  8, 5, 16, 8, 8, 8, 8, 8,

  8, 5, 16, 8, 8, 8, 8, 8,
  8, 5, 16, 8, 8, 8, 8, 8,

  8, 5, 16, 8, 16, 16, 16, 16,
  8, 5, 16, 8, 16, 16, 16, 16,
  8, 5, 16, 8, 16, 16, 16, 16,
  8, 8,  8, 8, 8, 8, 8, 8,

  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  32, 32, 32, 32, 32, 32, 32, 32



};
// determine the length of the arrays to use in the loop iteration
int songLength = sizeof(melody) / sizeof(melody[0]);
void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);
  Wire.begin();
}

void loop() {
  int sensorReading = (sensor.read()); //readData(sensor.read());
  SRF02::update();
  if ((sensorReading > 25) && (sensorReading < 100))

  {
    // Iterate through both arrays
    // Notice how the iteration variable thisNote is created in the parenthesis
    // The for loop stops when it is equal to the size of the melody array
    for (int thisNote = 0; thisNote < songLength; thisNote++) {
      // determine the duration of the notes that the computer understands
      // divide 1000 by the value, so the first note lasts for 1000/8 milliseconds
      int duration = 1000 / durations[thisNote];
      MIDI.sendNoteOn(melody[thisNote], 127, 1);
      // pause between notes
      int pause = duration * 4; //1.8
      delay(pause);
      // stop the note
      MIDI.sendNoteOff(melody[thisNote], 0, 1);

    }
  }
}

Presumably after the melody has been played, the sensor can still see something.

Put some serial prints in to prove it.

Inside loop, you need to call

SRF02.update();

before you take your readings.

You can also save a lot of space by making your arrays byte vs. int

I cannot see a reason why it would stop after 3 times. I would expect it to repeat forever while the object is between those distances.

Why would it do that? There is nothing in your code to stop it after one play. Remember, loop() gets called over and over until power is disconnected or reset is pressed. If the object is still in that range, it will play again and again.

If you want it to play once only, you need your code to detect when the object first enters that range, meaning it is in that range now but was not in that range when it was previously checked.

Thanks for those suggestions. I realise that I need to detect when the object enters range but was unsure how to code that. I have some code from a previous capacitance sensor project that I've tried but now the sequence plays through once and won't trigger again. Does it need tweaking or should I take a different approach code wise?

#include "Wire.h"
#include "SRF02.h"

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

SRF02 sensor(0x70, SRF02_CENTIMETERS);



// Two things need to be created: the array for the notes of the melody (in order)
// and the duration of each (think of it like sheet music in two parts)

// BOTH ARRAYS MUST BE THE SAME SIZE!

// The melody array
int melody[] = {
  //intro glockenspiel

  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,

  // drum saw canjo

  60, 65, 62, 60, 94, 62, 64, 69, //60, 64, 62, 60, 64, 62, 64, 69,
  60, 91, 62, 64, 60, 89, 62, 64, //60, 64, 62, 64, 60, 64, 62, 64,
  60, 87, 62, 60, 64, 84, 64, 69, //60, 64, 62, 60, 64, 62, 64, 69,
  60, 64, 62, 82, 60, 64, 79, 64, //60, 64, 62, 64, 60, 64, 62, 64,

  // glockenshpiel
  94, 91, 89, 91, 94, 91, 89, 87, //94, 91, 89, 91, 94, 91, 89, 87,
  94, 91, 89, 91, 94, 91, 89, 87, //94, 91, 89, 91, 94, 91, 89, 87,

  84, 87, 89, 91, 84, 87, 89, 91, //84, 87, 89, 91, 84, 87, 89, 91,
  84, 87, 89, 91, 94, 91, 89, 87, //84, 87, 89, 91, 94, 91, 89, 87,

  84, 62, 64, 82, 79, 82, 84, 60, //84, 87, 84, 82, 79, 82, 84, 87,
  84, 62, 64, 82, 79, 82, 79, 77, //84, 87, 84, 82, 79, 82, 79, 77,
  84, 62, 64, 82, 79, 82, 79, 77, //84, 87, 84, 82, 79, 82, 79, 77,
  60, 72, 75, 77, 79, 82, 84, 87, //75, 72, 75, 94, 91, 89, 87, 84,

  72, 75, 77, 79, 82, 84, 87, 89, //72, 75, 77, 79, 82, 84, 87, 89,
  91, 94, 91, 89, 87, 84, 82, 79, //91, 94, 91, 89, 87, 84, 82, 79,
  77, 75, 72, 75, 77, 79, 82, 84, //77, 75, 72, 75, 77, 79, 82, 84,
  87, 60, 91, 94, 60, 94, 91, 60, //87, 89, 91, 94, 91, 94, 91, 94,
  91, 60, 91, 94, 60, 94, 91, 60,  //91, 94, 91, 94, 91, 94, 91, 94,
  91, 94, 91, 94, 91, 94, 91, 94

};

// The note duration, 8 = 8th note, 4 = quarter note, etc.
int durations[] = {
  // intro glockenspiel
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,


  // drum saw canjo
  16, 16, 16, 16, 16, 16, 16, 16,
  8, 8, 8, 16, 16, 16, 16, 8,
  16, 16, 8, 8, 16, 16, 8, 8,
  16, 16, 16, 16, 16, 16, 16, 16,

  // glockenspiel
  8, 8,  8, 8, 8, 8, 8, 8,
  8, 5, 16, 8, 8, 8, 8, 8,

  8, 5, 16, 8, 8, 8, 8, 8,
  8, 5, 16, 8, 8, 8, 8, 8,

  8, 5, 16, 8, 16, 16, 16, 16,
  8, 5, 16, 8, 16, 16, 16, 16,
  8, 5, 16, 8, 16, 16, 16, 16,
  8, 8,  8, 8, 8, 8, 8, 8,

  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  32, 32, 32, 32, 32, 32, 32, 32



};
// determine the length of the arrays to use in the loop iteration
int songLength = sizeof(melody) / sizeof(melody[0]);
void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);
  Wire.begin();
}

void loop() {
  static boolean lastsensorReading = false;
  
  SRF02::update();
  int sensorReading = (sensor.read()); //readData(sensor.read());
  if ((sensorReading > 25) && (sensorReading < 100))

  if (sensorReading != lastsensorReading)

    if (sensorReading && !lastsensorReading)

  {
    // Iterate through both arrays
    // Notice how the iteration variable thisNote is created in the parenthesis
    // The for loop stops when it is equal to the size of the melody array
    for (int thisNote = 0; thisNote < songLength; thisNote++) {
      // determine the duration of the notes that the computer understands
      // divide 1000 by the value, so the first note lasts for 1000/8 milliseconds
      int duration = 1000 / durations[thisNote];
      MIDI.sendNoteOn(melody[thisNote], 127, 1);
      // pause between notes
      int pause = duration * 4; //1.8
      delay(pause);
      // stop the note
      MIDI.sendNoteOff(melody[thisNote], 0, 1);

    }
    lastsensorReading = sensorReading;
  }
}

Maybe something like this?

void loop() {
  static bool musicPlayed = false;
  
  SRF02::update();
  int sensorReading = sensor.read();

  if ((sensorReading > 25) && (sensorReading < 100)) {
    if (!musicPlayed) {
      // Iterate through both arrays
      ...
      musicPlayed = true;
      }
    }
  else {
    musicPlayed = false;
  }
}

Thanks PaulRB. I have implemented your code as I understand it but now the piece plays through twice. It's an improvement on three times. I only trigger the SRF02 with a hand movement, nothing is left in its path.
Could it be the way I've incorporated your code? curly braces etc?

#include "Wire.h"
#include "SRF02.h"

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

SRF02 sensor(0x70, SRF02_CENTIMETERS);



// Two things need to be created: the array for the notes of the melody (in order)
// and the duration of each (think of it like sheet music in two parts)

// BOTH ARRAYS MUST BE THE SAME SIZE!

// The melody array
int melody[] = {
  //intro glockenspiel

  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,

  // drum saw canjo

  60, 65, 62, 60, 94, 62, 64, 69, //60, 64, 62, 60, 64, 62, 64, 69,
  60, 91, 62, 64, 60, 89, 62, 64, //60, 64, 62, 64, 60, 64, 62, 64,
  60, 87, 62, 60, 64, 84, 64, 69, //60, 64, 62, 60, 64, 62, 64, 69,
  60, 64, 62, 82, 60, 64, 79, 64, //60, 64, 62, 64, 60, 64, 62, 64,

  // glockenshpiel
  94, 91, 89, 91, 94, 91, 89, 87, //94, 91, 89, 91, 94, 91, 89, 87,
  94, 91, 89, 91, 94, 91, 89, 87, //94, 91, 89, 91, 94, 91, 89, 87,

  84, 87, 89, 91, 84, 87, 89, 91, //84, 87, 89, 91, 84, 87, 89, 91,
  84, 87, 89, 91, 94, 91, 89, 87, //84, 87, 89, 91, 94, 91, 89, 87,

  84, 62, 64, 82, 79, 82, 84, 60, //84, 87, 84, 82, 79, 82, 84, 87,
  84, 62, 64, 82, 79, 82, 79, 77, //84, 87, 84, 82, 79, 82, 79, 77,
  84, 62, 64, 82, 79, 82, 79, 77, //84, 87, 84, 82, 79, 82, 79, 77,
  60, 72, 75, 77, 79, 82, 84, 87, //75, 72, 75, 94, 91, 89, 87, 84,

  72, 75, 77, 79, 82, 84, 87, 89, //72, 75, 77, 79, 82, 84, 87, 89,
  91, 94, 91, 89, 87, 84, 82, 79, //91, 94, 91, 89, 87, 84, 82, 79,
  77, 75, 72, 75, 77, 79, 82, 84, //77, 75, 72, 75, 77, 79, 82, 84,
  87, 60, 91, 94, 60, 94, 91, 60, //87, 89, 91, 94, 91, 94, 91, 94,
  91, 60, 91, 94, 60, 94, 91, 60,  //91, 94, 91, 94, 91, 94, 91, 94,
  91, 94, 91, 94, 91, 94, 91, 94

};

// The note duration, 8 = 8th note, 4 = quarter note, etc.
int durations[] = {
  // intro glockenspiel
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,


  // drum saw canjo
  16, 16, 16, 16, 16, 16, 16, 16,
  8, 8, 8, 16, 16, 16, 16, 8,
  16, 16, 8, 8, 16, 16, 8, 8,
  16, 16, 16, 16, 16, 16, 16, 16,

  // glockenspiel
  8, 8,  8, 8, 8, 8, 8, 8,
  8, 5, 16, 8, 8, 8, 8, 8,

  8, 5, 16, 8, 8, 8, 8, 8,
  8, 5, 16, 8, 8, 8, 8, 8,

  8, 5, 16, 8, 16, 16, 16, 16,
  8, 5, 16, 8, 16, 16, 16, 16,
  8, 5, 16, 8, 16, 16, 16, 16,
  8, 8,  8, 8, 8, 8, 8, 8,

  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  32, 32, 32, 32, 32, 32, 32, 32



};
// determine the length of the arrays to use in the loop iteration
int songLength = sizeof(melody) / sizeof(melody[0]);
void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);
  Wire.begin();
}

void loop() {
 
   static bool musicPlayed = false;
  
  SRF02::update();
  int sensorReading = sensor.read();

  if ((sensorReading > 25) && (sensorReading < 100)) {
    if (!musicPlayed)
  

  {
    // Iterate through both arrays
    // Notice how the iteration variable thisNote is created in the parenthesis
    // The for loop stops when it is equal to the size of the melody array
    for (int thisNote = 0; thisNote < songLength; thisNote++) {
      // determine the duration of the notes that the computer understands
      // divide 1000 by the value, so the first note lasts for 1000/8 milliseconds
      int duration = 1000 / durations[thisNote];
      MIDI.sendNoteOn(melody[thisNote], 127, 1);
      // pause between notes
      int pause = duration * 4; //1.8
      delay(pause);
      // stop the note
      MIDI.sendNoteOff(melody[thisNote], 0, 1);
      
    musicPlayed = true;
      }
    }
  else {
    musicPlayed = false;
  }
}
}

Could be. Hard to tell because the indentation in your code is a mess. Click Tools->Auto Format in the IDE to fix that and re-post.

EDIT: yeah, pretty sure one of those } at the end of the sketch should be higher up, maybe before the line musicPlayed = true;. If you look at my suggested code from post #6, there were 2 } at the end, but your version has 3.

Here's a good tip. In the IDE, if you put your cursor just after a }, the corresponding { gets highlighted. Same for } and any other kind of braces ( [

Wonderful stuff PaulRB!
The offending curly brace was the one just after

Leaving only the last two at the end of the code needed.
Now plays once through before stopping as needed!
Thanks immensely!

#include "Wire.h"
#include "SRF02.h"

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

SRF02 sensor(0x70, SRF02_CENTIMETERS);



// Two things need to be created: the array for the notes of the melody (in order)
// and the duration of each (think of it like sheet music in two parts)

// BOTH ARRAYS MUST BE THE SAME SIZE!

// The melody array
int melody[] = {
  //intro glockenspiel

  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,
  91, 94, 91, 94, 72, 75, 72, 75,

  // drum saw canjo

  60, 65, 62, 60, 94, 62, 64, 69, //60, 64, 62, 60, 64, 62, 64, 69,
  60, 91, 62, 64, 60, 89, 62, 64, //60, 64, 62, 64, 60, 64, 62, 64,
  60, 87, 62, 60, 64, 84, 64, 69, //60, 64, 62, 60, 64, 62, 64, 69,
  60, 64, 62, 82, 60, 64, 79, 64, //60, 64, 62, 64, 60, 64, 62, 64,

  // glockenshpiel
  94, 91, 89, 91, 94, 91, 89, 87, //94, 91, 89, 91, 94, 91, 89, 87,
  94, 91, 89, 91, 94, 91, 89, 87, //94, 91, 89, 91, 94, 91, 89, 87,

  84, 87, 89, 91, 84, 87, 89, 91, //84, 87, 89, 91, 84, 87, 89, 91,
  84, 87, 89, 91, 94, 91, 89, 87, //84, 87, 89, 91, 94, 91, 89, 87,

  84, 62, 64, 82, 79, 82, 84, 60, //84, 87, 84, 82, 79, 82, 84, 87,
  84, 62, 64, 82, 79, 82, 79, 77, //84, 87, 84, 82, 79, 82, 79, 77,
  84, 62, 64, 82, 79, 82, 79, 77, //84, 87, 84, 82, 79, 82, 79, 77,
  60, 72, 75, 77, 79, 82, 84, 87, //75, 72, 75, 94, 91, 89, 87, 84,

  72, 75, 77, 79, 82, 84, 87, 89, //72, 75, 77, 79, 82, 84, 87, 89,
  91, 94, 91, 89, 87, 84, 82, 79, //91, 94, 91, 89, 87, 84, 82, 79,
  77, 75, 72, 75, 77, 79, 82, 84, //77, 75, 72, 75, 77, 79, 82, 84,
  87, 60, 91, 94, 60, 94, 91, 60, //87, 89, 91, 94, 91, 94, 91, 94,
  91, 60, 91, 94, 60, 94, 91, 60,  //91, 94, 91, 94, 91, 94, 91, 94,
  91, 94, 91, 94, 91, 94, 91, 94

};

// The note duration, 8 = 8th note, 4 = quarter note, etc.
int durations[] = {
  // intro glockenspiel
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,


  // drum saw canjo
  16, 16, 16, 16, 16, 16, 16, 16,
  8, 8, 8, 16, 16, 16, 16, 8,
  16, 16, 8, 8, 16, 16, 8, 8,
  16, 16, 16, 16, 16, 16, 16, 16,

  // glockenspiel
  8, 8,  8, 8, 8, 8, 8, 8,
  8, 5, 16, 8, 8, 8, 8, 8,

  8, 5, 16, 8, 8, 8, 8, 8,
  8, 5, 16, 8, 8, 8, 8, 8,

  8, 5, 16, 8, 16, 16, 16, 16,
  8, 5, 16, 8, 16, 16, 16, 16,
  8, 5, 16, 8, 16, 16, 16, 16,
  8, 8,  8, 8, 8, 8, 8, 8,

  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16, 16, 16, 16, 16,
  32, 32, 32, 32, 32, 32, 32, 32



};
// determine the length of the arrays to use in the loop iteration
int songLength = sizeof(melody) / sizeof(melody[0]);
void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI);
  Wire.begin();
}

void loop() {

  static bool musicPlayed = false;

  SRF02::update();
  int sensorReading = sensor.read();

  if ((sensorReading > 25) && (sensorReading < 100)) {
    if (!musicPlayed)

      // Iterate through both arrays
      // Notice how the iteration variable thisNote is created in the parenthesis
      // The for loop stops when it is equal to the size of the melody array
      for (int thisNote = 0; thisNote < songLength; thisNote++) {
        // determine the duration of the notes that the computer understands
        // divide 1000 by the value, so the first note lasts for 1000/8 milliseconds
        int duration = 1000 / durations[thisNote];
        MIDI.sendNoteOn(melody[thisNote], 127, 1);
        // pause between notes
        int pause = duration * 4; //1.8
        delay(pause);
        // stop the note
        MIDI.sendNoteOff(melody[thisNote], 0, 1);

        musicPlayed = true;
      }
  }
  else {
    musicPlayed = false;
  }
}

Not really. That { was fine, you needed to move one of the } from the end to just before the line musicPlayed = true;.

Ok, what you have works. But musicPlayed = true is now inside the for-loop, so will get executed 700~800 times when it only needed to be executed once! That does no harm really, but it might cause confusion later.