Shop OBEX P1 Docs P2 Docs Learn Events
Trouble with midi.tx - any way to test? — Parallax Forums

Trouble with midi.tx - any way to test?

tuffstufftuffstuff Posts: 24
edited 2013-10-03 14:12 in Propeller 1
I'm having some trouble sending midi messages. I think my midi send circuit isn't correct but I'm having trouble testing it. I have come up with a way to test if the midi messages are outputting to the midi jack, but its isn't working that well. I have set up a couple of cogs, one reads the midi messages the other sends and prints what is being read to the terminal. Here is my code:
CON
_clkmode = xtal1+pll16x
_xinfreq = 5_000_000
 
OBJ
  pst   : "Parallax Serial Terminal"
  midi  : "FullDuplexSerial"

VAR

  LONG stack[500]
 
PUB Play | Index

  pst.Start(115200)
  midi.start(0, 5, %0000, 31250)
  cognew(Read, @stack) 
             
  repeat
    repeat Index from 0 to 3
      midi.tx($90) 
      midi.tx(midimessage[Index])
      pst.str(string("|"))
      waitcnt(clkfreq + cnt)

PUB Read | a,b,c

  pst.Start(115200)
  midi.start( 0, 5, %0000, 31250 )

  repeat
    'pst.str(string("|"))
    
    a := midi.rx
    b := midi.rx
    c := midi.rx
    pst.hex(a,2)
    pst.hex(b,2)
    pst.hex(c,2) 
    
DAT

midimessage WORD $3755, $3700, $4055, $4000

There are two cogs running one sends midi messages the other reads them and prints them to the terminal. The circuit is a midi in midi out circuit. I have tried a few on this forum to no avail.

What's wierd about the code above that when I comment out the midi.rx lines in the second cog and un-comment out "pst.str(string("|"))". It will flood the terminal with pipes like you might expect. When I un-comment the midi.rx the pipes stop. Is the second cog freezing? Does that term apply?

Can anyone suggest a better way of testing the midi out to read what it is outputting?

Thanks!

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2013-10-01 22:18
    Your MIDI reader should have its pins crossed and therefore needs another (temporary) serial device. Also, midimessage is a word array but tx only sends a byte. Assuming little endian it could look like this:
    CON
    _clkmode = xtal1+pll16x
    _xinfreq = 5_000_000
     
    OBJ
      pst   : "Parallax Serial Terminal"
      midi[2] : "FullDuplexSerial"
    
    VAR
      LONG stack[500]
     
    PUB Play | Index
    
      pst.Start(115200)
      midi[0].start(0, 5, %0000, 31250)
      cognew(Read, @stack) 
    
      waitcnt(clkfreq*3 + cnt)
                 
      repeat
        repeat Index from 0 to 3
          midi[0].tx($90)
          midi[0].tx(midimessage[Index])
          midi[0].tx(midimessage[Index] >> 8)
          waitcnt(clkfreq + cnt)
    
    PUB Read
    
      midi[1].start(5, 0, %0000, 31250)
    
      repeat
        pst.hex(midi[1].rx, 2)
        
    DAT
    
    midimessage word $3755, $3700, $4055, $4000
    
    DAT
    
  • AribaAriba Posts: 2,690
    edited 2013-10-01 22:38
    Here is how I would do it:
    CON
      _clkmode = xtal1+pll16x
      _xinfreq = 5_000_000
     
    OBJ
      pst   : "FullDuplexSerial"
      midi  : "FullDuplexSerial"
    
    PUB Play | Index,evt,time,d
    
      pst.Start(31, 30, 0, 115200)
      midi.start(0, 5, %0000, 31250)
                 
      repeat
        repeat evt from 0 to 3        '4 events
    
          repeat Index from 0 to 2    'send 3 bytes 
            midi.tx(midimessage[evt*3+Index])
    
          time := cnt+clkfreq         'for 1 second
          repeat while time-cnt > 0
            d := midi.rxcheck         'get received from buffer
            if d=>0
              pst.hex(d,2)            'and show on terminal
              pst.tx(" ")
          pst.tx("|")
    
    DAT
    midimessage
      byte  $90,$37,$55, $90,$37,$00
      byte  $90,$40,$55, $90,$40,$00
    

    Andy
  • kuronekokuroneko Posts: 3,623
    edited 2013-10-01 22:42
    After seeing Andy's post, my example will simply verify what you send, not what's coming from an external device. Sorry for the confusion.
  • tuffstufftuffstuff Posts: 24
    edited 2013-10-02 22:35
    Thank you both for you comments. I am now able to read the midi out properly. One of the great things about this forum is seeing how other people structure their code. I have a few questions concerning how you all did yours.

    Andy, I see that you initialized two "FullDuplexSerial" objects, one for printing to the terminal and the other for reading and writing midi messages. I didn't know you could use FDS for writing to the terminal. I will need to learn more about these serial objects. My question is why did you use two objects for this? Why can't we print to the terminal with the same object that we are reading and writing midi data with?

    Kuroneko, you used square brackets in an interesting way. Can you explain what their functions are? Are you initializing two object also in a sort of short hand way?
    midi[2] : "FullDuplexSerial"
    ... 
    midi[0].start(0, 5, 00, 31250)
    ...             
    midi[0].tx($90)
    midi[0].tx(midimessage[Index])
    midi[0].tx(midimessage[Index] >> 8)
    ...
    midi[1].start(5, 0, 00, 31250)
    


    Thanks again for the help!
  • kuronekokuroneko Posts: 3,623
    edited 2013-10-02 22:46
    tuffstuff wrote: »
    ... you used square brackets in an interesting way. Can you explain what their functions are? Are you initializing two object also in a sort of short hand way?
    This usage pattern is for an array of objects. I could have used midi_one and midi_two, in this case however I declared two objects (midi[2]) and use both of them with index 0 and 1. In the end it's down to your personal preferences which style you use, e.g. using an array lets you call all object instances in a loop. Otherwise you'd have to spell them out. HTH
    object_1.start(1)
      object_2.start(2)
      object_3.start(3)
    
    ' vs
    
      repeat n from 1 to 3
        object[n].start(n)
    
  • AribaAriba Posts: 2,690
    edited 2013-10-02 23:41
    tuffstuff wrote: »
    Andy, I see that you initialized two "FullDuplexSerial" objects, one for printing to the terminal and the other for reading and writing midi messages. I didn't know you could use FDS for writing to the terminal. I will need to learn more about these serial objects. My question is why did you use two objects for this? Why can't we print to the terminal with the same object that we are reading and writing midi data with?
    The USB chip on the board is just a USB to serial converter, the Propeller and the Terminal see a serial connection, also if there is a USB line in between. The PST object is a modified FullDuplexSerial (FDS) object with a few different methodes. I'm more used to the FDS.

    Using two times the same object spares also a lot of RAM because the same object exists only one time in hub-ram, only the VAR sections of the two FDS objects need their own memory.

    You need two serial objects because one handles serial in and out on pin 0 and 5 with 31250 baud, and the other serial in and out on pin 30 and 31 with 115.2 kBaud. The FDS object provides only one in and one out channel with the same baudrate. And you can not switch the pin and baudrate without stopping and restarting the object.

    Andy
  • tuffstufftuffstuff Posts: 24
    edited 2013-10-03 11:50
    Andy, so you initialized two serial objects to use two seperate baud rates with out having to dynamically set the pins and baud rates. The two object actually exist as one in memory, so there is no penalty for doing this.

    By using code example to write my code I overlooked the two distinct baud rates in my two serial objects. Why do we use 115200 for writing to the terminal and 31250 for reading/writing pins?

    Thanks again,
  • Mike GreenMike Green Posts: 23,101
    edited 2013-10-03 12:11
    31250 is not a standard Baud for terminals or terminal programs. 115200 is a commonly used Baud for fast terminal programs and is the default for some of them making its use convenient.

    Common Bauds these days: 9600, 19200, 38400, 57600, 115200. Still used occasionally: 1200, 2400, 4800.
  • AribaAriba Posts: 2,690
    edited 2013-10-03 14:12
    tuffstuff wrote: »
    Andy, so you initialized two serial objects to use two seperate baud rates with out having to dynamically set the pins and baud rates. The two object actually exist as one in memory, so there is no penalty for doing this.

    By using code example to write my code I overlooked the two distinct baud rates in my two serial objects. Why do we use 115200 for writing to the terminal and 31250 for reading/writing pins?

    Thanks again,

    The penalty is that every instance of the FDS object needs its own cog, a few variables and two 16 byte buffers one for receive, one for transmit.
    Also if you could use the same baudrate you need two transmitters (MIDI and Terminal) and one receiver (MIDI). One FDS object can handle only one trnsmitter.
    There is also a 4 port serial object, which could handle all 3 serial channels with one cog.

    Andy
Sign In or Register to comment.