Velocity Sensitivity with non-MIDI Keyboard

I have a 61 key velocity sensitive non-MIDI keyboard and I want to add MIDI to it using the Arduino and still maintain velocity sensitivity as a MIDI function. In other words, I want the MIDI signal generated by the Arduino (after key stroke) to also contain velocity data. I've seen tutorials with FSR strips and such, but since my keyboard matrix already has 2 switches per key, I should be able to assign each of the 2 data switches (per note group) to an interrupt and have the Arduino measure the time between the triggering of each switch per note press and convert this time into a MIDI velocity parameter.

My question: Is this possible for a 61 key keyboard to have velocity in addition to generating a MIDI signal for the note...AND have a decent level of polyphony and low latency, all from ONE Arduino module? Or would I need to chain additional modules together and assign them specific functions? For instance, Arduino #1 handles velocity measurement, while Arduino #2 handles generating the MIDI note from key press, while #3 combine the data from #1 and #2 to form a complete MIDI signal for output. And will this allow for polyphony - can all 61 keys be scanned at (actually near, but indiscernible to the human ear) the same time?

I'm just concerned that the above desired functions will be too much for one Arduino board to handle effectively, and with low latency - as I know that they are serial microprocessors at 16 MHz.

Any educated input is welcome,
Thanks

So you have 122 switches? How does that give velocity information?

My gut feeling is to do it in one Arduino because at least that way you have the timing stuff together. I'm not sure about using interrupts, you certainly don't have over 100 of them.

One possibility is a matrix (like a keypad) but you will throw away polyphony doing that.

Have a read of this: Code Tinker Hack: How to turn Piano toy into MIDI keyboard (using Arduino/Atmega)

Looks like he did some multiplexing, although I didn't read the whole thing, sounds like you activate a group, then check each key in the group.

Get back to us if that article doesn't help.

Thanks for the info. For the keys, each note has two switches (122 total), and so the onboard processor must measure the time it take between hitting each switch during one key press, and generate velocity based on that value. The switches are stacked vertically with a degree of displacement, so when you complete a full press, you turn on both switches. The speed of hitting the switches per single press translates into velocity. The onboard processor does this well, but the keyboard has no MIDI and it would be cool to also have velocity in MIDI by tapping into that matrix. The matrix is kind of like 2 matrices overlapping - one for each type of switch (low hit point and high hit point of the key press). So velocity measurement won't be exclusive to each individual key, but every key on that same data bus of the matrix (which is ok with me).

Do you think having one Arduino doing so many things at once will have noticeable latency?
I'll read that article in more detail, as I may have to go with the FSR that he used.

The 122 switches give velocity information by comparing the timing between the two buttons for each key, which are spaced at slightly different depths. I'm surprised it works with any reliability, but apparently it does well enough and is a pretty common design for simple keyboards:

I would think this would be possible with one arduino. You'd need to figure out an efficient loop that would monitor and track the press timing for each switch, calculate velocities using timing differences, and send key ON and OFF MIDI signals when appropriate. One reasonable first step might be to try to create MIDI output from one pair of switches on one key, as that would sidestep all the complications related to multiplexing.

The rate at which musicians hit a keyboard is somewhat slower than the 16 MHz processor in the device, so I have a certain amount of hope that code which scanned the switches could do so without noticeable lag.

I haven't really tried this so I would do a few more searches on the topic of something like "velocity sensitive midi arduino".

Cool - Looks like I have some research and design to work on :slight_smile: Thank you!

jon_s:
The 122 switches give velocity information by comparing the timing between the two buttons for each key, which are spaced at slightly different depths. I'm surprised it works with any reliability, but apparently it does well enough and is a pretty common design for simple keyboards:
How a MIDI keyboard works | Open Music Labs

Its the standard design for most keyboards with velocity sensitivity.

Unfortunately, doing so will turn up lots of forum posting, blog posts etc about scanning the matrix of keys (a 61 key keyboard is typically wired as a 8x8 matrix, with diodes to cope with the ambiguity of multiple keypresses, so it is similar to decodin a matrix keypad) with code which uses only one set of switches per key, then ends lamely with "and the velocity is just a fixed value in my code for now, I will add velocity sensing later" followed by the end of the thread :roll_eyes:

Not having done this either, but planning to - the top set of switches is an 8 rows by 8 columns matrix; the bottom set is an 8 rows by 8 columns matrix. As far as I can see the rows can be shared between the two, so you loop through rows, output a signal per row and scan both sets of columns. That adds up to 24 pins (or less pins, if a serial-to-parallel latching port expander like 74HC595 is used to generate 8 rows from 3 pins). If the columns can use pins that correpond to a contiguous set of 8 on one port, then port reads can be used to read the entire column at once.

For a velocity sensitive keyboard you would need to maintain a key state array with a entry for each key, based on the two scan results for upper and lower switches. The key states are:

  1. unpressed (upper and lower open)
  2. press started (upper closed, lower open)
  3. press complete (upper and lower closed) (sample aftertouch)
  4. release started (upper closed, lower open)
  5. release finished (upper and lower open)

Looking at those key states they are defined not only by the upper and lower switch states but also by whether they key is rising or falling i.e. the previous state.

The normal sequence of key state transitions is 1, 2, 3, 4, 5, 1. Code should also cope with 1, 2, 1 (the key starts to depress but then goes up again, no MIDI generated) and 4,3,4 (key starts to rise but then goes back to fully depressed, no MIDI generated).

At states 2 and 4 you would want to get the current time (millis) and store it. I believe the two times could use the same array location.

At states 3 and 6 you would want to get the current time (millis), compare it to the stored time, and then compute the velocity which is usually a 7-bit value where 1 is very soft (a long tie between the two switches) and 127 is hard (a fast time between the two switches). Zero has a special meaning (a Note-On with velocity of zero means Note-Off). You would need to decide a minimum and maximum time to map to 1 and 127. This could be a linear relatinship or you could allow various velocity curves.

Then a state 3 you send Note-On with velocity and go to state 4. At state 6 you send Note-Off with velocity and go to state 1.

To cope with poor quality, easily confused lowest-common-denominator MIDI implementations I would also suggest providing the option to skip measuring the key release velocity and instead send Note-On with velocity zero at stage 6. This is for three reasons; firstly many synthesizes etc don't do anythng with release velocity so there is no benefit to measuring it; secondly if using MIDI-over-DIN your bandwidth is very limited and sending a sequecnce of Note-On v followed by Note-On 0 allows runing status so you only send the status byte once. (This does not apply to MIDI-over-USB which does not need, or indeed allow, runnin status and has ample bandwidth, 12Mbits instead of 31kbits). Thirdly, some poor implementations not only won't use release velocity but are actually confused by it and will not register a note-off. These are thankfuly rare.

If your keyboard has a single pressure sensor, then you can also measure and send Channel Aftertouch during key stage 3. And if you are building your own keyboard and have lots of money for 61 pressure sensors plus ADC multiplexing circuitry, then you could measure and send Polyphonic Aftertouch at stage 3.

Nick, could you explain that point further? I don't see any way that matrix scanning (which is the standard method for keyboards since the 60's) is incompatible with polyphony, as long as the switch matrix incorporates diodes which they all seem to do.

You are right (I think) with diodes to stop cross-talk between the switches, I suppose it is the same as multiplexing a 64-segment LED display, except in reverse. Oh well, that makes it nice and simple. A few shift registers or a couple of 16-port port-expanders and you should be able to interrogate all 128 combinations fairly quickly.

Nantonos, your explanation above sounds right to me. For the velocity sensing getting the timing moderately accurate is probably crucial. A fast scan would probably do it, alternatively a port-expander which generates interrupts might give you a slight edge (eg. MCP23017).

I've got a post about using that here.

I'd be tempted to set 8 ports as outputs and high, and 8 as inputs (ie. the two sides of the matrix) and setup to generate an interrupt. The interrupt gives you the moment the switch was pressed pretty accurately, then quickly scan to find exactly which switch it was.

On the diodes, here are some keyboard wiring diagrams of the Fatar keyboards used in a number of commercial keyboards:
http://www.doepfer.de/DIY/MKE_keyboards.htm

I'm curious what velocity sensitive keyboard you have that does not have MIDI.

Hi Guys,
I am so glad to have found this thread. I am also working on a 61-note MIDI project which involves adding velocity sensitive MIDI to the upper manual of a Hammond organ. The organ's contact system is strictly SPST with no way to add or modify it to achieve an OFF state, and after R&D'ing several options, such as leaf switches and optical sensors, I have settled on using Arduino to process force data obtained from Resistive force strips mounted beneath the keys. I have Visual Basic programming and electronics experience but have never worked with Arduino. My plan is to process note On-Off data through the existing contacts and a MidiBoutique.com controller, model MKCV128SN, and hope to find a way to process the velocity data and send it to the controller at the time of key press. If anyone has any thoughts or ideas to pass along I'd be grateful.
Regards,
Bruce

That sounds like polyphonic aftertouch, not velocity.

The "time between break and make" method of velocity sensing described here is really common, especially in high-end keyboards. I've seen it in almost everything I've taken apart (but then, of that vintage, almost everything used the Yamaha FS mechanism or some ripoff of it).

Other suggestions already posted seem to be right on the money, or very close to it... just had a look at an old service manual for an instrument time forgot and it seems very similar to how the big boys do it except you won't have multiple processors all doing different jobs and having to tell the main one what they're up to :smiley: So hopefully, a much simpler task.