Shop OBEX P1 Docs P2 Docs Learn Events
MIDI Receiver with SX/B — Parallax Forums

MIDI Receiver with SX/B

Jon WilliamsJon Williams Posts: 6,491
edited 2006-07-27 17:54 in Robotics
A lot of folks are interested in MIDI and have used BASIC Stamp 2 modules to send MIDI data.· The trouble with receiving it with the BASIC Stamp, though, is that a lot of data can be in the stream, and things can get a bit tricky.· In a *simple* MIDI system, to turn a note on and then off, we would like to get these messages:

$90·$3C·$64·· ·' middle C on
$80 $3C $00·· ·' middle C off

The *problem* for us using the BASIC Stamp is that most MIDI instruments actually take advantage of what is called Running Status, so the way the sequence above is typically transmitted is like this:

$90·$3C·$64·· ·' middle C on
$3C $00········' middle C off

Running Status means that the receiver must keep track of the last valid status (command)·byte and when a data byte shows up before another status byte, the last status (running status) gets used.· In this case, an Note On ($90) command of $00 is used to turn the note off.· The reason this strategy is used is that is saves a byte in the stream -- and that's precious time since MIDI serial is not that fast (31.25 kBaud).

Another thing that happens is system commands.· For example, I have·keyboard that constantly sends Active Sensing ($FE) bytes.· I did some analysis and saw that the output looked something like this:

FE FE FE FE 90 3C 64 FE FE FE 3C 00 B0 7B 00 FE FE ...

You can see the Note On and running status Note Off commands, as well as a Controller ($B0) message of All Notes Off ($7B).

After creating an LED modulator using the new SX/B compiler I decided to update that code to receive and buffer MIDI data, then create a MIDI framework for processing the data.· In the attached code and schematic I am simply controlling IO pins with Note On and Note Off commands, as well as the Controller All Notes Off and System Reset.· The framework is in place, however, for handling other MIDI messages.·

The attached project will control one octave (C, C#, D ... A, A#,·B --·12 notes) of outputs.· Two sets of switches are used: a 4-position DIP switch selects the MIDI channel, a 3-position DIP switch sets the device octave; control output 1 will respond to note C in that octave.· In my tests I'm simply controlling LEDs, but the outputs could easily be sent to ULN2x03s or similar devices to drive high-current components like relays and solenoids.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA


Post Edited (Jon Williams) : 4/17/2005 4:23:05 PM GMT

Comments

  • ForrestForrest Posts: 1,341
    edited 2005-04-18 00:11
    Now you just need to add some hamsters for MIDI control - like they've done here instruct1.cit.cornell.edu/courses/eceprojectsland/STUDENTPROJ/2002to2003/lil2/

    cool.gif
  • bishopbishop Posts: 82
    edited 2005-04-18 01:29
    dang...Jon is scary smart.
    good thing you dont work with nuclear technology too.
    :P

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    **************

    daniel woolston
    Teksystems Inc.
    www.danwoolston.com
    **************
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-04-18 12:46
    Thank you, Bishop, but I'm not particularly smart -- just industrious. My project is not unique, there are lots of them like it on the 'net -- but none with the SX and certainly none programmed with SX/B (in fact, most don't list their source).

    When I took my military entry exams for the Navy, the results were very good. The recruiter smiled and said, "Congratulations, Jon, we're going to make you a nuclear engineer on a submarine." To which I replied, "No, thanks, I'm going to go see the folks in the Air Force." That was one of the smarter moves of my life. That said, my expertise in radar and jamming techiques (I was an electronics countermeasures specialist) did not help me talk my way out of a speeding ticket a couple years ago....

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-04-18 13:23
    Now to go back on topic, great project Jon. Id love to see this project interfaced with Freescale's E field sensor MC33794 used as a touch panel. It provides support for 9 sensors and supposedly can detect near presses (senses you without you actually touching it) and as such can provide an additional channel for midi control for such things as note velocity. Or maybe a light organ like they use to show on sci-fi shows during the 70's.

    Post Edited (Paul Baker) : 5/16/2005 2:02:55 AM GMT
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-04-18 17:22
    John Barrowman and I have started a group at Parallax called Parallax EFX that will create products for those who build props and FX (movies, TV, Halloween and other displays, etc.) -- this project is the first of several MIDI ideas I have for that product group. The reason I keep the outputs to 12 was that we're intending for this to be used as a local prop controller in a large system. It could easily be extended though -- by adding a couple 74HC595s or using an SX48 one could do multiple octaves on the same device. That would make it easy for one to build a Close Enounters-style light panel to communicate with outerspace aliens that happen to land in the neighborhood.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA


    Post Edited (Jon Williams) : 4/18/2005 6:34:48 PM GMT
  • jwillisjwillis Posts: 8
    edited 2005-05-16 00:44
    Jon:

    Check out my thread on the SX applications forum. (SX/B serin problems) I have designed a 64 note MIDI decoder-driver for pipe organ applications. I tried to make things work without using interrupts or inserting assy language routines for the UART function, insteasd using serin, and all works well as long as there is a short time intercval between bytes in the midi on or off string. I need to adapt my program to work with an interrupt driven UART subroutine to allow time for processing the midi messages and outputing them to the buffers, but I do not yet understand how to code for this. Any help you can give me would be appreciated.

    Jim Willis
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-05-16 02:25
    Jim,

    If you take a few minutes with the code it will become quite easy to adapt -- so long as you use the same frequency the interrupt code is steady and will put recieved characters into a 16-byte circular buffer for you to recieve and decode. There's really nothing magic about the process, and using the buffer allows you to process complex messages while other characters are coming in.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA
  • jwillisjwillis Posts: 8
    edited 2005-05-17 19:14
    Thanks Jon

    I have gone over the code and it is straightforward. I have been working with ASSY language since the days of the
    DEC pdp-8 and the intel 8008, but SX/B and the interface between SX/B basic and SX assy subroutines is new. Gunther has been helpful. I have a handfull of 50 MHz resonators and perhaps one 20 MHz. Can you give me the constant values for 50 MHz or is 20 MHz necessary for stable operation?


    Thanks


    Jim Willis
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-05-17 20:20
    Without making any other changes, you would load the rxTimer variable with 15 for 1.5 bits, and 10 for 1 bit (no magic, simply multliplied each value by 50/20).· The program is designed for 20 MHz so that it runs fast enough to process the 31.25 kBaud input WHILE doing forground processing of data from the buffer.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Dallas, TX· USA
  • jwillisjwillis Posts: 8
    edited 2005-05-24 16:47
    Have the program running using your UART and buffer code with my own SX/B code to process the midi messages and interface to the external 64 bit register and driver circuitry. As soon as I have the schematic completed I will post it on the project forum if it is OK with you.

    Thanks Again

    Jim Willis
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-05-24 20:29
    Sure -- post it as a new project so that people can see it's available.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • elliottelliott Posts: 14
    edited 2005-08-17 20:29
    Hello-

    I've prototyped the jon's midi receiver project on the prodeveloper board and fixed a few hardware bugs. Now I'm going to drag my powerbook with logic over to my windows machine and start spitting MIDI at it. I'll make a test file that sweeps through 4 octaves pretty quickly on an "omni" channel setting. This should give me the ability to see the midi data I'm sending and if there is any response from the device.

    Another very simple question first. in the schematics there are dip switches to set the channel and octave. (I KNOW THIS IS A STUPID QUESTION, but I really am just learning). but short of using my sequencer to "sweep" through different channels and test for a response. Does anybody know how to set the dip switches to determine the channel?

    Like I said I feel kind of silly asking all of these simple questions. I read the Nutz and Voltz article on the "Joy's of experimenting" and I agree completely. I am prepared to use the sequencer and work backwards to figure it out. However, understanding the underlying concept would be great.

    thanks in advance
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2005-08-17 22:45
    Your hardware bugs, not mine, right?· I ran that project on my PDB and tested with two different keyboards; everything works fine when I hook it up.

    Studying the code (hint, hint...) will answer your questions. The channel switch is read with this routine:

    ' Use: GETCHANNEL
    ' -- reads channel inputs and refreshes 'channel'

    GETCHANNEL:
    · channel = ~CtrlHi············· ' get channel number
    · SWAP channel
    · channel = channel & $0F
    · RETURN

    Note that the switches get inverted (~ operator does that) -- so a closed switch is a "1" bit. All switches open then, is 0 (MIDI channel 1); all switches closed is 15 (MIDI channel 16).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • elliottelliott Posts: 14
    edited 2005-08-17 23:57
    absolutely, my hardware bug!

    thanks for the hints
  • elliottelliott Posts: 14
    edited 2005-08-19 02:36
    I've been working for the past 12 hours on the programming and the circuit. I think I may be getting the hang of it. A few more questions. Status: I slowly took apart the whole circuit and got it up and running. I have my powerbook throwing midi notes at it, and it works. However, I have a few questions about the debugger and what's happening in the code.

    first: somehow I have managed to get it to work in an "omni" mode. The Dip switches for the Octaves clearly work. However, unless I'm misunderstanding the code. The channel DIP switches are supposed to allow you to select a SPECIFIC channel. Now I i know that the mistake is mine, just looking for clarity on a few points.

    When establishing a breakpoint at line 366 in the code in the NOTEON subroutine (IF temp1 = channel THEN). If only the first (channel) dip switch is closed I get 00000001 in the W register (01) and F in the M register. That is dec 1 or midi channel 2. The strange thing is, if I play a keyboard on any channel when it is configured this way, as long as the notes are with in range, I get note ons. (?)

    And yet,

    if I set any other DIP combination (as an example): first two channel dip switches closed, second two open. I get 00000011 in the W register (03) and F in the M register. That should be Decimal 3, or midi channel 4. THE POINT IS WITH ANY OTHER COMBINATION OF DIP SWITCHES I GET NO REACTION (no Note ons).

    I realize (i think) that the program initially reads the the DIP channel setting in the GETCHANNEL subroutine so:
    When establishing a breakpoint at line 506 in the code in the GETCHANNEL subroutine ( MOV W,/Ctrl1Hi). If only the first (channel) dip switch is closed I get 00011111 in the W register (1F) and F in the M register. that would be(?) decimal 31 or midi channel 32.(?) So it appears as if the dip switches are being read.

    side note: I've been sending midi messages through both Logic and a very simple midi keyboard. I have been monitoring their output to confirm there channel settings

    I realize that I've been shooting questions left and right. I'm just really excited about this stuff and trying to learn. THANKS! jumpin.gif
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-05-05 03:44
    You can use the 74HC165 shift register to open up inputs.· Download StampWorks to see how you can code for the '165, one at a time, or several in a chain.· With three you'd get 24 inputs, and a 4th for 32 and don't use them all.· you'll need four bytes to store the data shifted back from the 165s -- each bit will hold the state of a pedal.·

    For specifics on BASIC Stamp coding your should post these kinds of question in that forum.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-05-06 14:57
    Please move your questions to the BASIC Stamp forum -- this thread has to do with a completed project and you've hijacked it with questions not related to that project.· In the BASIC Stamp forum you'll get more responses.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • VinnieVinnie Posts: 15
    edited 2006-07-23 20:00
    I'm looking forward to building this design but have a hardware question: why does the schematic use external pull-up resistors with the dip and octave switches, as the sx has the unique feature of internal pull-up resistors? they seem quite up to this job!?

    btw my final goal is a midi transformer device, so i also need to add midi output vp/uart to this code, so if anyone reading this has already done that, please share!! smile.gif
  • BeanBean Posts: 8,129
    edited 2006-07-24 12:59
    Vinnie,
    You are correct. The internal pull-ups could have been used instead.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com

    "The meaning of life, is to give life meaning" Unknown.
    ·
  • VinnieVinnie Posts: 15
    edited 2006-07-27 17:54
    one more thing; I was puzzled by the comment in the prg change and chan pressure subs:
    ' patch already in midiDB2

    after some 'clever' thinking, I assume Jon means midiDB1...?

    greetings
    Vinnie
Sign In or Register to comment.