Intro to MIDI using PicBasic Pro

This page covers only the details of MIDI communication on the PIC using PicBasic Pro.

Because MIDI operates at 31,250 bps, it’s not possible to use PicBasic Pro’s serin and serout commands for MIDI on a 4MHz PIC. In order to use a PIC and PBPro for MIDI, there are two options:

  • Use a faster clock than 4MHZ. Even then, serin and serout are not always reliable. Generally, a 20MHz powered oscillator does the job well.
  • Use the hardware serial port on the PIC (16F876, ‘877, and ‘F628, in our case).

The hardware serial option is the more reliable option, so that’s the one we’ll cover here.

First, make sure you are using a PIC with a hardware serial port. The 16F819, for example, does not have a hardware serial port, but the 18F452 and 18F252, do. In the data sheet, it will be listed as USART (Universal Synchronous Asynchronous Receiver Transmitter). Check the first page of the data sheet of the PIC you are using.

To use the hardware serial port in PBPro, you have to use the Hserout command. The Hserout command allows you to send serial data only on the TX and RX pins of the PIC (portc.6 and portc.7 on the 18F252/452) as follows:

Hserout [data]
  • data – the data to be sent out. This can be formatted as raw values, ASCII, HEX, Binary, or strings. See below for details.
  • There are some other optional parameters of the hserout command which have been omitted here for simplicity’s sake. See the PicBasic Pro manual for more on serout.

Before sending serial data, you need to define the baudrate and enable serial transmit and receive registers at the beginning of your program using DEFINE statements as follows:

DEFINE HSER_RCSTA 90h ' enable the receive register
DEFINE HSER_TXSTA 20h  ' enable the transmit register
DEFINE SER_BAUD 31250 ' set the baud rate

The hserin and hserout commands assumes you’re using a 4MHz clock, so if you’re suing a different speed clock, be sure to define the clock speed first, as follows (this is for a 20 MHz clock):


hserin and hserout don’t allow you to set whether the data is inverted or not; logical 0 is always 0V, and logical 1 is always +5V. So to use MIDI or RS-232 using hserout and hserin, you’ll need an extra component called a hex inverter. Digikey, Jameco, and most other electronics parts retailers (except Radio Shack) carry them. Look on those sites for a “7404 hex inverter”.

The MIDI in and MIDI out schematics look like this:

MIDI schematic

Here’s a picture of my MIDI breadboard with a 18F452. Note that the hex inverter needs power and ground. This circuit has a 20MHz powered oscillator for its clock. This circuit is MIDI out only (note that you can also use the simplified MIDI circuit shown further below with the PIC):

Here’s a simpler circuit for MIDI output that works well with the PIC microcontrollers, the BS-2, and the BASIC ATOM Pro24. Note that all three of these microcontrollers can send non-inverted serial data, which is why this simplified circuit works.


Once you’re connected, sending MIDI is just a matter of sending the appropriate bytes. You can send them in any format you want: binary, hex, decimal, etc. The example below sends a noteon and noteoff in hexadecimal format (Many MIDI tables give the command values in hex, so this was done in hex for the sake of convenience):

DEFINE HSER_RCSTA 90h ' enable the receive register
DEFINE HSER_TXSTA 20h  ' enable the transmit register
DEFINE HSER_BAUD 31250 ' set the baud rate
    ' noteon channel 1, middle A, middle velocity
    hserout [$90, $45,$40] 
    pause 1000

   ' noteoff channel 1, middle A
   hserout [$80, $45, $00] 
goto main