Recording duration (millis) into an array - (MIDI)

Hello,

I have been having a problem getting my code to work the way I want. I am trying to create a function that will allow to populate 2 arrays: 1 - record_notes and 2 - record_durations. What I am trying to accomplish is the following:

1 - when any of the 26 keys are pressed ( they return value 1);
2 - the corresponding key give a midi note value (eg: 72 = C5);
3 - This value will be stored on record_notes array (first position);
4 - A buffer array (duration_buffer) will store the current millis() on its first position;
5 - the record_durations array first position value will be the current millis() - millis from buffer array.
6 - counter++ will do this to every key pressed, until reach a maximum of 128 keys pressed.

So far, I have only been able to sucessfully populate an array with notes pressed. The problem is with the durations. The below code is working but not correctly. The first note is missing its duration, and all the other notes durations are having values much higher than they are supposed to:

void recording(){

int long duration_buffer[128] = {0};
int record_notes[128] = {0};
int long record_durations[128] = {0};
static int note_counter;

  for (int i=1; i<26; i++){                           // for all the keys        
      
      if (key[i] == 1) {                           // if any key is pressed        

        lcd.setCursor(note_counter,1);                  // sets lcd cursor into position
        lcd.write(0);                                   // displays musical notation symbol on counter position   

        note_counter++;                                 // increases note_counter +1
        note_counter %= 128;                            // limits number of recorded notes to 128                  
 
        record_notes[note_counter] = note45[i];
        duration_buffer[note_counter] = millis();
        record_durations[note_counter] = millis() - duration_buffer[note_counter-1];
        
                    
        }
          
      
      }
      

}

All in all what I would like to ask help with is what is the best way to save the millis() each time a key is pressed and with that information be able to populate an array with durations between key presses.

Any help is appreciated. Thanks.

What you need to do is to store the value given by millis() on the key down event and on the key up event subtract this stored value from the current value of millis().

The for loop is not the right structure to use, just use a counter to work through the index, indicating the note order.

Grumpy_Mike:
What you need to do is to store the value given by millis() on the key down event and on the key up event subtract this stored value from the current value of millis().

Actually I want the duration from the key down event until another key down event happens. This is because of two reasons:
1 - Due to the limitation of my hardware, it is better to keep playing a note until another one is played. This makes notes have a longer sustain from instruments like a piano or guitar, however some synthesizer instruments will just keep playing without pause. My input keys are stylophone keys that trigger a noteOn when I apply 5V to them (using a stylos pen connected to 5V arduino, and therefore closing the circuit).
2 - I want to avoid having to deal with pauses between notes to get a smooth transition between notes. Maybe this is just a personal preference.

Keeping that into consideration, what I would like to get a millis value every time a keys is pressed down, and then subtract the values to get a duration of each note. Would you be able to help me with this code?

Grumpy_Mike:
The for loop is not the right structure to use, just use a counter to work through the index, indicating the note order.

The FOR loop here is just used to get the right note that will be played by a specific key. Since I have 26 keys, I have 26 notes. If any of these keys are pressed, then the corrosponding index will give the note value, and save it into the record_notes[note_counter] where note_counter will increase with each key down event.

Or maybe I am not understanding you right?

Here is the full code in a zip. Sorry I have to put everything in a zip since there are alot of files, but you will get the idea better this way.

Midi_Stylophone_Synthesizer_Mega.zip (14.7 KB)

My input keys are stylophone keys that trigger a noteOn when I apply 5V to them (using a stylos pen connected to 5V arduino, and therefore closing the circuit).

Well that is upside down, you should enable the internal pull up resistors and have the stylus connected to ground.This is much safer than having a flying 5V around a circuit.

This sounds similar to my Spoon-o-Phone in my book:- Arduino Music and Audio Projects
It looks like this:-


And you can change the key by changing the voltage to an analogue input through a tap in a resistor chain.

however some synthesizer instruments will just keep playing without pause.

Yes this is a problem.

You need buttons to start and stop recording as well as one to play it back.

It is similar to my MIDI Lopper peddle in chapter 4 of my book. You can get all the software from the book from that link and the Looper is Listing 4-10, you will see it is quite involved.

Basically if you don't want to record the note off event, then you have to take a time measurement at the start of the recording and one at the end. Then you have the time for the whole sequence. On playback you use that time plus the current time when playback starts, to add to the recorded time of the note in the sequence to determine when that note should be played. It sounds a bit more complicated when you explain it than it actually is.

Do send a note off message before the note on message to prevent your sound generating module from jamming up. On the start of recording I would also send an "all notes off on this channel" CC message as well.

Here is mine. However the keys are connected to A0 and A1, that is why I cannot use input pullups.

However the keys are connected to A0 and A1, that is why I cannot use input pullups.

Input pull-ups work on the analogue pins as well.

Also you can add external PULLUP resistors as well.

Thanks for sharing.

I dont understand how an analog input pull up could work. How can i get different analog values if this needs to be 0 when circuit is closed?

I dont understand how an analog input pull up could work.

Because those two zero ohm links you have to ground would be replaced by resistors to 5V, of a value comparable to the mid value of the resistors R1 to R13. Then your probe can be connected to ground. With nothing connected to the probe you would read 1023, then lower readings would represent contact with other keys.