Building a MIDI keytar

Status
Not open for further replies.
MJ The reason i asked as i 'nearly' got caught out ordering a 5 pin DIN.....it was 270 degree ! ...not 180 ...
 
There are a lot of DIN plug types that look similar to the MIDI socket.
So it's easy to make that mistake.

Those particular DIN sockets have the extra pins removed. It threw me off at first, but once I took a meter to them,
I realized that only the important pins were there.
 
Here's the keybed decoder / scan logic.



The taped down bundles are the data and strobe lines coming from the PIC. The rectangular copper foil patch is the ground plane for the PIC.

Over the next few days, I'll be wiring up the CPU. I'm going to get the basic device communicating with the ICD3 and write a simple test program
to clock a port with pulses. Then, on to register setup and programming.
 
Last edited:
I've searched a little bit about keybeds and some roland types readout the highest notes with the lowest matrix.
Because there was some space there, but not in the highest matrix.
When scan logic works You can create MiDi Strings with the USART and test it out with an PC e.g. with MiDi OX.
 
Hi MJ what sound box / synth are you feeding with the Keytar ? I have just added a slave Alesis Q49 keyboard to my Yamaha , think i may need a MiDi sniffer,, so another project looms ...
 
wkrug: As soon as I get a test program set up, I'll be able to take a look at the keybed and test it.
I'd also like to pick up a 49 key bed from doepfer.de I have those mating connectors, so I can retrofit the key action.

granddad: I have a few synths that I could use.

I have a Virus C, Roland XV-5050 and a JP-8080, and both an Alesis S4-Quadra and the QSR.
As wkrug said, I can feed it into the midi interface and use MIDI-OX to see what's coming out.

That sounds like a neat project.
 
So I've gone through the documentation for the PIC24F32KA304 (44 pin TQFN)

Here's all of the Data ports with their corresponding shared pins.


Here's what I came up for the keytar port assignments.


As soon as I get everything wired up and tested, I'll post pics and a schematic.
 
MJ , just a reminder the ANSA, B , C registers default to analogue (SET) , some times missed by young players ...
 
granddad: Young player? I'm still a toddler.
I have so much to learn...

Thanks.

I've started writing the initialization code. First, I have to shut off everything I'm not using.

Then, the UART and Timer1.
Luckily for me, 31250 Baud is an exact register value.

As soon I get the basic stuff working, I'll post the new source code.
 
Here it is. Not my best work. If I had my druthers I'd redo it and do a better layout.
Who knows...I may just do that.

The top of the Keytar board, in its' entirety. As you can see, I stashed the crystal inside the empty space of the socket.



This was supposed to be better detail, but the shot got blurry.

Oh, well...




Here's the CPU wiring.



Here's a close up of the A/D convertor inputs. I hope the twisted pairs keep the noise down.
I didn't do a separate Analog / Digital ground. Perhaps in the next prototype, I'll plan that in.



There are two sections which I must complete:

1) The buttons. I have enough pins and space to poll another key matrix using some of the original hardware. The AC238 can poll the rows and
an AC244 can be used to scan for columns.

2) The Display controller. I have a chunk of room where I can fit just about everything I need.
I still have to design that part of the system.

I'll publish a schematic in a few days. First, I want to get the PIC functioning and make sure that no hardware changes are needed.

More to come...
 
Last edited:
Hitting all notes of a keyboard can be a challenge because the difference between the higher pitch notes becomes a small fraction of the processor crystal speed.

There are tricks to overcome the issues by selecting the "perfect" crystal speed that allows the 12-note "octave" to align with the integer scaling factors that can be easily done with a chip.

The long-form datasheet for the old AY- series sound generators (General Instruments/Microchip) from the 1980s (Atari and Apple sound cards), gives an excellent example of hitting all musical note frequencies with a relatively low frequency crystal - simply by picking the right starting crystal frequency.
 
gophert: Thanks for replying.

This project is only going to be generating MIDI events to feed to a synthesizer, which is a "walk in the park"
in comparison to actual waveform generation.

But I've always wanted to build a DIY synth.

Sad that those ICs are difficult to get these days.
 
MJ ... any thoughts on how you re-code scan value to note value ? or that next week ....
 

Let me know if you want a few, I have a drawer full of them and I doubt I'll ever get a project started. AY-3-8913.

Each chip can play three tones at a time plus a noise channel. Weird but cool effects possible. Not a full-on synth but it would be great for playing an 8-bit audio concert.
 
gophert: Thank you for your kind offer. Perhaps we can collaborate on a project.

granddad: I'm still thinking that one out...

Please bear with me, as I'm a complete n00b with the PIC. The changeover of tools with Microchip has made it even more difficult.


Here's my data segment (so far)

Code:
            .data
Transpose:        .byte    0
Octave:            .byte    0
VelCounters:    .space    49, 0
LastRawScanData:    .space    16, 0
RawScanData:    .space    16, 0

I'm thinking something like this. I wrote it in C, but I'll code it up in PIC assembler when I'm ready to implement it.
Code:
for(i = 0;i < 16;i++)
{
     LastRawScanData[i] = RawScanData[i];
}
for(i = index = 0;i < 8;i++)
{
    Set the AC238 address to the lower 3 bits of 'i'.
    1 or 2 tick delay...not sure. Will check the timing when the code is running.

    Set the latch enables on the AC573 to low.
    1 or 2 tick delay (Same as above)

    Set the latch enables on the AC573 to High.
    1 or 2 tick delay (Same as above)

    Set the latch enable #1 on the AC573 to Low.
    1 or 2 tick delay (Same as above)
    RawScanData[index++] = <Port byte>;

    Set the latch enable #1 on the AC573 to High.
    1 or 2 tick delay (Same as above)

    Set the latch enable #2 on the AC573 to Low.
    1 or 2 tick delay (Same as above)
    RawScanData[index++] = <Port byte>;

    Set the latch enable #2 on the AC573 to High.
    1 or 2 tick delay (Same as above)
}
// We now have the previous keyboard scan data as well as the current scan data.
// We can start comparing the bits and acting accordingly

// 7 bits used and only 7 out of 8 raw data registers used...
for(i = KeyIndex = 0;i < 7;i++)
{
BYTE KeyPress1 = RawScanData[i << 1],KeyPress2 = RawScanData[(i << 1) + 1];
BYTE LastKeyPress1 = LastRawScanData[i << 1],LastKeyPress2 = LastRawScanData[(i << 1) + 1];

    for(j = 0;j < 7;j++)
    {
// I'm going to do a bit by bit comparison. The notation I'm using here is not correct, but it illustrates the bit comparison...
          if (LastKeyPress1<j> != KeyPress1<j>)
          {
                if (KeyPress1<j> != 0)
                {
                    if (KeyPress2<j> == 0)
                            VelCounters[KeyIndex] = 0;
                }
                else
                {
                          // The key has been released...
                }
          }
          else if (KeyPress1<j> != 0 && KeyPress2<j> == 0)
               VelCounters[KeyIndex]++;
          else if (KeyPress1<j> != 0 && KeyPress2<j> != 0)
          {
// Send a Note on to the UART buffer...
          }
          KeyIndex++;
    }
}

If a key hasn't been pressed, the velocity will be 0.

Of course, this is just a rough skeleton. I have to implement the UART code and the transpose / octave code.

The variable "Transpose" will hold a value which is summed to the Note number.
The range of this value will be -11 to 11.

The variable "Octave" will hold a value which will sum 12 (the number of notes per octave) to the key address.

The important thing to remember is that a MIDI note can only be between the range of 0 and 127.
So it will have to be clipped to that range.
 
MJ I think you will find the MPLABX [watch] option useful in conjunction with a break point. ( watch does not always tell the truth ! ) I run MPLAB on linux , PC it seems a lot less buggy . When I did my KB scanner I used the PIC EEprom to hold the table of note values , and from the row/column counts just produced an address of the note , (2x66 note manuals so different counts) was easy to transpose that way also... I also could send a second MiDi channel with the same note value ..
Edit , I don't think the 10000's of EEprom reads is a problem , although the uSec to do so may, as you are scanning so fast ...
 
Last edited:
granddad: I suspect that the note octave positions were fixed in your design.
Moving the 49 note key array up and down across the entire 128 note range was not needed?

Correct me if I'm wrong. If you needed to do that, you'd simply set a starting offset into the EEROM key table.

In this case, I need to provide two functions (well... 3 if you include layering.):

1 ) the user needs to be able to transpose notes played.

2 ) The user also needs to move the controller through the octave positions.

The 3rd function is to allow the keyboard to be split. (i.e. the lower range plays notes on the first MIDI channel, and the upper range needs
to play notes on a different MIDI channel.)

Layering is another nice effect; When a key is struck, it produces two separate MIDI events on different channels.

That means Transposing and Key range need to be stored for each of the MIDI channels involved in the Split / layering.

Another issue that needs to be handled is MIDI congestion. You don't want too many note on events going out for the same key number
without a corresponding note off being sent first. That needs to be handled in the code as well.

So, you only have about 80% of the info when the timer tick is completed.

Then there's system event handling, as well as MIDI clock.

I should be done with the schematic in a few hours.
I'll post it as soon as it's complete.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…