PDA

View Full Version : picbasic pro optimizations



markedwards
- 30th September 2005, 00:24
Cliff Griffin lists several picbasic pro optimizations at http://www.rcfaq.com/PIC/optimize.htm. Are there more optimization tips?


@ incf _Time ,1
This compiles two words shorter, but is functionally equivalent to
Time = Time + 1

If... AND... Then's
Using two IF commands saves five words

looptest:
'if (i=1) and (k=1) then looptest

Instead, use this technique:
if i=1 then
if k=1 then looptest

Darrel Taylor
- 30th September 2005, 05:12
You might want to be carefull with those techniques.

The way they save code space is by bypassing the normal Bank switching, and Code Page changes that PBP needs to keep track of, to continue working correctly. Under the right circumstances they can indeed save Code Space.   But, just at the time when you "Need" to have the program working, you'll be chasing bugs that seem like they "Just can't be happening". He hints at the problem with a "NOTE:" but I think it's more serious than that.   Especialy with large programs. A.K.A. Harder to Debug.

Granted, others are valid, like separating "ANDed" IF statements etc. But, bypassing PBP's internal processes can be risky.
<br>

markedwards
- 30th September 2005, 13:47
Darrel,

Thanks for the reply and caution.
I was surprised there wasn't more discussion on optimizing for performance
and saving code space on the forum. I have only written a few picbasic programs. I try to save codespace and sometimes improve speed.

Thanks for posting your averaging routine, I recommended it a few times.


Mark

mister_e
- 30th September 2005, 17:41
Somethig interesting to use http://www.picbasic.co.uk/forum/showthread.php?t=2418

Really handy to compare between 2 piece of code.

There's always a midpoint between a tight code and a 'bullet proof' code. Yes it's interesting to have some way to reduce code size but if it gives more potential bugs or headache... will you aprreciate your tight code even if it gaves you extra debug hours? I don't think so :)

PBP is stable and mature, i don't like to play with his internal ressource to save few bytes only to save few cents by choosing a smaller PIC to do the job. well it's my opinion after doing that on a full 64K of code.... yeah it's working fine now.. no problem at all. I just hope to have a 28Pin device with much codespace one day... probably there's already one that i didn't see. I'd use a 18F2680. Code overlay could be an option at that time... i'd just challenge myself to fit everything in the same PIC.

about the speed... depending how critical your application is, using a higher crystal speed or use some assembler line could do the job as well.

each project is different so i don't think there's an universal way to do one thing.

Using built-in function for an application that don't need all the bells and ring and data handling include in the built-in function like ADCIN,SEROUT, HSEROUT,HSEROUT,HPWM and much other is often killer. Save code space by writing/reading directly to the internal register is the way to go. In many case, it will be done much faster too. Oh yeah much tricky... of course, but you have the full control of!

How to save code space, how to write a program is an endless story. In many case, i'll prefer the internal register way against built-in function... well for my own application. To teach to someone else, to do some test, the use of built-in function seems to be easier/faster to understand.

HTH

Darrel Taylor
- 30th September 2005, 18:18
Mark,

Hey, glad you like the averaging routine. I was wondering if you could do me a favor? &nbsp; I made a modification to it a little while ago. &nbsp; You know how the least sigificant digit will "wobble" back and forth between 2 numbers? It's half-way between 2 numbers and it can't quite figure out which one it should be. &nbsp; Well, the modification adds hysterisis to the averaging routine to eliminate that.

None of my current projects use the averaging, so I haven't had a chance to test it yet. &nbsp; I gave it to someone else, but never heard back from him. I assume that means it worked.

If you have some extra time, maybe you could try this out.
'************************************************* ***************
'* Name : Average_Hyst.pbp *
'* Author : Darrel Taylor *
'* Date : 7/19/2005 *
'* Version : 3.0 *
'* Notes : Modified to use Hysterisis *
'* : Use as an INCLUDE file *
'************************************************* ***************
' This routine will keep a "Running Average" of 10-bit Analog Values
' Instead of adding a bunch of values together and then dividing by the number
' of samples, it averages each sample into the final result immediately.
' This eliminates the need for 32 bit math.
' To allow it to "Catch up" to large changes, set the FAspread to an
' acceptable range.
' Simply place the new number in VALUE and GoSub Average
' The Average (with Hysterisis) will be returned into the same variable VALUE

'---- [ User Options ] ---------------------------------------------------------
HystLevel CON 7 ' 7 = .7 of the Least Significant Digit
' Valid HystLevel is from 6 to 13
AvgCount CON 16 ' = Number of samples to average. For best response
' times, keep AvgCount as small as you can
FAspread CON 50 ' = Fast Average threshold +/-
' FAspread should be larger than the worst possible
' noise in the A/D conversion.
'-------------------------------------------------------------------------------

AVGchanged VAR BIT ' 1 indicates that the Average Value has changed
' you have to clear this bit after using it
ADavg VAR WORD ' Stores the current Average
ADhyst VAR WORD ' Stores the current Value for Hysterisis
Value VAR WORD ' Input / Output variable to be averaged
spread CON FAspread * 10 ' adjust spread *10 for Hyst.

GOTO OverAverage
' -=-=-=-=-=-= Average Analog values -=-=-=-=-=-=-=-=-=-=
Average:
Value = Value * 10 ' Scale value up for hysterisis
IF Value = ADavg Then NoChange ' if they're the same, nothing to do
IF ABS (Value - ADavg) > spread OR Value < AvgCount Then FastAvg
IF ABS (Value - ADavg) < AvgCount Then RealClose
ADavg = ADavg - (ADavg/AvgCount) ' Subtract 1 samples worth
ADavg = ADavg + (Value/AvgCount) ' Add in the new sample portion
GoTo AVGok
FastAvg: ' Catch up to the changing value
ADavg = Value ' Set Average to the current value
GoTo AVGok
RealClose: ' Reduce the sample size when
ADavg = ADavg - (ADavg/(AvgCount/4)) ' the average and the sample are
ADavg = ADavg + (Value/(AvgCount/4)) ' "Real Close"
AVGok:
IF ABS (ADavg - ADhyst) > HystLevel then ' If it changed > HystLevel +/-
ADhyst = ((ADavg + 5) / 10) * 10 ' Round ADavg to get new Value
AVGchanged = 1 ' Indicate that Average changed
ENDIF
NoChange:
Value = ADhyst / 10 ' Scale the result down
Return

OverAverage:
'---------------------------------------------------------------

markedwards
- 1st October 2005, 14:31
Darrel,

I will gladly test your new modifications and post the results here after
I return from a business trip next week!

Mark

Darrel Taylor
- 1st October 2005, 19:32
Cool, Thanks Mark!

Have a nice trip,
too bad it's for business.
<br>

markedwards
- 21st October 2005, 21:35
Darrel,

I returned from my business trip and have been swamped with several customer changes, I hope to test your filter modifications this weekend!

Mark

Darrel Taylor
- 22nd October 2005, 19:19
Thanks Mark,

No hurry. The customer's always come first.

I apprecieate your efforts.
<br>

spcw1234
- 1st January 2011, 16:43
Thanks Darrel! This routine was just what I needed to smooth out a slightly unstable temp reading on a hot tub project I was working on. Just for reference, the code as you have it works 100%

Darrel Taylor
- 3rd January 2011, 21:29
Thanks for the feedback Shawn. :)

DT