Midi Controller

My father plays in a band and he uses multiple MIDI sound modules with an old Akai MPC60 serving as a MIDI controller. The MPC60 is getting quite old and seems to be less reliable after all these years of service, so when I heard my father was looking for a new MIDI controller, I started thinking about building one for him.

Like with most controller circuits, I started out with a PSoC micro controller. I chose the CY8C29466-24PXI) as this controller has room for 8 communication blocks, which I used for 4 MIDI outputs, 2 MIDI inputs and an RS232 UART for communication with a PC (laptop/netbook) through USB-to-Serial cable. With all 8 communication blocks used up, there still are 8 other configurable digital blocks left for other general stuff (Timers, PWM, etc…).

OLYMPUS DIGITAL CAMERA

I haven’t made any schematics of the circuit itself, but it’s pretty straight-forward.
A simple google image search returns a lot of useful MIDI-interface circuits. I’ve used a couple of 74HC14 inverters as a buffer for the MIDI outputs and 6n138 opto-couplers for the inputs. All resistors in the midi-interface circuit are 220 Ohms.

The power supply is built around a LM2574HVN-5.0. There are 4 diodes configured as a bridge rectifier followed by a 220uF/35V capacitor at the power input so the controller can accept both DC and AC adapters of a wide voltage range.

The RS232 interface is a standard interface using a MAX232 and a handful of 100nF capacitors.

MIDI Controller API

The controller supports 4 layers, which means that one midi message on any input can be routed to a maximum of 4 channels (on the same or multiple outputs) at the same time

  • int midi_setoutput(struct midi *m, int layer, int input, int inchannel, int output) // Set the physical output to which a certain input/midi channel combination for this layer should be routed to
  • int midi_setchannel(struct midi *m, int layer, int input, int inchannel, int channel) // Set the output midi channel to which a certain input/midi channel combination for this layer should be routed to
  • int midi_setvelocity(struct midi *m, int layer, int input, int inchannel, int velocity) // Set the velocity of this input/midi channel combination for this layer anywhere between 0-200%
  • int midi_enabled(struct midi *m, int layer, int input, int inchannel, int enabled) // Enable/disable this input/midi channel combination for this layer
  • int midi_getoutput(struct midi *m, int layer, int input, int inchannel) // Get the physical output to which a certain input/midi channel combination for this layer is currently routed to
  • int midi_getchannel(struct midi *m, int layer, int input, int inchannel) // Get the output midi channel to which a certain input/midi channel combination for this layer is currently routed to
  • int midi_getvelocity(struct midi *m, int layer, int input, int inchannel) // Get the velocity of this input/midi channel combination for this layer
  • int midi_isenabled(struct midi *m, int layer, int input, int inchannel) // Check if the input/midi channel combination for this layer is enabled
  • int midi_disableall(struct midi *m) // Disable all routes
  • int midi_output(struct midi *m, int output, unsigned char *data, int len) // Send raw MIDI data to an output
  • int midi_bufferinfo(struct midi *m, unsigned char *data) // Get info about the internal MIDI output buffer usage
  • int metronome_start(struct midi *m, unsigned char *pattern, int len, int period) // Start metronome using a onfigurable speed and pattern
  • int metronome_stop(struct midi *m) // Stop metronome
  • int metronome_clickselect(struct midi *m, int click) // Select a click sample

Here‘s a link to the Picture Gallery.

Attached are the PSoC Designer files and an application (Linux) to test functionality. The final PC-side application hasn’t been built yet.

The circuit becomes clear when looking at the pin usage after opening the project in PSoC Designer.

For more pictures check out the gallery

This entry was posted in Projects. Bookmark the permalink.

Comments are closed.