howto: send a value ONCE ONLY on bttn release?

another easy question.

synopsis: i have a footpedal (essentially an on/off switch) that acts as an enabler for my midi controller. when the footswitch is depressed, notes are triggered monophonically (cut each other off) via a PING sensor, while an infrared sensor manipulates volume, filter cutoff etc. when the footswitch is NOT depressed, nothing happens.

now, ideally, i want this behavior: when the footswitch is released, i want a NOTEOFF to be sent to the active midi note.

applicable code is this part:

   if(footswitch.isPressed()){    
          ...

       if(notenumber != storednumber){  
      midi.sendNoteOn(channel, cmajarray[notenumber/2], 127);
      midi.sendNoteOff(channel, cmajarray[storednumber/2], 127);
      storednumber = notenumber;
      lastnumber = notenumber;}

i'd just do an }else(midi.sendNoteOff(channel, cmajarray[notenumber/2]) but that sends a constant STREAM of noteoffs, when i only want one.

i could paste the whole code but it's very long and messy...

sorry the details were sparse, i had to run.

i’m using a midi library and a button library, but that doesn’t really matter. basically, the subject sums it up: i want to know how to send a value (in my case midi note off) just ONE time.

Create a boolean variable, offSent. Initialize it to false. When you send the "off" note, set the variable to true.

Now, the key is only send the "off" note when the variable is false. So, it is important to set it to false again at the appropriate time. That would probably be when the pedal is pressed.

thank you for the comment.
i have entered a boolean variable into my project and set it to be false whenever the footswitch is triggered…

if(footswitch.isPressed()){                             
    foot = false;                                        
    ...does other stuff

i conclude this statement with this:

}else{
    foot = true; }
    if(foot=true){midi.sendNoteOff(channel, cmajarray[notenumber/2], 127);}

unfortunately, i still face the problem of constant, all the time, streaming noteoff messages, instead of just 1 noteoff killing whatever note was playing when the footswitch was released.

undoubtedly this is user error. i apologize in advance for this, but here’s the code in its applicable entirety, beginning with “if(footswitch.isPressed()){”

i’m sorry it’s not as stylish as it could be. i’m a beginner to programming as of october 09. the important part is at the top and at the bottom - the “selection” parts and the ping code is kind of sandwiched in there

if(footswitch.isPressed()){                                    // <== FOOTSWITCH enabler.
    foot = false;                                              // <== make sure footswitch value is false

                                                               // FUNCTION USES INFRARED To CREATE A CC, applies MINIMUM and MAXIMUM
IRval = (analogRead(IRpin));                                   // <= reads the pin for infrared sensor.
IRval = constrain(IRval, 150, 750);                                 // <= ** CHANGE IF NECESSARY. sets up a minimum IRval.
IRval = IRval - 150;
mappedIRval = map(IRval, 0, 600, 0, 255);                  // <= 

  if(selection == 1)
    {remapped7val = map(mappedIRval, 0, 255, minimum7, maximum7);     // <= uses CC MINIMUM and CC MAXIMUM values established a couple blocks above to map cc output
      IRval7 = remapped7val;                                     // <= specifies ccIRval out of remappedIRval for future math
      if(IRval7 < 6){IRval7 = 0;}              
      if(IRval7 != stored7IRval){                              // <= forbids outputting identical data
      if(abs(IRval7 - prev7IRval) >= THRESHOLD){                     // flicker killer for top and bottom values.
      midi.sendControlChange(channel, 7, IRval7/2);                 // selection 1. just volume.
      prev7IRval = IRval7;
      stored7IRval = IRval7;}}}
      
  if(selection == 2)
    {remapped1val = map(mappedIRval, 0, 255, minimum1, maximum1);     // <= uses CC MINIMUM and CC MAXIMUM values established a couple blocks above to map cc output
      IRval1 = remapped1val;                                       // <= specifies 2IRval out of remapped2val for future math
      if(IRval1 < 6){IRval1 = 0;}              
      if(IRval1 != stored1IRval){                                  // <= forbids outputting identical data
      if(abs(IRval1 - prev1IRval) >= THRESHOLD){                   // flicker killer for top and bottom values.
      midi.sendControlChange(channel, 1, IRval1/2);                // selection 2. just modwheel.
      prev1IRval = IRval1;
      stored1IRval = IRval1;}}}
  
    if(selection == 3)
    {remapped2val = map(mappedIRval, 0, 255, minimum2, maximum2);     // <= uses CC MINIMUM and CC MAXIMUM values established a couple blocks above to map cc output
      IRval2 = remapped2val;                                     // <= specifies 2IRval out of remapped2val for future math
      if(IRval2 < 6){IRval2 = 0;}              
      if(IRval2 != stored2IRval){                              // <= forbids outputting identical data
      if(abs(IRval2 - prev2IRval) >= THRESHOLD){                     // flicker killer for top and bottom values.
      midi.sendControlChange(channel, 2, IRval2/2);               // selection 3. just breath.
      prev2IRval = IRval2;
      stored2IRval = IRval2;}}}
     
   if(selection == 4){
    bendval = map(duration, 350, 3500, minimump, maximump);     // <= uses CC MINIMUM and CC MAXIMUM values established a couple blocks above to map cc output
      if(bendval != storedbendval){                              // <= forbids outputting identical data
        midi.sendPitchChange(bendval);                           // selection 4 - pitchbend *?* < will this work before DURATION is created?
        storedbendval = bendval;}}                                // <= creates reference value for above identity data filter

  if(selection == 0){                                               // all 3 midi ccs are sent, as above.
    remapped1val = map(mappedIRval, 0, 255, minimum1, maximum1);    
      IRval1 = remapped1val;                                     // <= specifies 2IRval out of remapped2val for future math
      if(IRval1 < 6){IRval1 = 0;}              
      if(IRval1 != stored1IRval){                              
      if(abs(IRval1 - prev1IRval) >= THRESHOLD){                     
      midi.sendControlChange(channel, 1, IRval1/2);               // send CC1
      prev1IRval = IRval1;
      stored1IRval = IRval1;}}
    remapped2val = map(mappedIRval, 0, 255, minimum2, maximum2);     
      IRval2 = remapped2val;                                     
      if(IRval2 < 6){IRval2 = 0;}              
      if(IRval2 != stored2IRval){                             
      if(abs(IRval2 - prev2IRval) >= THRESHOLD){                     
      midi.sendControlChange(channel, 2, IRval2/2);               // send CC2
      prev2IRval = IRval2;
      stored2IRval = IRval2;}}
    remapped7val = map(mappedIRval, 0, 255, minimum7, maximum7);     
      IRval7 = remapped7val;                                     
      if(IRval7 < 6){IRval7 = 0;}              
      if(IRval7 != stored7IRval){                              
      if(abs(IRval7 - prev7IRval) >= THRESHOLD){                    
      midi.sendControlChange(channel, 7, IRval7/2);               // send CC7
      prev7IRval = IRval7;
      stored7IRval = IRval7;}}}
  

                                                   
// PING))) is triggered by HIGH pulse of 2+ ms.                // ***** BEGIN BORROWED CODE FOR PARALLAX PING))) ULTRASONIC SENSOR
//Give short LOW pulse to ensure clean HIGH pulse:             // <= borrowed code can be found online as an arduino tutorial
                                                               // <= here is the full tutorial: http://arduino.cc/en/Tutorial/Ping?from=Tutorial.UltrasoundSensor
   pinMode(pingPin, OUTPUT);                                   // <= original code used the PING))) sensor as an "invisible ruler" and printed a value in inches and cm
   digitalWrite(pingPin, LOW);                                 // 
   delayMicroseconds(200);
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(500);
   digitalWrite(pingPin, LOW);

// The same pin is used to read signal from the PING))):
// a HIGH pulse whose duration is the time from the 
// sending of the ping to the reception of its echo.
   
   pinMode(pingPin, INPUT);
   duration = pulseIn(pingPin, HIGH);                          // <= instead of a measurement, i use the duration to create a range of notes
                                                               // ***** END BORROWED CODE FOR PARALLAX PING))) ULTRASONIC SENSOR
    
   if(duration > 3590){duration = 3591;}
   if(duration < 450){duration = 450;}
//   if(abs(duration - prevduration) >= THRESHOLD2){ 
//     prevduration = duration;}
     if(selection != 4 && duration != 3591){
   mappedVal = map(duration, 450, 3590, notemaximum, noteminimum);
     constnote = constrain(mappedVal, 0, 150);
   if(abs(constnote - prevconstnote) >= THRESHOLD){             // /2 in the next lines...questionable.        
     notenumber = constnote;
     prevconstnote = constnote;}  
          delay(5);    
   if(notenumber != storednumber){  
      midi.sendNoteOn(channel, cmajarray[notenumber/2], 127);
      midi.sendNoteOff(channel, cmajarray[storednumber/2], 127);
      storednumber = notenumber;
      lastnumber = notenumber;}
    }
  }else{
    foot = true; }
if(foot=true){midi.sendNoteOff(channel, cmajarray[notenumber/2], 127);}
 
    
  
}
if(foot=true)

[edit]Try if(foot == false)[/edit]

ack! embarrassing.