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.
Optimising code (Things take too long)
-
- 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)
- Attachments
-
- PIC18F4550_Apple_RC V4_temp.fcf
- (88.09 KiB) Downloaded 212 times
- 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)
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.
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.
-
- 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)
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
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