PDA

View Full Version : button press AND hserout issues?!



Giulio
- 29th July 2011, 20:20
So... I dug out my ICD2 and selection of pics, to build myself a MIDI foot controller. Not having played with MIDI before, I set up a 16f628a, and tried the following:

DEFINE HSER_TXSTA 24H
DEFINE HSER_BAUD 31250

main:

[set relevant ports and CMCON, etc...]

loop:
hserout [144,90,90]
goto loop

Voila! My MIDI analyser shows note on, channel 1, regular as clockwork. Next, I need to send differing messages dependent on one of [n] push-to-make footswitches, so I tried:

if not porta.1 then
hserout [144,90,90]
endif

FAIL! Whereas the analyser was consistent before, now it fails every so often, showing error messages/system reset errors, etc., which leads me to believe there are timing issues with the USART that the if...then and porta.0 test is causing.


I don't want to write a hserout equivalent in assembler, as that's the whole point of using PicBasic Pro, but the timing issues and the button press test are making what should have been a simple project quite frustrating...

I feel that there's not enough documentation available which explains precisely which resources a given command uses, borne out of other frustrating isues I've had with timers, serial LCD display, etc...

Can anybody shed any light on this, or is it back to assembler for this whole project???

G

mackrackit
- 29th July 2011, 22:07
Have you turned of the analog on PORTA?

Giulio
- 29th July 2011, 22:37
Yes, I didn't want to waste space by showing my initialisation code, but:

CMCON = 7

and to isolate the one switch for testing:

TRISA = %00000010



G

mackrackit
- 29th July 2011, 22:46
if not porta.1 then
hserout [144,90,90]
endif

FAIL! Whereas the analyser was consistent before, now it fails every so often, showing error messages/system reset errors, etc., which leads me to believe there are timing issues with the USART that the if...then and porta.0

You may want to post your whole code...

Giulio
- 29th July 2011, 23:41
The porta.0 was a typo in my message - the code was exact. This works, every time, and doesn't skip a beat:


define OSC 20

DEFINE HSER_TXSTA 24H
DEFINE HSER_BAUD 31250

main:

CMCON = 7
TRISA = %00000010
TRISB = 0


loop:

hserout [144,90,90]

goto loop

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

This also works some of the time, but midi analyser shows 'error' periodically, and results are spurious:


define OSC 20

DEFINE HSER_TXSTA 24H
DEFINE HSER_BAUD 31250

main:

CMCON = 7
TRISA = %00000010
TRISB = 0


loop:

if not porta.1 then
hserout [144,90,90]
endif

goto loop

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

As I said, the if...then, and the test for button is most certainly doing something to the hserout command. I've tried putting a PAUSE [x] before and after and both before and after the hserout command, and it just slows things up, and still produces errors at the midi analyser... ???


G

cncmachineguy
- 30th July 2011, 00:02
Just for kicks, change the loop label to something other then loop. That is a keyword in later releases and maybe it is playing up on the IF?

And maybe put a check after the HSEROUT to check if the transmission is done. Maybe the transmission is colliding with the next time through loop since there is nothing else to do? Of course that doesn't explain why the first one works.

Giulio
- 30th July 2011, 00:46
Did this:

define OSC 20

DEFINE HSER_TXSTA 24H
DEFINE HSER_BAUD 31250

main:

CMCON = 7
TRISA = %00000010


lp1:

hserout [147,100,100]

pause 1000

goto lp1

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

changed the label to lp1 [I usually get some kind of warning for reserved words], and added a long pause, and everything is fine. This corresponds to a note on message on channel 4 and, sure enough, the analyser shows exactly that, then the leds on the analyser go off according to the pause time [I've tried longer and shorter], and never misses a beat or gives an error.

Tried this, by way of a debug/test:


define OSC 20

DEFINE HSER_TXSTA 24H
DEFINE HSER_BAUD 31250

main:

CMCON = 7
TRISA = %00000010
TRISB = %00000000
OPTION_REG.7 = 0

lp1:

portb.3 = 0
if not porta.1 then
portb.3 = 1
endif

goto lp1

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

Sure enough, the led on pin 9, [portb.3] comes on when I press the switch connected to pin 18 [porta.1] and goes off when I release it, perfectly. The switch is pulled up to 5v via a 10k resistor, with the connection to the pin on the switch side of the resistor. Multimeter shows 5.18v on no press, and .082v on press, so well beyond the logic transition levels. Besides, I'm content with the switches, and have done a lot of playing with them, so I'm sure there's no issue with the hardware.

However, if I put the hserout command in, after the led on command, thus:


portb.3 = 0
if not porta.1 then
portb.3 = 1
hserout [144,100,100]
endif

then the note on message NEVER works, even with a suitable pause after. The analyser shows 'error', 'system reset', and the odd spurious code, like 'song select', which tells me that the timing for the hserout is failing badly.

I've wasted hours on this, and it's extremely frustrating. I've never coded the USART in assembler, but think my time might be best used doing so, instead of trying to work around the obvious problems inherent with this compiled language.

This reminds me of the problems I had with a serial LCD display. If I tried to use any interrupts, the display would go off, or show random characters, so the hserout command, or at least the assembly language behind it, must be using one or more of the timers, and other resources. Can I be bothered to pore over the disassembly? Probably not...

G

HenrikOlsson
- 30th July 2011, 07:48
Hi,
In your latest post, first example you're sending 144,100,100 and in the second example you're sending 147,100,100. I know nothing about MIDI and I suspect this has nothing to do with the problem but I mention it anyway.

OK, try this, just as a test:

HSEROUT [147, 100, 100] ' Dummy output, try removing this if "everything" works.

Pause 500

LP1:
If PortA.1 = 0 THEN
TXREG = 147 : GOSUB WaitForIt
TXREG = 100 : GOSUB WaitForIt
TXREG = 100 : GOSUB WaitForIt
While PortA.1 : WEND ' Wait for button to be released.
ENDIF
Goto LP1

WaitForIt:
While PIR1.4 : WEND ' Wait for TXREG to clear.
RETURN

Personally I don't think there's a problem with HSEROUT per se, I've never had any problem/bug with that but that's no guarantee. Unfortunately I don't have another suggestion on what might be the problem... You don't happen to have a logic analyzer that you can monitor the serial line with?

mister_e
- 30th July 2011, 09:02
The logic analyser may help, but for MIDI I would suggest you to install MIDI-OX and monitor it directly on your PC. It's like a Hyperterminal but for MIDI... assuming you have a USB to MIDI or else MIDI interface attached to your PC.

OR some Terminal may read 31250 BAUDs.

Still the issue make no sense, which version of PBP are you using? What if you use 3 HSEROUT?
what if you add

DEFINE HSER_RCSTA 90h

Last thing, are you really sure TXSTA need to be 24?

Giulio
- 30th July 2011, 09:29
Thanks for taking time out to consider this, guys!

I tried the code example, and no go. Funny thing is, Henrik, I wrote some inline assembly, which didn't work UNLESS I included a 'dummy' call to hserout at the top of the program, just as you have, and then the assembly worked fine?!?!

The same happened if I tried to do anything else, though.

mister_e, you are correct about the 24h. It DOES work occasionally, but is 'happier' with a 20h - again, I don't know why there should be a 'high' and 'low' mode, or at what speed the selection should be made?

I'm now thinking that the baud rate of 31250 'drifts' if you try to do anything else in the main loop, but is fine if the main loop is nice and stable and executes precisely the same instructions every time, maybe???

Again, thanks for the input!


G

mackrackit
- 30th July 2011, 10:16
It may be advantageous to use the high baud rate
(BRGH = 1) even for slower baud clocks. This is
because the FOSC/(16(X + 1)) equation can reduce the
baud rate error in some cases.
Writing a new value to the SPBRG register causes the
BRG timer to be reset (or cleared) and ensures the
BRG does not wait for a timer overflow before
outputting the new baud rate.
The data on the RB1/RX/DT pin is sampled three times
by a majority detect circuit to determine if a high or a
low level is present at the RX pin.

I wonder....

HenrikOlsson
- 30th July 2011, 12:29
Hi,
The dummy HSEROUT just forces a "proper" setup of the USART, it can just as well be done manually. When your inline assembly didn't work it was missing something in USART setup. (Been there...)

Using Steves excellent tool (PICMultiCalc (thanks again Steve!)) suggests the following for 31250baud @ 20MHz:

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 39 ' 31250 Baud @ 20MHz, 0,0%
SPBRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator

Try that and remove the DEFINE HSERBAUD 31250 and see what happends. The weird thing is that since you say it works perfectly when you send continously the baudrate "must" be correct and adding the button check really shouldn't matter.

mister_e
- 30th July 2011, 13:41
Writing to the SPBRG register ought to solve the problem if it's a baudrate error thingy. IF so, my guess is the math done at compile time are so so. Hence the PîcMultiCalc.

PS: you'll need to remove those 2 line for the PIC16F628
SPBRGH = 0 BAUDCON.3 = 1 ' Enable 16 bit baudrate generator

Still the issue is weird, I would like to see the whole code....

Giulio
- 30th July 2011, 14:12
The whole code is above! It was just a few lines before things started going awry...

For everybody's info (and thanking you all again for your input), I transferred over to a 18F4550, which is total overkill for the MIDI project, but I had a couple lying around with future projects in mind.

Result: Works perfectly every time! Button press on a porta pin calls hserout, and the MIDI analyser never shows an error, just the expected leds lighting up according to note on, control change, etc...

So I'm now sticking with a sledgehammer to crack a nut - at least the sledgehammer works! I have no idea why the 16F628A is failing in this respect, and I shall avoid this particular chip for MIDI, but at least I now have a working prototype. Thanks again.

G

mister_e
- 31st July 2011, 01:22
I would bet it is not a 20Mhz rated one... or badly rated :D

Hammer time!