Optimising code (Things take too long)

For questions and comments on programming in general. And for any items that don't fit into the forums below.

Moderators: Benj, Mods

Post Reply
hyperion007
Posts: 528
Joined: Sat Dec 01, 2012 1:23 pm
Location: Sweden
Has thanked: 49 times
Been thanked: 101 times
Contact:

Optimising code (Things take too long)

Post by hyperion007 »

Hi,

I have a problem that I could use some input on.

When running my code, using a 48Mhz X-tal and no divide (I think this is maximum speed) on my PIC18F4550, some events take to much time to execute.

I am using two interrupts:
RB0INT
RB2INT

And two timers:
TMR0
TMR3


RB2INT is used to detect a change on a 128ppr optical encoder used for volume control.
- When INT occurs it reads the state of two pins to determine direction
- Then it calls one of two Macros that determines if a variable = X or not
- Then it calls a Macro that prints a number on the display
- Then it calls a Macro that bit bangs out a 32-bit long sequence, one bit at the time (8-bits and a Loop 4 times)
Then it returns to main

RB0INT is used to detect a change on a IR receiver.
- When INT occurs it starts TMR0 and switch edge on RB0INT.
- Then it stops the TMR0 at the next INT and reads the value of TMR0, resets TMR0, switch edge on RB0INT and finaly starts TMR0 again.
- It repeats this for all 32-bits of the IR code, keeping count of which bit it is currently processing.
- At every INT it also checks the value it got from TMR0 against a couple of IF arguments to determine if it was a "0" or "1"
- It then either writes a "1" and shifts the byte or just shifts the byte if it is a "0"
- It goes into a Switch when the received bit counter has reached 8,16,24,32 and I store the corresponding byte and reset the original byte
- When the bit counter is 24 I store byte 3 which is the one I am after. and also perform a LSB to MSB and then go to different macros depending on the value of this byte. for example the same macros asI use with RB2INT for volume up and down.
- After 32Bits I reset everything so it is ready to start again with the next IR code that is coming in.

TMR3 is used to scroll one line on a LCD (In my case VFD) I used TMR3 because it was the slowest one at 22Hz
- On TMR overflow the macro goes through a Switch. It does this 5 times, going through all 5 Switches before printing another 16 characters to the display.


Also I am using the USB Slave component, without the service macro. In the main loop I check-RX and respond accordingly.


So, the problem:

When I power on the PIC with everything connected it says "Volume: -96dB" on line 0. When I start playing a song in Spotify on my computer, it sends a string to the PIC via USB slave.
It is then displayed on line 1 on the LCD and starts scrolling exactly like I want it to. So far so good.
When I turn my optical encoder the number value on the display reacts lightning fast and the text is scrolling on line 1 very nicely still.

But when I press the volume up or down button repeatedly, the scrolling text slows down to a crawl and the remote control feels sluggish and sometimes misses a button press.

I had to disable TMR3 directly after RB0INT is triggered and then re-enable TMR3 again when TMR0 flows over at the end of an IR transmission is complete.
That was the only way I could come up with to ensure that every IR code got received.


So what can I do to have a scrolling text that isn't affected by other events (noticeable by the human eye), ensure the IR codes are received without error and keep the responsiveness of the optical encoder?

I have attached my fcf file and I realize that it might be a bit hard to get with all things going on but I have really tried to explain the code with annotations and comments.

Here is what it looks like when the text is scrolling:
http://youtu.be/_5U173JcX2g

What can I do different to speed things up?

One idea I had was to use a separate PIC that takes care of the IR routine and then sends only the one command Byte to the first PIC. But I have never tried using multiple PIC's and don't know what kind of communication I should use. Maybe CAN? something simple but reliable and with few lines :)

If you spot something I have done wrong please let me know.

Thanks so much for any and all help.
Attachments
PIC18F4550_Apple_RC V4_temp.fcf
(88.09 KiB) Downloaded 212 times

User avatar
LeighM
Matrix Staff
Posts: 2178
Joined: Tue Jan 17, 2012 10:07 am
Has thanked: 481 times
Been thanked: 699 times
Contact:

Re: Optimising code (Things take too long)

Post by LeighM »

Just as a general tip you need to do as little as possible in the interrupt routines themselves.
Maybe just set a variable value or a flag or both (i.e. set the global variable and set a flag to indicate it has changed)
Then test for the flag or variable change in the main loop and then do any calls to display or such like from there.

hyperion007
Posts: 528
Joined: Sat Dec 01, 2012 1:23 pm
Location: Sweden
Has thanked: 49 times
Been thanked: 101 times
Contact:

Re: Optimising code (Things take too long)

Post by hyperion007 »

Thanks Leigh.

I have now put everything in the main loop and calling macros from there instead of doing stuff in the Interrupt macros.

It did in fact improve things quite a bit. It is still not as fast as I would have liked bit less IR codes are "lost" and the remote feels more responsive. Also the scrolling isn't affected as much but it is still quite noticeable.

Here is the new and improved code
PIC18F4550_Apple_RC V4_temp.fcf
(108.36 KiB) Downloaded 236 times

Post Reply