Opening the MIDI can of worms

Jon_

Member
Hi All,

This subject has been featured quite heavily on various posts in this forum but i am posting about it again for clarification.

I have designed a circuit that is triggered by certain inputs, one being a computer input, but i now need it to trigger when there is a MIDI input. oh dear, here we go again with baud rates.

I personally don;t want the headache of trying to push MIDI through picaxe because after researching on here it seems it just cannot handle that sort of input. So the question is, is there any clever way round interfacing an MIDI in signal to picaxe?

All i need to be able to listen for is program change and read the value of the new program value.

many thanks,

Jon
 

hippy

Technical Support
Staff member
Welcome to the PICAXE Forum.

Capturing MIDI, even passing it through, shouldn't be too hard using an X1 or X2 which supports high-speed serial background receive. The following for the 20X2, although untested, should capture all Program Change commands sent to a specific MIDI Channel, and handles MIDI Running Status ...

Code:
#Picaxe 20X2
#Terminal 9600

Symbol MIDI_CHANNEL = 1 ' Set to 1 to 16

Symbol PROG_CHANGE_COMMAND = $BF + MIDI_CHANNEL
 
HserSetup B31250_8, %001

Do
  Do : Loop Until hSerPtr <> ptr
  b0 = @ptrInc
  If b1 = PROG_CHANGE_COMMAND And b0 <= $7F Then
    SerTxd( "Got Prog Change = ", #b0, CR, LF )
  Else
    b1 = b0
  End If
Loop
 

Jon_

Member
Thank you Hippy!

So for this to work the MIDI connection would have to be connected to the hserin pin, i am using an 40X1 chip so it should work.

I will get back with my results!
 

hippy

Technical Support
Staff member
That's correct. HSERSETUP for the 40X1 doesn't allow the polarity of the hserin pin to be altered so you may have to experiment with the opto-isolator on the input to get the polarity right - I think it should be low-side, pull-up R but am never sure off-hand.
 

Jon_

Member
I am a little uncertain how to wire the midi interface to the picaxe chip through an optoisolator, attached is a circuit diagram of how i assume you do it, resistor values are high for protection so i expect they could be lower/not all needed.
 

Attachments

hippy

Technical Support
Staff member
Not quite. The MIDI In socket wires must be completely isolated from the supply. Do not connect pin 2 of the DIN to 0V, pin 4 goes to the opto anode, pin 5 goes to the opto cathode. A series R of 220R in the pin 4 signal line.

I've no idea what leg 6 of the opto should connect to.
 

Attachments

Last edited:

Jon_

Member
Thanks for that Hippy, i think i should get the award for the most creative optoisolator circuit!!

I have an issue now with the programmer, it is complaining about a syntax error on the baud rate being 31250. This is what I am using, exactly the same as yours except i have changed the chip details:

Code:
#Picaxe 40X1
#Terminal 9600

Symbol MIDI_CHANNEL = 1 ' Set to 1 to 16

Symbol PROG_CHANGE_COMMAND = $BF + MIDI_CHANNEL
 
HserSetup B31250_8, %001

Do
  Do : Loop Until hSerPtr <> ptr
  b0 = @ptrInc

  If b1 = PROG_CHANGE_COMMAND And b0 <= $7F Then
    SerTxd( "Got Prog Change = ", #b0, CR, LF )
  Else
    b1 = b0
  End If
Loop
Regards,
 

Jon_

Member
I have tried updating my compiler and it all compiles now :)

However, i don't seem to be getting anywhere, i send a program change and i get nothing in the terminal window. I am not sure where to start the debugging really, bit of a pain without an oscilloscope.
 

eclectic

Moderator
I have tried updating my compiler and it all compiles now :)

However, i don't seem to be getting anywhere, i send a program change and i get nothing in the terminal window. I am not sure where to start the debugging really, bit of a pain without an oscilloscope.
I'm unable to answer, but,
have a look at Hippy's post #4

Ec
 

hippy

Technical Support
Staff member
However, i don't seem to be getting anywhere, i send a program change and i get nothing in the terminal window. I am not sure where to start the debugging really, bit of a pain without an oscilloscope.
First place to start is to download a simple test program to prove you can debug ...

#Picaxe 40X1
Do
SerTxd( "I'm Alive" )
Loop

You may have to adjust that for whatever resonator you are using. Once that's working apply the speed changes where need be in the MIDI program if _8 is not correct. Is MIDI_CHANNEL set to the channel you are using ?

You can put a LED across the opto LED inputs and it should flash when MIDI data is received. Check pin4/5 not swapped on the MIDI DIN.

And check if anything is arriving ...

#Picaxe 40X1
HserSetup ...
Do
If ptr <> hSerPtr Then
SerTxd( "Got ", @ptrInc, CR, LF )
End If
Loop
 

Jon_

Member
#Picaxe 40X1
Do
SerTxd( "I'm Alive" )
Loop
That works


You may have to adjust that for whatever resonator you are using. Once that's working apply the speed changes where need be in the MIDI program if _8 is not correct. Is MIDI_CHANNEL set to the channel you are using ?
All correct and talking on midi channel 1

Started playing a midi file:

You can put a LED across the opto LED inputs and it should flash when MIDI data is received. Check pin4/5 not swapped on the MIDI DIN
Worked to start with, then realised the midi din was swapped so i changed them round, only for it to stop flashing. However, the picaxe chip suddenly started to receive data using your last piece of code (attached), not sure if that is what we wanted though as it seems to just output special chars?
 

Attachments

hippy

Technical Support
Staff member
Oops; missed a # out of the SERTXD. Try this one ...

Code:
#Picaxe 40X1
HserSetup ...
Do
  If ptr <> hSerPtr Then
    b0 = @ptrInc
    b1 = b0 / $10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
    b2 = b0 & $0F + "0" : If b2 > "9" Then : b2 = b2 + 7 : End If
    SerTxd( "Got $", b1, b2, " ", #b0, CR, LF )
  End If
Loop
 

Jon_

Member
ok, so now it is outputting what is attached.

Just so i am clear what it is doing, i take it the first dollar value is the status message followed by one byte of data?
 

Attachments

hippy

Technical Support
Staff member
Each line of data is one byte received, shown in hex and then decimal. MIDI status bytes have msb set, data bytes have msb clear. Status bytes are easier to decode from hexadecimal, data bytes often best in decimal.

Manually decoding what you're seeing it doesn't look like a valid MIDI command sequence; possibly a signal polarity issue. I'd suggest feeding in MIDI from a simple non-velocity sensitive keyboard and plonking on middle-C, just sending Note On and Note Off commands. You should see something like the following for each key press-

Press ...

Got $90 144 - Note On
Got $3C 60 - Middle C
Got $40 64 - Default Velocity

Release ...

Got $3C 60 - Middle C
Got $00 0 - Zero velocity ( Note Off )

You can take another PICAXE and use that to send the above MIDI packets, get it working by feeding its MIDI Out to a keyboard / sound generator / etc. Then use it as sender to the receiving PICAXE. Then you know exactly what you are sending and what you should be looking for.
 
Last edited:

Jon_

Member
your right hippy, something rather weird is happening.

Attached is a screen shot of midiox sending a middle c note on and note off, the picaxe does not seem to be displaying anything at all logical to what is being sent!!
 

Attachments

hippy

Technical Support
Staff member
Probably best to post a full schematic of your circuit and the HSERSETUP used. It's probably a signal polarity issue.

MIDI is a fast baud rate, bytes are sent back-to-back so it may help running the PICAXE at a faster speed. Also a PAUSE to allow the data to be captured before dumping may improve things.
 

Jon_

Member
attached is my current circuit diagram, if i have managed to read it correct of the breadboard!!

the current code i am using is:

Code:
#picaxe 40X1

HserSetup B31250_8, %001


Do
  If ptr <> hSerPtr Then
    b0 = @ptrInc
    b1 = b0 / $10 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
    b2 = b0 & $0F + "0" : If b2 > "9" Then : b2 = b2 + 7 : End If
    SerTxd( "Got $", b1, b2, " ", #b0, CR, LF )
  End If
Loop
and outputs:
$88 136
$FD 253
$C8 200
$fC 252

when note on and note off middle c is sent.
 

Attachments

hippy

Technical Support
Staff member
Isn't the 40X1 default operating speed 4MHz, so ...

HserSetup B31250_4, %001
 

Jon_

Member
aaaahhhh Bingo, nice find hippy, i have been looking at that all day and never noticed that.

Now i play middle c and get the following:

$90 144
$3c 60
$64 100
$90 144
$3c 90
$00 0

which i believe is correct!!!

also when i patch change i get:

$C0 192
$02 2

where the first line is correct for patch change is it not?
 

hippy

Technical Support
Staff member
Excellent. Looks like it's all working now. The original code should now work to detect the program changes ( just make sure HSERSETUP matches the latest ).
 

axe_hackin

New Member
Hey guys.

Just now stepping into the cold pool of MIDI.

I am starting with an 20X2.
What i'd like to do is have the 20x2 look for note #16 on Ch. 10 and then blink and LED.
I am just starting out trying to configure the 20x2 to only respond to the note and the channel.

I have seen this statement used a bit on the forums "ptr <> hserptr" which I do not understand.

well, here is my code:
Code:
#picaxe 20x2

' 10011001= 99[hex]= 153[dec]= Channel 10 Note On
' 10001001= 89[hex]= 137[dec] = Channel 10, Note Off
' Note number (0 - 127)
' ex. 00000000 10011001 = Ch. 10 Note On, Note 0
' ex. 00000000 10001001 = Ch. 10 Note OFF, Note 0

setfreq m64

hsersetup B31250_64, %00001               ' 64MHZ clock. Baud 31250, auto receive.

main:
	read b0, b0 	                        ' read scratchpad variable into temp variable b0, which is channel #.
	read b1, b1		                        ' assume scratchpad has incremented, and now has note # value.
		if b0 = $99 AND b1 = 16 then ' b0 is Channel 10, and b1 is note #16.
			pulsout b.0, 500 		' blink an LED
			hserptr= 0			'reset the hserptr so no data gets lost in the scratchpad.
		esle 					' Different MIDI note and Channel.
		        hserptr= 0			'reset the hserptr so no data gets lost in the scratchpad.
                endif
goto main
I hope it makes sense.

Any insight would be much appreciated. Thanks.
 
Last edited:

hippy

Technical Support
Staff member
You are using READ which doesn't read the scratchpad and also take a look at the code in post #2, which was ...

Code:
#Picaxe 20X2
#Terminal 9600

Symbol MIDI_CHANNEL = 1 ' Set to 1 to 16

Symbol PROG_CHANGE_COMMAND = $BF + MIDI_CHANNEL
 
HserSetup B31250_8, %001

Do
  Do : Loop Until hSerPtr <> ptr
  b0 = @ptrInc
  If b1 = PROG_CHANGE_COMMAND And b0 <= $7F Then
    SerTxd( "Got Prog Change = ", #b0, CR, LF )
  Else
    b1 = b0
  End If
Loop
Untested ...

Code:
#Picaxe 20X2
#Terminal 9600

Symbol MIDI_CHANNEL     = 10 ' Set to 1 to 16

Symbol NOTE_ON_COMMAND  = $8F + MIDI_CHANNEL
Symbol NOTE_OFF_COMMAND = $7F + MIDI_CHANNEL
 
HserSetup B31250_8, %001

Do
  Do : Loop Until hSerPtr <> ptr
  b0 = @ptrInc
  If b1 = NOTE_ON_COMMAND And b0 = 16 Then
    SerTxd( "Got Note 16 On", CR, LF )
  Else
    If b1 = NOTE_OFF_COMMAND And b0 =16  Then
      SerTxd( "Got Note 16 Off", CR, LF )
    Else
      b1 = b0
    End If
  End If
Loop
 

axe_hackin

New Member
Hello again,

I have finally gotten around to trying out the codes posted in this thread.

I am getting data into my 20X2, however it is not being read correctly.

Not only that, the values seem to change slightly.

I have attached the data from the terminal, plus a MIDI monitor program that shows the true HEX values, and my code.

I am confident of my MIDI interface, It is a MIDI module (jacks, opto, resistors, diodes) from an old Roland keyboard.

I would really appreciate some insight as to what may be wrong.

Thanks.MIDI_2.JPG
 

axe_hackin

New Member
I would guess that input signal polarity was wrong so try changing to -

HSerSetup 31250_8, %111
Hippy, I don't know how you do it, but you did it again!

I haven't tried it yet, but I looked at my schematic of the module I drew - sure enough- the output of the opto goes through an inverter before the header connected to the 20X2.

S'mazing!
 

OLDmarty

Senior Member
Not quite. The MIDI In socket wires must be completely isolated from the supply. Do not connect pin 2 of the DIN to 0V, pin 4 goes to the opto anode, pin 5 goes to the opto cathode. A series R of 220R in the pin 4 signal line.

I've no idea what leg 6 of the opto should connect to.
I'm not sure of the 4N35 specs, but the preferrered "Midi Opto" for absolute decades has always been the 6N138 (Hi Speed 100 kBd, low Input Current).

I seem to recall generic optos (4n28 etc) back oin the day being a bit laggy and low slew rates which often corrupted midi data.
The 6n138 offers more precise 'sharper' data pulses without corruption.

I hope this helps, just in case some crappy opto's are causing your code grief. (when in fact it's not the code at fault).
 

hippy

Technical Support
Staff member
I'm not sure of the 4N35 specs, but the preferrered "Midi Opto" for absolute decades has always been the 6N138 (Hi Speed 100 kBd, low Input Current).
My official MIDI 1.0 specification states; "Optoisolator currently shown is Sharp PC-900 (HP 6N138 or other optoisolator can be used with appropriate changes)".

Commercial products I was involved in used 4N25 optoisolators with 1K0 pull-up to 5V and I do not ever recall any problems with MIDI being reported.

I do not know what the actual specs of any of those optoiosolators are but would have thought almost anything would be usable providing it did not have truly atrocious characteristics.

If propagation delay simply lags the output with respect to the input there should not be a problem. An unbalanced propagation time for rising and falling edges may present more issues.

It would however be worth checking characteristics against a PC-900 / 6N138 if having problems.

Added : By putting HSEROUT into the opto and using HSERIN for input from that, it should be possible to vary the baud rate to get a rough idea of what the limitations of a particular opto are.
 

OLDmarty

Senior Member
My official MIDI 1.0 specification states; "Optoisolator currently shown is Sharp PC-900 (HP 6N138 or other optoisolator can be used with appropriate changes)".

Commercial products I was involved in used 4N25 optoisolators with 1K0 pull-up to 5V and I do not ever recall any problems with MIDI being reported.

I do not know what the actual specs of any of those optoiosolators are but would have thought almost anything would be usable providing it did not have truly atrocious characteristics.

If propagation delay simply lags the output with respect to the input there should not be a problem. An unbalanced propagation time for rising and falling edges may present more issues.

It would however be worth checking characteristics against a PC-900 / 6N138 if having problems.

Added : By putting HSEROUT into the opto and using HSERIN for input from that, it should be possible to vary the baud rate to get a rough idea of what the limitations of a particular opto are.

Interesting......I'm probably biassed to suggest 6N138, because EVERY SINGLE MIDI KIT in our local Electronics mags for 30+ years has always strongly suggested to always use the 6N138 instead of the more common 4N25/4N28 that people would normally buy.
Several articles kept highting the reason to use the 6N138 over the 4Nxx opto's.......
It must have drilled it's way into my brain for me to keep preferring to use 6Nxxx for midi interfacing......

Anyway....
 

hippy

Technical Support
Staff member
Tried and tested is usually a good reason to suggest using something. And there may be good reason for using or preferring a particular thing even if others seem to be good enough.
 
Top