Search

Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Building a MIDI keytar

Go to page

Go to page

Active Member

The .96" and 1.3" OLEDS are cute but take a lot of code , a backpack I2C display that does not rely on 'busy' should be considered , also an I2C port expander MCP23008 a good choice for switches as it can generate an IOC ( Interrupt on change ) I built a I2C back pack with a PIC18F14K22 and MCP expander with LCD display /4x4 key pad / EEprom / LEDS ... It gets projects off the ground fairly quickly ..

Active Member

The only unknown right now is how much CPU time I need to process the keybed and switches / pots.

Using a second CPU (a little smaller) whose only job is to take the SPI info in and convert it to graphics sounds like a good option.

I will investigate further when I get the CPU wiring completed.

I still have a few questions.

1 ) I have 15kX9 sips that I'd like to use for the pullup resistors coming into the board from the keybed switch sense lines.
At +3.3V, is 15k too high? Do I need to go with 10k pullups?

2 ) Regarding the ICD3. I've been looking at the ICSP wiring, and they call for a 50K resistor (47K is what I'd use)
but the MCLR line calls for a 10K resistor to Vdd. I'm concerned about blowing up the ICD3,
but I'd like to use a 10K resistor instead of the 50K. That would allow me to use a 100nf ceramic cap for reset.
Do I need a reset capacitor? If so, I'm going to wire it to a dip switch, so I can switch it out of the circuit when using the ICD3.

Also, I want to tie the ICD3 ground to the prototype digital ground. The ICD3 reference guide seems to imply
that it's optional, but that doesn't sit right with me.

Should I hook up the ICD3 ground on the RJ11 to the digital ground of my prototype?

Well-Known Member

I've not got around to playing with this yet but I'm sure a 18 series Pic chip will handle a 64 key keyboard and deliver velocity values with time to spare. Can you tell me how velocity is defined? BTW, going to attempt in, can never be done, C. So, a value of zero is how long? And a value of 128 is?

Mike.
The rest of it can be done by the receiving chip. Think of the 18 series as a key scanner.

Active Member

In the datasheet of the E 510 Chip one velocitiy count is 250µs.
Maximum length for whole velocity is 125 x 250µs = 31,25ms.
With the used keybed it is to test if this values fit's for proper playing.
I guess it should be done in shorter periods, because the rubber contacts will close faster one after the other than the old rail ones.

When it has to go faster as the the chip can do this, You can countdown 2 steps per scan, that doubles the scan time.

Before processing the last values the pulling down for the next bank could be done, so there is a little bit of time to stabilize the voltage.

I think an optimized C-Code will be fast enough for the keybed scan, but assembler that could be run faster.

I guess the used Microcontroller has not enough memeory to steer this Display properly.
For every pixel You need 3 bytes of data = 128 x 128 x 3 = 49152 Bytes to transmit.
I think it's better to use a monocrome one, there every pixel have one bit = 2048 Bytes.

Additional I would use SPI for display steering, because it will be faster then I²C and easyer to handle.
And that could be done in C without problems.
Most displays can be programmed via solder points to the used protocoll.
For comunication between the main controller and the display controller You can use a hardware USART, like suggested at the start of this threat.
A possible protocoll could be: x-position, y-position, font, a few bytes ASCII, CR, LF.
The overhead is then 5 Bytes.
The display controller would setup the display then.
But then You need a main controller with a minimum of 2 USART's.
One for MiDi, one for display.

Active Member

MiDi Velocity between 0 and 128 , Zero being no velocity , 128 maximum ,, theoretically 128 steps is rather a lot you could get a way with less , So the fastest / hardest key depression is 128 , timer / counter needs to count down.. Velocity can also be used in aftertouch in the 'NOTE OFF' frame..

Active Member

I have a logic analyzer, so when I finish the scan logic, I'll post some pics of the raw data being clocked.
That will show the gap sizes between the first switch closure and the second switch closure.

LOL I have everything but the 74AC238 I'm waiting for it to be delivered. Probably tomorrow, so I'll finish the power supply
and MIDI section today.

Active Member

The code I've posted in #62 will do this in 250µs ( 8 key's ) with an 20MHz AVR ( ~ 20MIPS ) , depending how many key's are pressed at same time.
When all the key's are pressed it takes about 400µs.
It's C code, so to export it to an fast PIC micro should be possible.
Only the configuration, the port names and the data send has to be changed.
The timing is done by a flag in timer1 comparematch interrupt with 300µs cycles ( to win a little bit processing time ).

I have a logic analyzer, so when I finish the scan logic, I'll post some pics of the raw data being clocked.
That will show the gap sizes between the first switch closure and the second switch closure.

There is also an SD socket on the back with its own connections, if that's useful.

There are also driver libraries available for the PIC (in C).
Even if you do not use the literal code, the initialisation and function sequences and useful for reference.

A thought:
With enough memory, you could have a variable for each key and store the value from one of the timers as a key press is detected?
When the second contact is detected, read the timer again and calculate the time, plus setting a bit to show the key has been read.
That avoids having to count separately for every key.
Not practical on a small device but with a large RAM one, a full size integer array only takes a fraction of the RAM.

[Just checked the specs on your PIC24F - only 2K ram? the dspic33 we use has 32K or more..
You still only need about than 200 bytes for a table & flag bits].

I see that your resistor networks are tied to +3.3V, so they're acting as pull-ups.
The selected output of the 238 will also be high, so the pressed key won't make a change of state.
Unless I'm missing something, it seems to me that you either need a 138 or your r-networks need to be pull-downs.

Active Member

If You need a pullup or a pulldown depends of the direction of the diodes that are installed in the keybed.
When Diodes cathode shows to T0 ... T7, one of them have to be conected to GND and SM1 ... PM7 have to be read out.
Than SM1 ... SM7 & PM1 ... PM7 have to be pulled up.

MichaelaJoy
I would throw out U2 + U3 and use 2 Ports of the Controller instead of 1 for Input.
Then You not have to switch between the U2 and U3 chip.
You have only to readout 2 ports instead of: readout port - switch - readout port - switch.
I think pin6 of U1 can be connected to a fix value.
In pauses between two scans it doesn't matter what level is set on the keybed pin.
So You win 5 ports for the now needed 7, when this is nessesary.

Yesterday I found a keyboard with different velocity curves.
I guess this would be an interesting idea and should be easy to implement with lookup tables.
But You can implement this any time, because it is only software

Active Member

With enough memory, you could have a variable for each key and store the value from one of the timers as a key press is detected?
When the second contact is detected, read the timer again and calculate the time, plus setting a bit to show the key has been read.
That avoids having to count separately for every key.

But then You have to make a calculation when the second switch is closed.
New timer value - old timer value. Normalize it to velocity.
Ok, Your idea is better to avoid scan timing issues, but it can decreas velocity resolution.

I think it's faster to syncronize the scanning process with a timer.
Scan will be started when a timer value is reached.
When first key is pressed the depending variable would be decremented.
A key state variable would be changed.
At second switch contact the variable would be readout and You got raw velocity values.
With the key state table You suggest, I agree.

Only by setting the comparematch of timer will set the scan time and can be easely changed.
But the scan process has to be very fast then. Faster then 1 timer round.

Well-Known Member

The 74238 has active high outputs so 7 of the pins will be low and therefore 7 address lines are selected simultaneously. The 74138 is active low so only 1 address line is selected at once. The direction of diodes is irreverent.

Active Member

The 74238 has active high outputs so 7 of the pins will be low and therefore 7 address lines are selected simultaneously. The 74138 is active low so only 1 address line is selected at once. The direction of diodes is irreverent.

When giving +5V to a diode cathode while anode is pulled down, will not apear any change.
When make GND to the cathode while the anode is pulled up by resistor, the GND appears at the anode.
So the diode direction is importent.
Depending therfor the fitting encoder had to be chosen.

Active Member

Yesterday I found a keyboard with different velocity curves.
I guess this would be an interesting idea and should be easy to implement with lookup tables.
But You can implement this any time, because it is only software

wkrug: I was thinking that same thing.
Maybe doing some kind of velocity compression, with a lower and upper limit. If the final velocity falls within the window,
then set it to the fixed value. This would be great for MIDI recording.

wkrug and granddad said:

I would throw out U2 + U3 and use 2 Ports of the Controller instead of 1 for Input.

@wkrug,granddad: That's a great idea. My concern is having enough pins for the UART, SPI and 3 A/D converter inputs.

Multiplexing the pins does have the added bonus of letting me read the extra scan lines, so that I can add switches.
In retrospect, I may not need the pullup resistors at all, since the ac238 will drive the scan line line high, and the output of the diode matrix is
on the AC573 input.

Active Member

When the resistance fit's it is a good idea.
At the ATMEL AVR controllers the internal pullups has about 47k Ohm and so I rather would use external one.
Because the cabeling has some capacitance and the scanning pulses are short.
So some false readouts could appear ( rise and fall time ).
But that could be checked with an oscilloscope.

Active Member

But then You have to make a calculation when the second switch is closed.
New timer value - old timer value. Normalize it to velocity.
Ok, Your idea is better to avoid scan timing issues, but it can decrease velocity resolution.

It should be possible to adjust a timer rate so it counts 127 clocks over the appropriate time needed for a keypress velocity measurement, so no normalisation needed.
That also allows adjusting the touch sensitivity with a single calibration value for the timer in use.

As long as the scan rate is higher than the count rate, you get an absolute accurate velocity.

Just done a bit of research:
The "count" rate for key velocity is only around 4KHz; eg. the old stand-alone E510 MIDI encoder used a 256uS increment for its key velocity value.

A full scan in less that 256uS is easy, even as a sequence over a number of clock interrupts so nothing is waiting for the settling delays.

Active Member

It should be possible to adjust a timer rate so it counts 127 clocks over the appropriate time needed for a keypress velocity measurement, so no normalisation needed.
That also allows adjusting the touch sensitivity with a single calibration value for the timer in use.
As long as the scan rate is higher than the count rate, you get an absolute accurate velocity.