News:

SMF for DIYStompboxes.com!

Main Menu

PIC based MIDI controller?

Started by tempus, March 28, 2018, 03:24:44 PM

Previous topic - Next topic

tempus

Thanks again for your help Tom.

Moving 10000000 to TRISC had no effect on the outcome. I mentioned the error messages because I wondered if they may be having some effect on the programming.

I'm beginning to run out of ideas, but here are some other things I've uncovered:

"11.2 AUSART Asynchronous Mode
In this mode, the AUSART uses standard Non-Returnto-
Zero (NRZ) format (one Start bit, eight or nine data
bits and one Stop bit). The most common data format
is 8 bits."

My programming is sending the 8 bits (or at least it's supposed to), but where are the start and stop bits coming from? I haven't done anything in the programming to send them, have I? Here's the code for one of my button pushes:

lead       call   dbdelayd      ;debounce switch down
         ;   switching
         bsf      STATUS,  RP0   ;bank 1
         btfss   TXSTA, 1      ;is TSR register empty?
          goto    $-1            ;yes, it's empty, load status byte
         bcf      STATUS,  RP0   ;bank 0
         movlw   b'10110001'      ;status byte = CC Ch1
      ;   movlw   0xB1         ;status byte = CC on Ch1
         movwf   TXREG          ;send status CC on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   b'00000001'      ;CC 1
      ;   movlw   0x01         ;CC 1
         movwf   TXREG         ;send CC 1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   b'00111111'      ;CC value 63
      ;   movlw   0x7f         ;CC value 127
         movwf   TXREG         ;send CC value 63 to laptop
         movlw   0x03         ;load PORTA with 00000011
         movwf   PORTA         ;turn Lead LED on, send clear signal to other PIC
leadup       btfss   PORTB,1         ;lead switch hi?
         goto   leadup         ;no - switch pressed, check again
         call   dbdelayu      ;debounce switch up
         bcf      PORTA, 0      ;turn clear bit off
         goto   switch         ;check switches again

You can see that I added a check to see if the TSR register is empty, and commented out some of the hex and replaced it with binary in case that was the problem. Also, notice that after all of the MIDI code is sent an LED is lit. In every one of the tests since I posted here the LED has come on. Does this mean that the MIDI code is getting sent? I'm thinking yes, since each byte has to be sent for the register to be empty, and we're checking to make sure that the register is empty before proceeding to the next command. If the registers weren't empty (i.e. bytes weren't being sent) then the code would never get to the turn on the LED stage, but would get stuck in the flag-check loop.

Can you see any problems here?


ElectricDruid

Ok, so if the LED is getting lit, then the code runs and the bytes get sent, in some form or another. That's all good.

What can you see on the TX output? Are you getting any activity? Get the o'scope on that output pin, and if you're sending three bytes, you should be able to see the line jumping up and down. If not, I'd guess the pin assignments still aren't right or the TX output isn't turned on or something of the type.

In fact, I'd guess that the set-up code still isn't right anyway. You can spend days bashing your head against some "send byte" routine, only to discover that you had some register set wrong way back in the "setup UART" routine. So we need to be sure that's sorted first. Most problems are getting the thing set up right. Often this stuff is easy to use once it's running correctly, but the hard part is getting there, since it doesn't give you any clues as to what's wrong - it just simply doesn't work.

Start by having a look at that TX output. Is it moving? If it is, we're getting warm, and all we've got to do it get it talking MIDI. If not, we first need to get it talking, then we need to get it talking MIDI. One step at a time and we'll get there (slowly maybe, but we will!).

Tom


tempus

Thanks again Tom.

Yes, that's been my experience with the other uC projects I've done - it takes a while to sort out how to get everything set up correctly, but once it is, it's fairly easy to work with things.

Good idea regarding the scope; I tested the TX pin and found that there was activity on it, but it's hard to see exactly what. My digital scope has an output window that summarizes what's been probed as well as the usual trace window. The output window showed f of 7.8KHz, +pulse width of 32uS and -PW of 96uS every time I grounded an input, and the trace screen sometimes (but not always) displayed (very quickly) a several drops (like negative going square waves - could have been 8 bits long, but it was too quick to see) from the +5v it was reading without grounding the input.

From this I'd conclude that there is something at the TX output, which would mean that the UART at least should be set up properly. This means that something is wrong with the bytes I'm sending or that something's wrong with my MIDI connection, unless it's possible that the UART is set up mostly correctly but is not sending information correctly.

What are your thoughts?

ElectricDruid

My thought is that 7.8KHz x 4 = 31.2, which looks suspiciously like it's 31.25KHz MIDI baud rate divided by four. Is it running at quarter speed? That would explain why your MIDI monitor isn't seeing anything.

Tom

tempus

Good eye man

We know that FOSC is 4MHz, thanks to the flash LED test you devised. There is also no value for X (it would have to be 7) in the BRG speed tables that would result in a 7.8KHz Baud rate (incidentally, and perhaps significantly, I left off the last digit in the frequency - the scope is showing 7.81KHz, adding weight to your argument). Do you mean is the BRG running at 1/4 speed? How would I test that?

Here's my code again, in case I've changed anything. Do you see any problems?

start       bsf      STATUS,RP0      
         bcf      STATUS,RP1      ;bank 1
         bsf    OSCCON,IRCF2    ;set int osc 110=4Mhz   
         bsf    OSCCON,IRCF1         
         bcf    OSCCON,IRCF0
         movlw   0x01         ;load w with 00000001     
         movwf   SPBRG         ;Set Transmit Baud Rate to 31.25KHz
         movlw   0x22         ;load w with 00100010     
         movwf   TXSTA         ;Set up to transmit 8-bit, asynch, lo-speed, BRGH lo      
         ;movlw   0x10         ;load w with 00010000     
         ;movwf   PIE1         ;enable AUSART transmit interrupt
         movlw   0x0F         ;conifgure all pins as
         movwf   ADCON1         ;   digital inputs
            bcf      OPTION_REG,7   ;enable PORTB pullups
         movlw   0x00         ;load w with 00000000
         movwf   TRISA         ;make PORTA outputs
         movlw   0xFF         ;load w with 1's
         movwf   TRISB         ;make PORTB inputs   
         movlw   0x80         ;load w with 10000000
         movwf   TRISC         ;make PORTC outputs, except RC7 (RX - pin18)
         bcf      STATUS,  RP0   ;bank 0
         movlw   0x80         ;load w with 10000000     
         movwf   RCSTA         ;enable UART
         movlw   0x00         ;load PORTA with 00000000
         movwf   PORTA         ;turn all LEDs off

Thanks again Tom

tempus

Wait though... Didn't you say that a 4MHz clock speed is a 1MHz instruction cycle? Would that /4 also apply to the measured baud rate?


ElectricDruid

Quote from: tempus on April 05, 2018, 08:13:10 PM
Wait though... Didn't you say that a 4MHz clock speed is a 1MHz instruction cycle? Would that /4 also apply to the measured baud rate?

That depends on whether the BRG uses the raw oscillator or the instruction clock. That varies from peripheral to peripheral.
Checking it again now, it definitely says "Fosc" which is the oscillator frequency, not the instruction clock, so it's 4MHz like we thought.

Checking the MIDI spec too, we're expecting a MIDI byte (10 bits in total - 8 data bits, plus start and stop "wrappers") to take 320uS. Now, you said you'd got 32uS pulses, which would be right. 7.8KHz data rate might be a red herring - we're not measuring a nice regular square wave after all. If the individual pulses are 32usec long, I'd say that's looking pretty likely.

Another test which I like to do is send an incrementing count. So you send a MIDI byte of 0, then 1, then 2 etc up to 255. Obviously this isn't a valid MIDI message, but the repeating pattern is easily viewable on a 'scope and you can see if it's doing what you expect.

I'm starting to run out of ideas though. We've looked at most of the obviously stuff already. There must be something in there somewhere...

Regards,
Tom


tempus

I plugged the MIDI out of a keyboard into my scope to see what I got from it. The results were inconsistent (probably due to the difficulty in getting a suitable sampling rate), but revealing nonetheless. A note on/not off event registered a frequency of 7.81KHZ with a + and - PW of 64 uS. Program changes were less consistent, but gave similar results - either a frequency of 7.81KHz or a multiple of it, and PWs of 32 - 128uS in 32uS intervals. From this, it seems like what I'm sending is fairly typical.

I'm wondering if the problem is in the actual MIDI messages I'm sending, i.e., wrong binary numbers, etc that may make what I'm trying to transmit not an actual MIDI message. Do these look right?

lead       call   dbdelayd      ;debounce switch down
         ;   switching
         Bank1   
         btfss   TXSTA, 1      ;is TSR register empty?
          goto    $-1            ;yes, it's empty, load status byte
         Bank0
         movlw   b'10110001'      ;status byte = CC Ch1
         movwf   TXREG          ;send status CC on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   b'00000001'      ;CC 1
         movwf   TXREG         ;send CC 1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   b'00111111'      ;CC value 63
         movwf   TXREG         ;send CC value 127 to laptop
         movlw   0x03         ;load PORTA with 00000011
         movwf   PORTA         ;turn Lead LED on, send clear signal to other PIC
leadup       btfss   PORTB,1         ;lead switch hi?
         goto   leadup         ;no - switch pressed, check again
         call   dbdelayu      ;debounce switch up
         bcf      PORTA, 0      ;turn clear bit off
         goto   switch         ;check switches again

Thanks again Tom

ElectricDruid

Maybe write the bytes in hex rather than binary, since that's usually how MIDI messages are expressed. But binary's fine if you're comfortable with it. I guess it depends what you've got on your crib sheet!

But that should be valid. &B1 is a control change on channel *2* not channel 1 (0-15 becomes channels 1-16). But that shouldn't matter - it's still valid data. then you send a control change number, and some data - fine; anything will do.

So you can see the TX line jumping up and down, and it's doing it in 32usec segments...this is all good. But you've still got nothing on the MIDI monitor?

What does the hardware look like between TX and whatever the MIDI monitor is? Perhaps that's the problem, and all this digging through software will get us nowhere.

Tom



tempus

Yes, I switched the code from hex to binary thinking that my hex might be inaccurate and that was the problem, and earlier had switched the channel # in case my MIDI device was fussy about the 0 being 1 thing. My status byte starts with 1011 (designating CC) and ends with 0001 (for MIDI channel 2) giving me a binary number 10110001 for my status byte. Then I've used 00000001 for CC #2, then 00111111 for (randomly picked) CC value 63. Is all that correct?

On the hardware end, I've connected pin 17 (TX) to a 220 ohm resistor to pin 4 on the MIDI jack, pin 2 (on the MIDI jack) to ground and pin 5 (on the MIDI jack) to a 220 ohm resistor to +5v. I'm not doing any receiving, so nothing else is connected to the MIDI jack, and nothing is connected to the RX pin. Is everything good there?

Thanks again Tom

ElectricDruid

Yes, that's all fine, as far as I can see. Your data being sent is fine. Your hardware sounds fine - after all, it ain't super-complicated for this job!

Ok, let's try something else. What happens if you just send &F8 (MIDI clock) or &FA (Start)? Those bytes don't depend on anything else to be interpreted, so they're about as minimal as it gets.

If that fails, do the sequential count test and see if you can see a binary count going up and up on the scope.

Tom

tempus

One other thing I forgot to mention about the MIDI keyboard probe - it is not at 5v like the uC is.


ElectricDruid

MIDI is a 5mA current loop, so the voltage isn't important.

Unless it's one of those "MIDI powered" gizmos that ignores the specification and assumes that there's X volts available. They might or might not work. Even in the 1980's when practically everything ran MIDI at 5V they weren't that reliable. Nowadays with a slew of 3.3V (and less) processors flying about, the idea is even worse.

Tom

tempus

#33
I tried the 0xF8 idea, with no luck. Using your counting idea, I tried this code into a scope:

test      movlw   0x00         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x01         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x02         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x03         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x04         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x05         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x06         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x07         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x08         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x09         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         goto   test

(most of the commenting can be ignored; I did a lot of copy and pasting and just didn't bother to clear out the comments). This did not produce the results I was expecting to see, so I thought I'd ask. I was expecting to see 1 pulse , followed by 2 pulses, etc., but instead there almost seems to be random pulses on the scope. The output window tells me that the + pulse width is always 32uS, but the -PW varies from 32 to 288uS in 32uS intervals. The output window results seem logical, but I can't actually slow things down enough to see a 32uS progression; I have to freeze the display at various points to get this, but it's probably safe to assume that it's going 32, 64, 96, 128, 160, 192, 224, 256 and 288 (though I never actually saw the 224 and 256).

Is this what I should be seeing?

tempus

Update to my last post:

I modified the code somewhat to insert a ~1s delay after each of the 10 bytes were sent to turn on an LED followed by another ~1s delay for the LED to turn off. This caused the LED to turn on and off 10 times. From this I've concluded that the instructions associated with each transmission are being completed. This also slowed down the transmissions to the scope so I could see things more clearly. In order for the output window to display results on the screen long enough for me to actually read them, I had to slow down the sampling rate such that I could see the pulse on the screen but without sufficient definition to read it. Going by the output window's results, I got:

32, 224   32, 192   64, 192   32,160   32, 32   64, 156   92, 160   25, 128   32, 64

with the 1st number in the pair being the +PW and the 2nd being the -PW. So, while I am getting 10 distinct transmissions, the PWs are not what I would have expected.

What do you think?


ElectricDruid

I think you're doing it the hard way. A basic binary count going out could be done something like this:

test     move   COUNT, w      ; Get current count
          movwf   TXREG         ; Stick it in register to send
          btfss   PIR1, TXIF      ; Has TXREG cleared yet?
          goto    $-1                ; No, so go back and keep checking
          ; OK, it's cleared, the byte is sent
          incf   COUNT, f           ; Move to the next value
          goto test

I haven't tried it, but that's the gist. It'll produce an incrementing binary count on the output, from 0-255 (If you wanted to limit it to data bytes, you could AND the WREG with 127 before you stick it into TXREG). That means that you'll see the ten bits of each MIDI byte (Start bit, data byte, Stop bit) and the middle 8 bits will be incrementing in binary. That is to say, they'll be doing something like this:

0000
0001
0010
0011
0100
0101
0110
0101
0111
1000
1001
1010
1011
1100
1101
1110
1111

Now, there's something important to notice there, which is that each column flashes on and off half as fast as the column to its right. E.g. the rightmost column goes on then off every time, the next column stays on twice then goes off twice, next column is off four times, then on four times, etc.

That has the (useful) effect of slowing things that we can't keep up with down to a speed we can keep up with. If those bytes are coming in at roughly 3 per msec as they should be, the first column is flashing at 1562Hz, but the next one is only at 781Hz, and the next at 390, and the next at 195, and the next at 97, and the next at 48, the next at 24, and the last at 12.2Hz. That forms a distinctive pattern of flickering that'll you'll recognise. If it's going too fast, rather than sticking a delay between the bytes, change the BRG setting and send the output at a much slower speed. You need to be sure that the bytes you're outputting are the bytes you think you're outputting, and the best way to do that is to *see* them.

HTH,
Tom

potul

Do you have your full  code? I can try to test it on my side and see if I can spot something...

Mat

potul

Do you have any means to monitor the serial output? something like this is useful to monitor from a term software in a PC.

https://www.ebay.com/itm/CP2102-USB-2-0-to-UART-TTL-6PIN-Module-Serial-Converter-Adapter-Red-Silver-TS/222617611551?epid=1286993754&hash=item33d50b2d1f:g:FqYAAOSwxbpZl5x6

at least to check the bytes are sent correctly and at the proper speed.

tempus

Hi Mat;

Thanks for your reply. Here is the code I'm using:

;=============PIC MIDI pedalboard===============2018 03 29===

      list   p=pic16f737
      #include   <P16F737.inc>      ; processor specific variable definitions
      radix   hex
;
   __CONFIG    _CONFIG1,  _CP_OFF & _CCP2_RB3 & _DEBUG_OFF & _VBOR_2_0 & _BOREN_0 & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
   __CONFIG    _CONFIG2,  _BORSEN_0 & _IESO_OFF & _FCMEN_OFF
;------------------------------------------------------------
;            Counter locations

         cblock    0x20   
      dbcount
      dc1   
      dc2
      dc3   
         endc
;------------------------------------------------------------

;----------------------------------------
;   Bank Switching Macros



Bank0   macro         ; Select register bank 0
   bcf     STATUS,RP0
   bcf     STATUS,RP1
   endm
   
Bank1   macro         ; Select register bank 1
   bsf     STATUS,RP0
   bcf     STATUS,RP1
   endm

;----------------------------------------


         org      0x000
;
;Initialization

start       Bank1
         bsf    OSCCON,IRCF2    ;set int osc 110=4Mhz   
         bsf    OSCCON,IRCF1         
         bcf    OSCCON,IRCF0
         Bank0
         movlw   0x80         ;load w with 10000000     
         movwf   RCSTA         ;enable UART
         Bank1
         movlw   0x22         ;load w with 00100010     
         movwf   TXSTA         ;Set up to transmit 8-bit, asynch, lo-speed, BRGH lo
         movlw   0x01         ;load w with 00000001     
         movwf   SPBRG         ;Set Transmit Baud Rate to 31.25KHz
         movlw   0x0F         ;conifgure all pins as
         movwf   ADCON1         ;   digital inputs
            bcf      OPTION_REG,7   ;enable PORTB pullups
         movlw   0x00         ;load w with 00000000
         movwf   TRISA         ;make PORTA outputs
         movlw   0xFF         ;load w with 1's
         movwf   TRISB         ;make PORTB inputs   
         movlw   0x80         ;load w with 10000000
         movwf   TRISC         ;make PORTC outputs, except RC7 (RX - pin18)
         Bank0
         movlw   0x00         ;load PORTA with 00000000
         movwf   PORTA         ;turn all LEDs off

;Main Program

switch      btfss   PORTB,0          ;bypass switch hi?
         goto   bypass         ;no - switch pressed
         btfss   PORTB,1          ;lead (1) switch hi?
         goto   test         ;no - switch pressed
         btfss   PORTB,2          ;chdla (2) switch hi?
         goto   chdla            ;no - switch pressed
         btfss   PORTB,3          ;cl (3) switch hi?
         goto   cl           ;no - switch pressed
         btfss   PORTB,4         ;clchdla (4) switch hi?
         goto   clchdla             ;no - switch pressed
         btfss   PORTB,5         ;cllngdla (5) switch hi?
         goto   cllngdla      ;no - switch pressed
         btfss   PORTB,6         ;wah (6) switch hi?
         goto   wah          ;no - switch pressed
         btfss   PORTB,7          ;clear LEDs from other PIC in hi?
         goto   clear         ;no - lo
         goto   switch         ;check all switches again

;               Switch Actions

bypass      call   dbdelayd      ;debounce switch down
         ;   switching
         movlw   0xC0         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x00         ;patch 0
         movwf   TXREG         ;send patch change 0 to laptop
         movlw   0x01         ;load PORTA with 00000001
         movwf   PORTA         ;turn all LEDs off, send clear signal to other PIC
bypassup   btfss   PORTB,0         ;bypass switch hi?
         goto   bypassup         ;no - switch pressed, check again
         call   dbdelayu      ;debounce switch up
         bcf      PORTC, 0      ;turn clear bit off
         goto   switch         ;check switches again

lead       call   dbdelayd      ;debounce switch down
         movlw   0xC0         ;status byte = program change on Ch1
         movwf   TXREG          ;send program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x01         ;patch 1
         movwf   TXREG         ;send patch change 1 to laptop
         movlw   0x03         ;load PORTA with 00000011
         movwf   PORTA         ;turn Lead LED on, send clear signal to other PIC
leadup       btfss   PORTB,1         ;lead switch hi?
         goto   leadup         ;no - switch pressed, check again
         call   dbdelayu      ;debounce switch up
         bcf      PORTA, 0      ;turn clear bit off
         goto   switch         ;check switches again

chdla       call   dbdelayd      ;debounce switch down
         ;   switching
         movlw   0xC0         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x02         ;patch 2
         movwf   TXREG         ;send patch change 2 to laptop
         movlw   0x05         ;load PORTA with 00000101
         movwf   PORTA         ;turn chdla LED on, send clear signal to other PIC
chdlaup       btfss   PORTB,2         ;chdla switch hi?
         goto   chdlaup         ;no - switch pressed, check again
         call   dbdelayu      ;debounce switch up
         bcf      PORTC, 0      ;turn clear bit off
         goto   switch         ;check switches again

cl          call   dbdelayd      ;debounce switch down
         ;   switching
         movlw   0xC0         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x03         ;patch 2
         movwf   TXREG         ;send patch change 3 to laptop
         movlw   0x09         ;load PORTA with 00001001
         movwf   PORTA         ;turn cl LED on, send clear signal to other PIC
clup       btfss   PORTB,3         ;lead switch hi?
         goto   clup             ;no - switch pressed, check again
         call   dbdelayu      ;debounce switch up
         bcf      PORTC, 0      ;turn clear bit off
         goto   switch         ;check switches again

clchdla       call   dbdelayd      ;debounce switch down
         ;   switching
         movlw   0xC0         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x04         ;patch 4
         movwf   TXREG         ;send patch change 4 to laptop
         movlw   0x11         ;load PORTA with 00010001
         movwf   PORTA         ;turn clchdla LED on, send clear signal to other PIC
clchdlup    btfss   PORTB,4         ;lead switch hi?
         goto   clchdlup         ;no - switch pressed, check again
         call   dbdelayu      ;debounce switch up
         bcf      PORTC, 0      ;turn clear bit off
         goto   switch         ;check switches again

cllngdla      call   dbdelayd      ;debounce switch down
         ;   switching
         movlw   0xC0         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x05         ;patch 5
         movwf   TXREG         ;send patch change 5 to laptop
         movlw   0x21         ;load PORTA with 00100001
         movwf   PORTA         ;turn cllngdla LED on, send clear signal to other PIC
cllngdup    btfss   PORTB,5         ;lead switch hi?
         goto   cllngdup         ;no - switch pressed, check again
         call   dbdelayu      ;debounce switch up
         bcf      PORTC, 0      ;turn clear bit off
         goto   switch         ;check switches again

wah        call   dbdelayd      ;debounce switch down
         ;   switching
         movlw   0xC0         ;status byte = program change on Ch1
         movwf   TXREG          ;send status program change on Ch1 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x06         ;patch 6
         movwf   TXREG         ;send patch change 6 to laptop
         movlw   0x21         ;load PORTA with 01000001
         movwf   PORTA         ;turn wah LED on, send clear signal to other PIC
wahup       btfss   PORTB,6         ;lead switch hi?
         goto   wahup         ;no - switch pressed, check again
         call   dbdelayu      ;debounce switch up
         bcf      PORTC, 0      ;turn clear bit off
         goto   switch         ;check switches again

clear      call   dbdelayd      ;debounce switch down
         ;   switching
         movlw   0x00         ;load PORTA with 00000000
         movwf   PORTA         ;clear all LEDs
         goto   switch         ;check switches again

end

Also, I'm using MIDI-Ox on my laptop to monitor the MIDI transmissions.

Thanks for your help

tempus

Hi Tom;

I tried the count routine you suggested (using the AND to make it a byte though), so my code was:

         clrf   dbcount
test      movf    dbcount, w      ; Get current count
         andlw   0x7F         ;add 127
           movwf   TXREG         ; Stick it in register to send
            btfss   PIR1, TXIF      ; Has TXREG cleared yet?
            goto    $-1                ; No, so go back and keep checking
                        ; OK, it's cleared, the byte is sent
            incf   dbcount, f           ; Move to the next value
            goto test

I'm not exactly sure what I'm supposed to be seeing, but I've enclosed a screenshot. Is this the expected output?