News:

Let's find out together what makes a PIC Tick!

Main Menu

Bit Bang a serial output in the interrupt!

Started by Peter Truman, Jan 08, 2024, 03:35 AM

Previous topic - Next topic

Peter Truman

Hi all

I have a problem for which I can see a possible solution - but don't really know how to implement it  :-[

I have a fairly busy ISR running - with 2 USARTS and a timer (clock speed is 16MHz)

USART 1 is for 'real world' data (via a MAX232 to a PC or other equipment) at 19200 baud
USART 2 is for incoming data only - from a very slow radio modem at 1200 baud

I'm also using a software Serial output (RSout - inverted) to drive a remote LCD screen (at 9600 baud)

On existing hardware - so no substantial changes allowed

I'm using ring buffers on the 2 USARTS - generally without a problem

My problem arises when I use the RSout command to write to the LCD - I find I get a lot of usart2 overrun errors (I can't predict or control when the radio data comes in)

If I turn off interrupts while I use RSout I can write freely to the LCD but I miss a lot of data coming in on USART2

So I can't really win - if I turn off interrupts to get clean text on my LCD - I miss incoming data OR if I leave them on, I get USART2 Overrun errors

The only way to get reliable data on USART 2 at present is not to use RSout to write to the LCD (but I have no choice)

Would it be possible to effectively bit bang another USART Tx in the existing isr?

I thought perhaps using another timer I could fire off a byte of the LCD data every time the second clock ticked over and effectively avoid each operation affecting the other.

Can anyone shed any light on whether this is possible - and if so, how to work out all the timing etc?

Many thanks in anticipation



SCV

Been there, tried that...
Allocate a spare timer/ISR to tick at the 9600 baud interval (104uS). In the timers ISR, bit bash each bit. When no more data is to be sent, turn off int. It's not exact, but is as close as you can get without hardware. Lowering LCD baud rate will also help. Keep any ISR as short as possible and prepare each bit outside the ISR, essentially the ISR just looks up the pin state according to a bit index.

Tim

kcsl

Peter,
I've been having the same problem with several projects recently; too much to do, with h/w buffers not deep enough on too few serial ports.

As I see it, the problem will always be that the CPU can only really do one thing at a time. If you're in the middle of bit-banging and a timer and/or interrupt fires, you are going to mess up the timings, and disabling interrupts causes other problems.
You can only do so much with one CPU core.

The only options I could see were runs the comms much slower, move to PICs with more hardware UARTS (which may not always help anyway), run program code faster (or execute less instructions) so you have more time to service everything, look at dual core devices; ie the dsPIC33CH family, or offload the comms to slave PICs.

I'll be interested if you come up with something else.

Regards,
Joe

There's no room for optimism in software or hardware engineering.

trastikata

#3
Question here, maybe I am missing something, but aren't EUARTs full duplex peripherals?

So while you are using the hardware RX buffers with interrupts you can use in the same time the hardware TX buffer also with interrupts. Because writing and reading from the EUART buffers is very fast you won't miss or mess a thing. Thus use one of the EUARTs TX pin for that LCD.

And if you need a TX pin for the initial set up of the devices connected to the RX, then use any other pin for that with the RSOUT.

Peter Truman

Quote from: trastikata on Jan 08, 2024, 11:11 AMQuestion here, maybe I am missing something, but aren't EUARTs full duplex peripherals?

So while you are using the hardware RX buffers with interrupts you can use in the same time the hardware TX buffer also with interrupts. Because writing and reading from the EUART buffers is very fast you won't miss or mess a thing. Thus use one of the EUARTs TX pin for that LCD.

And if you need a TX pin for the initial set up of the devices connected to the RX, then use any other pin for that with the RSOUT.
I did look at doing that since I'm not using the USART for the radio data - but there are two issues in my case, first one is that I need to run the LCD data at 9600 and the radio is 1200 baud (there are a lot of LCD's screens out there already and I want to try to keep everything backwardly compatible) and the second is that I would have to make a hardware change to get at that pin. But a sensible approach if it were possible - thanks

Peter Truman

Quote from: kcsl on Jan 08, 2024, 10:07 AMPeter,
I've been having the same problem with several projects recently; too much to do, with h/w buffers not deep enough on too few serial ports.

As I see it, the problem will always be that the CPU can only really do one thing at a time. If you're in the middle of bit-banging and a timer and/or interrupt fires, you are going to mess up the timings, and disabling interrupts causes other problems.
You can only do so much with one CPU core.

The only options I could see were runs the comms much slower, move to PICs with more hardware UARTS (which may not always help anyway), run program code faster (or execute less instructions) so you have more time to service everything, look at dual core devices; ie the dsPIC33CH family, or offload the comms to slave PICs.

I'll be interested if you come up with something else.

Regards,
Joe


Yes - I'm amazed at how much you can do with a little 8 bit uC as it is!. I do some hardware for another project that uses the PIC32MZ - that's an amazing little device - fortunately (or unfortunatly) I don't do the firmware for that project - I leave that to the pro's)

What I have done since my original post, is modify my LCD write procedure so it no longer writes to the lcd if the text to display hasn't changed. I was writing to it every 200ms and that was just getting in the way. Now, since the only change to the text (in the main loop) is dictated by data from the radio - I can effectively not use the RSOUT until I have received an update from the radio - and then only if the data has changed. So that made a huge difference. Your advice about bitbanging my own usart is appreciated - I do have a good logic analyser so I'm sure I could work through it. Thanks again