DIYstompboxes.com

DIY Stompboxes => Digital & DSP => Topic started by: tempus on March 28, 2018, 03:24:44 PM

Title: PIC based MIDI controller?
Post by: tempus on March 28, 2018, 03:24:44 PM
Hey all;

I'm looking into designing and building a PIC based MIDI controller that will send MIDI messages to a laptop to switch on and off different VST effects. Surprisingly, I'm having a very difficult time finding any info on any PIC based MIDI controller. Has anyone made one, or can anyone point me in the right direction? I have some idea of what to do hardware wise, but seeing some sample code would be a huge help.

Thanks

Title: Re: PIC based MIDI controller?
Post by: potul on March 28, 2018, 05:18:09 PM
I built a PIC based MIDI foot controller long ago. But it was programmed in ASM. What PIC are you planning to use? Do you need to program it in C?
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on March 28, 2018, 06:51:04 PM
Ermmm...google? There's a ton of stuff on PIC MIDI controllers, surely?

That search query "PIC MIDI controllers" brings up a lot of useful results. What makes you say this is very difficult?

Tom
Title: Re: PIC based MIDI controller?
Post by: tempus on March 28, 2018, 07:28:59 PM
Ive got a couple of 16f737s around, and I figured I'd use one of them. I've programmed my previous PIC projects in asm.

ED, I have searched it up, but so far have found few useful results. There are a lot more things for Arduino, and a lot of the PIC articles just kind of explain how to accomplish it without going into any useful detail. Do you have a link that would be helpful?

Thanks
Title: Re: PIC based MIDI controller?
Post by: markseel on March 29, 2018, 01:13:26 PM
Disclaimer: Possible conflict of interest in this post since I am the creator of FlexFX and therefore may not be the most objective person to respond ...

Look at FlexFX the module.  It's a small 1"x1.4" module with a USB connector on it.  It has pins for power, ground, I2C, UART, and I2S (for audio).  Can be USB powered or self powered.  I2C and UART pins can be used for GPIO to sense foot switches or you can use I2C to interface to a port expander that interfaces to foot switches.  FlexFX was intended to support stomp box and high channel count USB/I2S audio applications with lots of DSP processing power ... of which you need none of.

But you can still use a FlexFX module and the free SDK (on GitHub) to sense switches and send MIDI to the host computer over USB.  You'd then have a USB MIDI controller with GPIO's.  The host computer would then see a MIDI device when you plug this in via USB.  If interested I can write up a quick code example - this might be a good example to add to the GitHub doco.

FlexFX will also have MIDI beat clock, MTC and MPC generation support.

https://github.com/markseel/flexfx_kit/blob/master/README.md

BTW the production of FlexFX modules, potentiometer/ADC/DAC main boards (to plug module into), and custom stomp box cases are being KickStarted in a couple of weeks.
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on March 29, 2018, 02:00:40 PM
Hi Tempus,

I've got some example code. It's for a set of MIDI bass pedals that I got off a dead electric organ and turned into a midi pedalboard.
I was going to post it here, but it exceeds the 20K message limit (didn't know about that til now!). Email me  (link below) and I'll send you a copy:

https://electricdruid.net/contact/ (https://electricdruid.net/contact/)

It uses a buffer to store outgoing MIDI bytes, and an interrupt pulls another byte out of the buffer when the last one has sent. That way the main code isn't held up waiting for a MIDI message to send. You can quickly dump a whole lot of stuff into the buffer and you're good to go. It will continue to send in the background. It uses 16F73 which isn't a million miles for the chip you suggested. If you're handy with ASM, you should be able to pull out the MIDI bits you need and chuck the rest away.

Tom
Title: Re: PIC based MIDI controller?
Post by: potul on March 30, 2018, 04:22:47 PM
I have a MIDI controller project using a 16f88

check it out  here:

http://www.diystompboxes.com/smfforum/index.php?topic=91291.0 (http://www.diystompboxes.com/smfforum/index.php?topic=91291.0)

You can see how the basic MIDI is done in the code.

Mat
Title: Re: PIC based MIDI controller?
Post by: tempus on March 30, 2018, 08:07:08 PM
You guys are awesome (and much more adventuresome than me)! Thank you so much for the help. Seeing the sample code clears up a lot of things and gets me on my way nicely. Your projects are much more involved and complex than mine, but I think I've figured some things out:

All I want to do is send a MIDI program change message to my laptop (via a recording interface), so I don't really need most of the stuff you guys have in your designs do I? Could I get away with just:

         movlw   0xC0   ;status byte = program change on Ch1
         movwf   TXREG ;send status program change on Ch1 to MIDI device
         call    senddla   ;wait 35ms for byte to be sent
         movlw   0x00   ;program #0
         movwf   TXREG   ;send prog change to #0 to MIDI device

?

I have the delay in there because my osc is running at 4MHz, so I figure the first byte won't be sent by the time the 2nd byte gets there without it. Oh, and I'm pretty sure I sorted out how to set up my UART.

Thanks again
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on March 31, 2018, 04:04:01 AM
Yes, if you don't mind hanging about waiting for the bytes to send, something like that will work.

One way to minimise the wait is to do a polled loop rather than a fixed delay of X msecs. You should be able to test either TXIF (in PIR4) or TRMT in TXSTA, with slightly different but equivalent results.
So something like this:

      movlw   0xC0   ;status byte = program change on Ch1
      movwf   TXREG ;send status program change on Ch1 to MIDI device
<memory page?>
      btfss    PIR4, TXIF      ; Has TXREG cleared yet?
      goto.    $-1
      ; Yes, it's clear, so send the next byte
         movlw   0x00   ;program #0
         movwf   TXREG   ;send prog change to #0 to MIDI device

HTH,
Tom
Title: Re: PIC based MIDI controller?
Post by: tempus on March 31, 2018, 09:07:38 AM
Hey Tom

Thanks again for your ongoing help.

That's definitely a better way to do it. A couple of questions though:

1. what do you mean by <memory page?>
2. What does $-1 do? I've seen this command in various code examples, and searches don't turn anything up - I figured this one out - it just goes to the previous line, so TXIF will continue to be tested until it is actually clear, yes?
3. Does the TXREG register clear once the byte has been sent (I'm assuming yes)?

Thanks
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on March 31, 2018, 03:29:24 PM
Quote from: tempus on March 31, 2018, 09:07:38 AM
Hey Tom

Thanks again for your ongoing help.

That's definitely a better way to do it. A couple of questions though:

1. what do you mean by <memory page?>

I mean that I can't remember off the top of my head what memory page PIR4 is in, and you may not be in the correct page when you enter the code, in which case you'd have to change it. I'm talking about "bank switching" which is another way of saying the same thing. The <memory page?> was just a reminder to think about which bank you're in.
The code I sent you included some macros for bank switching - just type "Bank0" or "Bank1" or whatever and the compiler pastes in the correct code to set up the RP0 and RP1 STATUS flags.

Quote
2. What does $-1 do? I've seen this command in various code examples, and searches don't turn anything up - I figured this one out - it just goes to the previous line, so TXIF will continue to be tested until it is actually clear, yes?
Yep, exactly. In some situations this can be dangerous because you can finish up in a loop which never ends. But if you're reasonably sure that the condition *has* to occur sooner or later, it's safe enough. In this case, we can be sure the byte will send - we just don't know if it will be received!

Quote
3. Does the TXREG register clear once the byte has been sent (I'm assuming yes)?
I don't know, and it doesn't matter. What we do know is that once it's been sent, we can safely stick another byte in there ready for sending. Whether it gets zeroed or not in between isn't really important.

Quote
Thanks

You're welcome.

HTH,
Tom
Title: Re: PIC based MIDI controller?
Post by: Blackaddr on March 31, 2018, 05:13:05 PM
Making a MIDI controller using a Teensy LC (https://www.pjrc.com/teensy/teensyLC.html) would be very easy way since you've got the Arudino MIDI library at your disposal, as well as Debounce and Rotary Encoder libraries ,not to mention analog libraries for reading pot values.

Disclosure, I'm the creator of the Teensy Guitar audio board (https://www.tindie.com/products/Blackaddr/arduino-teensy-guitar-audio-shield/?pt=ac_prod_search), so I'm biased as well in favour of the Teensy platform. The Teensy LC does not work with the Audio library (no sound procesing) but it's ideal for a MIDI controlller IMO.
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on March 31, 2018, 06:21:47 PM
I totally agree that using a Teensy LC or any other variant is a very easy way to make a MIDI controller and there are many available libraries that make this simple.

However...I can't really go along with such a course of action because it's COMPLETE OVERKILL!! Even the Teensy LC is a 32-bit, 48MHz processor with 62K flash and 8K RAM.
The 16F767 you were talking about is a 20MHz 8-bit chip with 8KWord of Flash and 368 *bytes* of RAM. And it's more than adequate for the task. If you don't believe me, check out the processors in any synth from the 1980's and then get an idea of what they made them do!! About ten times what we'd expect nowadays, in short.

So, yeah. One solution to any problem of this sort is "throw more computing power at it" and often that's the easiest solution. It may not be cheapest, but unless you're building 10,000 or 100,000 units, how much do you care about the extra $5? Probably not much. Multiply up and it becomes a big deal, but that's not our situation so go for your life.

Sorry, not trying to be a downer, and specifically not trying to diss the excellent work of those in the Teensy world (Blackaddr amongst them). I'm just a big fan of "doing more with less", rather than "doing less with more". I'm old-skool, I guess - I am...learned assembly on 6502.

Tom

Title: Re: PIC based MIDI controller?
Post by: potul on April 01, 2018, 02:23:41 AM
Quote from: ElectricDruid on March 31, 2018, 06:21:47 PM
I totally agree that using a Teensy LC or any other variant is a very easy way to make a MIDI controller and there are many available libraries that make this simple.

However...I can't really go along with such a course of action because it's COMPLETE OVERKILL!! Even the Teensy LC is a 32-bit, 48MHz processor with 62K flash and 8K RAM.
The 16F767 you were talking about is a 20MHz 8-bit chip with 8KWord of Flash and 368 *bytes* of RAM. And it's more than adequate for the task. If you don't believe me, check out the processors in any synth from the 1980's and then get an idea of what they made them do!! About ten times what we'd expect nowadays, in short.

So, yeah. One solution to any problem of this sort is "throw more computing power at it" and often that's the easiest solution. It may not be cheapest, but unless you're building 10,000 or 100,000 units, how much do you care about the extra $5? Probably not much. Multiply up and it becomes a big deal, but that's not our situation so go for your life.

Sorry, not trying to be a downer, and specifically not trying to diss the excellent work of those in the Teensy world (Blackaddr amongst them). I'm just a big fan of "doing more with less", rather than "doing less with more". I'm old-skool, I guess - I am...learned assembly on 6502.

Tom
I agree, but lately I find myself going the arduino route as well for this kind of projects. You can find arduino nano clones for around 3 $, and it's very convenient for a number of reasons:
-Tons of libraries available
-Easy programming
-No need for a programmer
-Power regulator included

On the downside, I still haven't found a way to emulate it that I like. I always develop and debug my software in an emulator, and MPLAB was my friend for PICs.

BTW, teensy is really an expensive overkill here. There are much cheaper small arduinos that can do the job
Title: Re: PIC based MIDI controller?
Post by: tempus on April 02, 2018, 10:41:51 AM
After having double (and triple checked) my code, I have been unsuccessful in sending any MIDI data. I've changed things slightly so that now I'm attempting to send button press messages using CCs (the software that I'm trying to control via MIDI accepts CC data as inputs). Here's an example of my switching code:

         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   0x00         ;CC 0
         movwf   TXREG         ;send CC 0 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x7f         ;CC value 127
         movwf   TXREG         ;send CC value 127 to laptop

Does it look OK? Also, I noticed this when reading through the 16f737 data sheet:

"The TXREG register is loaded with data in
software. The TSR register is not loaded until the Stop
bit has been transmitted from the previous load. As
soon as the Stop bit is transmitted, the TSR is loaded
with new data from the TXREG register (if available)."

What is a Stop bit and how do I transmit one? Is it already present in my MIDI command/data bytes?

Also, when I was testing my wiring, I discovered that there was +5v sitting on my TX pin. Is that normal? Referring again to the datasheet, I found:

"Bit SPEN (RCSTA<7>) and bits TRISC<7:6> have
to be set in order to configure pins RC6/TX/CK and
RC7/RX/DT as the Universal Synchronous
Asynchronous Receiver Transmitter."

I have this in my code:

   movlw   0x00         ;load w with 0's
         movwf   TRISC         ;make PORTC outputs

which should make PORTC all outputs, but it appears that I have to do something else to enable the TX pin, but I'm not sure what. I know that TRISC<7> means "TRISC bit 7, but what does TRISC<7:6> mean?

Thanks
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 02, 2018, 11:29:12 AM
Quote from: tempus on April 02, 2018, 10:41:51 AM
Here's an example of my switching code:

         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   0x00         ;CC 0
         movwf   TXREG         ;send CC 0 to laptop
         btfss   PIR1, TXIF      ;has TXREG cleared yet?
          goto    $-1            ;yes, it's clear, so send the next byte
         movlw   0x7f         ;CC value 127
         movwf   TXREG         ;send CC value 127 to laptop

Does it look OK?

Yes, it looks ok. PIR1 and TXREG are both in Bank0, so that should be fine.

Quote
Also, I noticed this when reading through the 16f737 data sheet:

"The TXREG register is loaded with data in
software. The TSR register is not loaded until the Stop
bit has been transmitted from the previous load. As
soon as the Stop bit is transmitted, the TSR is loaded
with new data from the TXREG register (if available)."

What is a Stop bit and how do I transmit one? Is it already present in my MIDI command/data bytes?
Yes. you don't have to send it yourself. As long as the UART is configured correctly for MIDI, it gets sent as part of the byte.


QuoteAlso, when I was testing my wiring, I discovered that there was +5v sitting on my TX pin.
Is that normal?

Yes.

Quote
Referring again to the datasheet, I found:

"Bit SPEN (RCSTA<7>) and bits TRISC<7:6> have
to be set in order to configure pins RC6/TX/CK and
RC7/RX/DT as the Universal Synchronous
Asynchronous Receiver Transmitter."

I have this in my code:

   movlw   0x00         ;load w with 0's
         movwf   TRISC         ;make PORTC outputs

which should make PORTC all outputs, but it appears that I have to do something else to enable the TX pin, but I'm not sure what. I know that TRISC<7> means "TRISC bit 7, but what does TRISC<7:6> mean?

It means "TRISC bits 6 through 7" - so both of them. <3:6> would be bits 3,4,5, and 6.

The SPEN bit ("EN" is an enable of some kind; "Serial Port" in this case) of the RCSTA register (one of the set-up/status registers for the UART) needs to be set too. Is that covered in your UART config code?

Sounds to me like you're very close. You've probably got one small bug in the UART config code.

Do you have a MIDI monitor so that you can see if you're sending valid bytes, even if not valid MIDI messages? I once struggled for ages with some MIDI code only to eventually connect it to a MIDI monitor and discover that it had been sending bytes correctly all along, but because I'd got a stray byte inversion command in the code somewhere (so 255 was being turned into 0) it wasn't producing any valid MIDI messages at all.

HTH,
Tom
Title: Re: PIC based MIDI controller?
Post by: tempus on April 02, 2018, 07:25:35 PM
Thanks again for your reply ED.

I do have a MIDI monitor, which shows no MIDI activity at all when I try to send a command. Searching more through the datasheet, I found this:

"When setting up an Asynchronous Transmission,
follow these steps:
1. Initialize the SPBRG register for the appropriate
baud rate. If a high-speed baud rate is desired,
set bit BRGH (see Section 11.1 "AUSART
Baud Rate Generator (BRG)").
2. Enable the asynchronous serial port by clearing
bit SYNC and setting bit SPEN.
3. If interrupts are desired, then set enable bit TXIE.
4. If 9-bit transmission is desired, then set transmit
bit TX9.
5. Enable the transmission by setting bit TXEN
which will also set bit TXIF.
6. If 9-bit transmission is selected, the ninth bit
should be loaded in bit TX9D.
7. Load data to the TXREG register (starts
transmission).
8. If using interrupts, ensure that GIE and PEIE
(bits 7 and 6) of the INTCON register are set."

I had already done these things, but does the order they are executed in matter? Here's what I've got in my code:

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   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   0x60         ;load w with 01100000
         movwf   TRISC         ;make PORTC outputs, enable TX and RX (pin 17 and 18)
         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

Anything out of line there?

Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 03, 2018, 06:08:46 AM
Hi Tempus,

Ok, let's have a look.

First: Have you *actually got* a 4MHz clock? I usually do a LED flash "hello world" to test this. Something like this:

FlashLED:
bsf   TEST_LED
nop
nop
nop
bcf  TEST_LED
nop
nop
goto  FlashLED


4MHz is a 1MHz instruction cycle, so 8 instructions gives us a 125KHz flash rate. Worth a check.

Next, you're using the low speed baud rate mode, so we have:

   Baud Rate = FOSC/(64(X + 1))

You stick 1 into SPBRG, so X=1, so:

   Baud rate = 4MHz/128 = 31250

So that looks fine.

Setting up the ports...Aha!

RC7 is RX, RC6 is TX. You've got those the wrong way around, Input should be Output, and vice versa.

Try that and see if it springs to life.

HTH,
Tom
Title: Re: PIC based MIDI controller?
Post by: tempus on April 03, 2018, 06:48:48 PM
Hey Tom;

Thanks again for your reply.

OK, so I loaded PORTC with 11000000, which had no effect on the results. Also, the datasheet says:

"Bit SPEN (RCSTA<7>) and bits TRISC<7:6> have
to be set in order to configure pins RC6/TX/CK and
RC7/RX/DT as the Universal Synchronous
Asynchronous Receiver Transmitter. "

Does that mean the both TRISC bits 7 and 6 need to be ones (which would make them both inputs), or do they mean set bit 7 to 1 and bit 6 to 0 (thus making 7 an in and 6 an out)? You would think that the TX bit would need to be configured as an output and RX an input....

Great idea to check the FOSC - I never would have thought of that technique. Checking with my scope I get a frequency of 110.1kHz, which would give 110.1 x 8 = 880.8 x 4 = 3.5232MHz. This would give us a baud rate of 3.5232MHz/128 = 27525. Is this close enough, or should I do some oscillator tweaking? Also, can we trust that my digital scope is actually giving an accurate reading of the flash rate? I messed around with OSCTUNE and got it up to 125KHz, but it had no effect on the results

On another note, when I build the project in MPASM, I get the following error messages:

...25 : Register in operand not in bank 0.  Ensure that bank bits are correct.

26 : Register in operand not in bank 0.  Ensure that bank bits are correct.

27 : Register in operand not in bank 0.  Ensure that bank bits are correct.


etc

The line numbers are all commands executed on Bank 1 (which is set in the 1st 2 lines of code). I'm assuming that MPASM is in err, since we've demonstrated that the OSC has been set at 4MHz?
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 04, 2018, 05:24:19 AM
Quote from: tempus on April 03, 2018, 06:48:48 PM
Hey Tom;

Thanks again for your reply.

OK, so I loaded PORTC with 11000000, which had no effect on the results. Also, the datasheet says:

"Bit SPEN (RCSTA<7>) and bits TRISC<7:6> have
to be set in order to configure pins RC6/TX/CK and
RC7/RX/DT as the Universal Synchronous
Asynchronous Receiver Transmitter. "

Does that mean the both TRISC bits 7 and 6 need to be ones (which would make them both inputs), or do they mean set bit 7 to 1 and bit 6 to 0 (thus making 7 an in and 6 an out)? You would think that the TX bit would need to be configured as an output and RX an input....

Exactly! They mean that "you need to set the bits" not "the bits need to be set". You need TRISC set with bit 7 to 1/Input and bit 6 set to 0/output. With Bit 6 set to 1, you've got TX set as an input and the UARTs output can't reach the pin - nothing will happen.
Also, you mean you changed TRISC, not PORTC. Messing with PORTC won't do anything useful.


Quote
Great idea to check the FOSC - I never would have thought of that technique. Checking with my scope I get a frequency of 110.1kHz, which would give 110.1 x 8 = 880.8 x 4 = 3.5232MHz. This would give us a baud rate of 3.5232MHz/128 = 27525. Is this close enough, or should I do some oscillator tweaking? Also, can we trust that my digital scope is actually giving an accurate reading of the flash rate? I messed around with OSCTUNE and got it up to 125KHz, but it had no effect on the results

No, that probably means that I forgot that "goto" uses two instruction cycles, which makes that loop nine instructions. 1MHz/9 = 111KHz.
So your 'scope is close enough.

Quote
On another note, when I build the project in MPASM, I get the following error messages:

...25 : Register in operand not in bank 0.  Ensure that bank bits are correct.

26 : Register in operand not in bank 0.  Ensure that bank bits are correct.

27 : Register in operand not in bank 0.  Ensure that bank bits are correct.

etc

The line numbers are all commands executed on Bank 1 (which is set in the 1st 2 lines of code). I'm assuming that MPASM is in err, since we've demonstrated that the OSC has been set at 4MHz?

Yep, it's useful to check that these lines match up with the ones where you've actually set Bank1. This is a "warning" not an "error", so its just a reminder and doesn't stop the code compiling. If it gets to bugging you, you can disable the warnings by sticking the following directive at the top of the code:

   Errorlevel -302

I usually put this under the usual "INCLUDE <p16fxxx.inc>" line.

HTH,
Tom
Title: Re: PIC based MIDI controller?
Post by: tempus on April 04, 2018, 02:49:21 PM
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?

Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 04, 2018, 03:36:48 PM
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

Title: Re: PIC based MIDI controller?
Post by: tempus on April 05, 2018, 02:39:00 PM
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?
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 05, 2018, 04:16:31 PM
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
Title: Re: PIC based MIDI controller?
Post by: tempus on April 05, 2018, 07:39:11 PM
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
Title: Re: PIC based MIDI controller?
Post by: 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?

Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 06, 2018, 12:15:59 PM
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

Title: Re: PIC based MIDI controller?
Post by: tempus on April 06, 2018, 02:08:41 PM
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
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 06, 2018, 03:40:54 PM
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


Title: Re: PIC based MIDI controller?
Post by: tempus on April 06, 2018, 05:31:37 PM
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
Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 06, 2018, 05:51:58 PM
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
Title: Re: PIC based MIDI controller?
Post by: tempus on April 06, 2018, 09:40:02 PM
One other thing I forgot to mention about the MIDI keyboard probe - it is not at 5v like the uC is.

Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 07, 2018, 05:07:38 AM
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
Title: Re: PIC based MIDI controller?
Post by: tempus on April 09, 2018, 10:27:13 AM
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?
Title: Re: PIC based MIDI controller?
Post by: tempus on April 09, 2018, 01:37:30 PM
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?

Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 09, 2018, 06:08:39 PM
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
Title: Re: PIC based MIDI controller?
Post by: potul on April 10, 2018, 05:47:13 AM
Do you have your full  code? I can try to test it on my side and see if I can spot something...

Mat
Title: Re: PIC based MIDI controller?
Post by: potul on April 10, 2018, 07:16:13 AM
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 (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.
Title: Re: PIC based MIDI controller?
Post by: tempus on April 10, 2018, 10:17:39 AM
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
Title: Re: PIC based MIDI controller?
Post by: tempus on April 10, 2018, 11:46:10 AM
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?


(https://s14.postimg.org/bexnz8okd/Count_test.jpg) (https://postimg.org/image/bexnz8okd/)
Title: Re: PIC based MIDI controller?
Post by: potul on April 10, 2018, 12:27:40 PM
Hi

I don't see anything at first glance....

I would suggest you use a serial TTL to usb converter and monitor the data somehow....
Does your scope have a digial analyser? Maybe you could get the values from there.

Another topic I have come up more than once is... did you connect the MIDI OUT corretly? It is not trivial to know what goest to pin 4 or 5 of the DIN connector... I've failed multiple times, so if it does not work, I always try it reversed.

Title: Re: PIC based MIDI controller?
Post by: tempus on April 10, 2018, 01:46:51 PM
Thank you so much - I switched my connections on pins 4 and 5 and I've got it running now. I originally got my pinout from this site:

http://www.rossbencina.com/code/midipic  where it shows pin 4 being the TX pin and pin 5 being the V+ pin, but checking this site:

https://www.midi.org/specifications/item/midi-din-electrical-specification

shows the opposite. The funny thing is that I tried switching the pins on a whim a week or so ago, with no success. Clearly my code wasn't up to snuff either. Just goes to show that you can't believe everything you read on a website.

Thanks a ton to you as well Tom for persevering and helping me to get this sorted out. You've been a great help.

Title: Re: PIC based MIDI controller?
Post by: ElectricDruid on April 10, 2018, 05:47:45 PM
Excellent! Glad to hear you've got it running! Nice work!

T.
Title: Re: PIC based MIDI controller?
Post by: potul on April 11, 2018, 02:22:16 AM
Good to see it works now. As I mentioned,... you are not the first one to fall into the trap.
In my case, I always have trouble figuring out which pin is 4 and 5 in the connector. I never remember if the schematics you find around are looking from behind or from the front of the connector.
I ended up taking pictures of my build and labeling the cables in the picture so that I can check it when needed.