General questions about implementing a 88-key MIDI keyboard

Status
Not open for further replies.

CyberGene

Member
I want to make a MIDI controller from a real grand piano action. I haven't yet decided what type of sensors I will use and there are many options. For example some of the commercial solutions (Yamaha/Kawai) use a small rectangular shutter on the hammer stem that passes through an optical pair and the velocity is calculated using time. In another solution (Alpha piano) the hammers strike a strain gage.

Anyway, I think I might go for optical reflective sensors such as the Vishay CNY70 that measures the distance from a reflective surface.




Since the sensor generates an analog output (output current is dependent on the object distance) I need to decide how I should calculate velocity. One idea I have is to just define two current thresholds (e.g. distances, d1, d2 on the picture) from which to calculate the time.

I haven't yet bought a Teensy and I'm wondering whether it will be quick enough to do that calculation. One idea I have is to feed each of that signals to a digital IO and use the interrupts. I will use two inputs from the hammer sensor (corresponding to two distances) and one from the key (only on/off). So, these are three inputs per note, meaning I can use one Teensy (58 inputs) for 19 notes, i.e. I will have to use 5 Teensy boards to cover all 88 notes. I will have one more Teensy to act as a master and send the MIDI messages, polling the other boards through SPI/I2C.

Do you believe that a single Teensy board, using interrupts would be fast enough to calculate velocities in this way? For clarity, a hammer may reach a velocity of up to 10m/s and the two measurements should be done as close as possible to the strike point (because that's where the hammer detaches from the key, otherwise its speed might be variable due to key not being pressed with the same speed across its path). So, let's say I need to measure the last 5-10mm of the hammer travel. If we take the worst case: 10m/s in 5mm, that means a duration of 500us. In order to be able to precisely interpret that, I guess each interrupt processing should take no more than 250us. But then, it might have to process also all other notes (and the key), i.e. all 57 sensors/interrupts. And that brings it down to just 4us which to me seems like impossible :(

Do you think my calculations are in any way flawed? If not, does that mean that the only way to correctly calculate velocities from so many sensors is to dedicate a PIC controller or something else at each note?

Do you believe I can implement the whole thing in an entirely different manner? If I go for strain gages, how can I detect the max strike force related to each hit (which will be a huge chatter around a short duration) and how many ADC should I have in order to process all sensors in reasonable time?

Any advices will be appreciated.
 
Based on looking at a keybed that I have, each key has two switches and the velocity is measured as the time between each switch activating much like you said. The only difference is that the switches are wired in a matrix fashion instead of going directly into the Teensy, so out of the 58 I/Os you could do a 28x28 matrix with the 2 remaining pins used as hardware midi if you need it. This would effectively give you 784 individual button inputs or 392 keyboard keys, obviously this is way more than you need but shows how many buttons the Teensy could theoretically have.
 
Here's an update with the project. I decided to experiment with the Vishay CNY70 sensor. It's a reflective optical sensor with a LED and a phototransistor that changes its collector-emitter current according to the distance of subjects, i.e. an analog output sensor. However ADC seems to be a slow process and I need to read a lot of values. A better way of course is to convert it to a digital sensor with two digital outputs that will activate at two predefined distances. The hammer will trigger these two points in succession and by measuring the time I will be able to produce velocity. A guy on another forum suggested me to hook the sensor output to an analog comparator with two different reference voltages that will correspond to two distances from the sensor.

Here's the circuit of what I call a Note Unit (two sensors, one for hammer, one for key, four trimpots, four digital outputs)


So, I will have one sensor for each hammer to produce velocity from two digital outputs. And in order to know how long the key is being held and then released (to produce noteOff), I also need one sensor for each key. Most piano softwares however support release velocity so I will apply the same two digital outputs per key sensor to be able to calculate release velocity.

So, by using a comparator and setting the reference voltages with trimpots to serve as thresholds I can set the two distances at which the sensor will detect proximity, close and very close. I tested that idea with a single sensor and a white paper card on a Teensy board that just arrived.

So, in order to read all 88 hammers and 88 keys (each producing two binary values corresponding to two proximity levels for a total of 352 digital outputs) it seems I need to use matrix read/write. I have a Teensy 3.6 board with 58 digital I/O pins. I will group 4 hammers and keys (i.e. 4 note units) in a single group for a total of 22 groups to scan. Since each unit produces 4 values, the whole group will produce 16 digital values to feed to the Teensy digital inputs. Thus I will use 22 digital outputs + 16 digital inputs (+ 1 analog input for the continuous damper pedal + 2 digital inputs for the soft and sostenuto pedals).

What I'm still not sure is how to disregard the output of groups that are not "active" at the moment. One idea I have is: each Note Unit will be connected to a Quad two-input OR Gate so that I will activate only one group at a time through the 22 digital outputs. The outputs will be mutually exclusive, meaning there will always be only one active low from those pins. Then by using tables I will be able to read each separate sensor value out of the currently active 16 from each group.

Here's a schematic (very rough):


Please note, I am not very good at electronics :) Maybe that all is wrong? If you have some ideas of how to implement the OR-ing not through OR gates but by any other means (diodes?), i.e. how to activate only one group at a time, feel free to give me advice.
 
Status
Not open for further replies.
Back
Top