PDA

View Full Version : A more program space efficient way of doing ta whole heap of IFs????



HankMcSpank
- 26th May 2011, 21:32
I'm putting my nooby hat firmly back on here!

This following chain of multiple IFs, is absolutely slaughtering my modest 12lf1822's program space, I wonder if anyone would be so kind to offer up a better way (ie uses less code space) of approaching this....



if supply_in>= 253 then max_duty = 154
if supply_in> 250 and supply_in< 254 then max_duty = 155
if supply_in> 248 and supply_in< 251 then max_duty = 156
if supply_in> 245 and supply_in< 249 then max_duty = 157
if supply_in> 240 and supply_in< 243 then max_duty = 159
if supply_in> 237 and supply_in< 241 then max_duty = 160
if supply_in> 234 and supply_in< 238 then max_duty = 161
if supply_in> 231 and supply_in< 235 then max_duty = 163
if supply_in> 229 and supply_in< 232 then max_duty = 165
if supply_in> 226 and supply_in< 230 then max_duty = 167
if supply_in> 223 and supply_in< 227 then max_duty = 169
if supply_in> 220 and supply_in< 224 then max_duty = 172
if supply_in> 218 and supply_in< 221 then max_duty = 175
if supply_in> 215 and supply_in< 219 then max_duty = 179
if supply_in> 212 and supply_in< 216 then max_duty = 181
if supply_in> 210 and supply_in< 213 then max_duty = 182
if supply_in> 207 and supply_in< 211 then max_duty = 184
if supply_in> 204 and supply_in< 208 then max_duty = 188
if supply_in> 201 and supply_in< 205 then max_duty = 191
if supply_in> 199 and supply_in< 202 then max_duty = 195
if supply_in> 196 and supply_in< 200 then max_duty = 214
if supply_in> 193 and supply_in< 197 then max_duty = 238
if supply_in> 187 and supply_in<194 then max_duty = 251
if supply_in< 188 then max_duty = 255


Surprisingly, (to me at least) a 'select case' used even more program, space (which I realise would be quicker & more efficient, but I've got to roll with whatever takes the least amount of program space presently!

Could an array be brought into play or similar?

mister_e
- 26th May 2011, 21:57
First thing that spring to mind is an internal EEPROM based lookup table. This will save a lot of IF-THEN and code space.

Or throw all your data in MiscEl or Excel and see if you can extract an accurate enough formula from it (Curve fit).

Darrel Taylor
- 27th May 2011, 01:32
Use ELSEIF.

The second test in each line is not needed, because the previous test already checked that condition. And having multiple conditions in an IF line involves temporary system variables to save the intermediate results.

The code in post#1 compiled to 559 words.

This one is 189 words.
PBP 2.60 required, but the same thing can be done without 2.60 and elseif.
if supply_in>= 253 then
max_duty = 154
ELSEIF supply_in> 250 then
max_duty = 155
ELSEIF supply_in> 248 then
max_duty = 156
ELSEIF supply_in> 245 then
max_duty = 157
ELSEIF supply_in> 240 then
max_duty = 159
ELSEIF supply_in> 237 then
max_duty = 160
ELSEIF supply_in> 234 then
max_duty = 161
ELSEIF supply_in> 231 then
max_duty = 163
ELSEIF supply_in> 229 then
max_duty = 165
ELSEIF supply_in> 226 then
max_duty = 167
ELSEIF supply_in> 223 then
max_duty = 169
ELSEIF supply_in> 220 then
max_duty = 172
ELSEIF supply_in> 218 then
max_duty = 175
ELSEIF supply_in> 215 then
max_duty = 179
ELSEIF supply_in> 212 then
max_duty = 181
ELSEIF supply_in> 210 then
max_duty = 182
ELSEIF supply_in> 207 then
max_duty = 184
ELSEIF supply_in> 204 then
max_duty = 188
ELSEIF supply_in> 201 then
max_duty = 191
ELSEIF supply_in> 199 then
max_duty = 195
ELSEIF supply_in> 196 then
max_duty = 214
ELSEIF supply_in> 193 then
max_duty = 238
ELSEIF supply_in> 187 then
max_duty = 251
ELSE
max_duty = 255
ENDIF

Darrel Taylor
- 27th May 2011, 01:54
Here's another way.
Oddly enough, it's 191 words.

supply_in VAR BYTE
max_duty VAR BYTE
ItemNo VAR BYTE
'
LOOKDOWN2 supply_in, >[252,250,248,245,240,237,234,231,229,226,223,220,21 8,215,212,210,207,204,201,199,196,193,187,0],ItemNo
LOOKUP ItemNo,[154,155,156,157,159,160,161,163,165,167,169,172,17 5,179,181,182,184,188,191,195,214,238,251,255],max_duty

Darrel Taylor
- 27th May 2011, 02:27
OK, so let's go with Steve's idea and put it in EEPROM.

88 words.

supply_in VAR BYTE
max_duty VAR BYTE
ItemNo VAR BYTE
Temp VAR BYTE
'
supply_Max DATA 252,250,248,245,240,237,234,231,229,226,223,220,21 8,215,212,210,207,204,201,199,196,193,187,0
Set_duty DATA 154,155,156,157,159,160,161,163,165,167,169,172,17 5,179,181,182,184,188,191,195,214,238,251,255
'
FOR ItemNo = 0 TO (Set_duty - supply_Max)
READ (supply_max + ItemNo), Temp
IF supply_in > Temp THEN
READ (Set_duty + ItemNo), Temp
max_duty = Temp
EXIT
ENDIF
NEXT ItemNo

I haven't tested it, but it looks right.
Check my work.

HankMcSpank
- 27th May 2011, 11:44
Wow....what can I say Darrel....you lost me after the elseif post, but I'm gonna read it again & again until it sinks in!

(also thank you steve ....all great stuff)

Edit: Even just rolling with the ELSEIF melarkey ...my program now compiles at 1643 words ...it was maxing out before (greater than 2048 words), so even if I never get to understand the EEPROM method (& the initial indications aren't favourable, lol!) then nevertheless you've saved the day!

Demon
- 27th May 2011, 12:22
PICs have 2 areas of memory: codespace, for your program, and eeprom, you use DATA to store data and READ to get at it (you can also WRITE to it during program execution).

Eeprom is a simple way to store tables and then use For loops to scan through them later. Three common uses; character definitions for LCDs, conversion tables and saving PIN numbers.

I think Melanie has a thread somewhere on how to use some of that eeprom area for codespace.

HankMcSpank
- 27th May 2011, 12:29
PICs have 2 areas of memory: codespace, for your program, and eeprom, you use DATA to store data and READ to get at it.

Eeprom is a simple way to store tables and then use For loops to scan through them later. Two common uses; character definitions for LCDs and conversion tables.

I think Melanie has a thread somewhere on how to use some of that eeprom area for codespace.

Thanks Robert (a cool name ;-) )...while I'm fairly clued up on how to get the PIC to work now (as well as being reasonably savvy on the electronics /interfacing aspect), the darned pesky coding world is still totally flat in my eyes!! (this is frustrating as I have a head brimmed with ideas...but no quick way to get them out of my fingertips & into a PIC)

I'll have to take a night out to get the hang of using EEPROM so I'll have a search for any related threads outlining how to get started with them.

rsocor01
- 27th May 2011, 13:25
if supply_in>= 253 then
max_duty = 154
ELSEIF supply_in> 250 then
max_duty = 155
ELSEIF supply_in> 248 then
max_duty = 156
ELSEIF supply_in> 245 then
max_duty = 157
ELSEIF supply_in> 240 then
max_duty = 159
ELSEIF supply_in> 237 then
max_duty = 160
ELSEIF supply_in> 234 then
max_duty = 161
ELSEIF supply_in> 231 then
max_duty = 163
ELSEIF supply_in> 229 then
max_duty = 165
ELSEIF supply_in> 226 then
max_duty = 167
ELSEIF supply_in> 223 then
max_duty = 169
ELSEIF supply_in> 220 then
max_duty = 172
ELSEIF supply_in> 218 then
max_duty = 175
ELSEIF supply_in> 215 then
max_duty = 179
ELSEIF supply_in> 212 then
max_duty = 181
ELSEIF supply_in> 210 then
max_duty = 182
ELSEIF supply_in> 207 then
max_duty = 184
ELSEIF supply_in> 204 then
max_duty = 188
ELSEIF supply_in> 201 then
max_duty = 191
ELSEIF supply_in> 199 then
max_duty = 195
ELSEIF supply_in> 196 then
max_duty = 214
ELSEIF supply_in> 193 then
max_duty = 238
ELSEIF supply_in> 187 then
max_duty = 251
ELSE
max_duty = 255
ENDIF

Darrel,

Let me ask a very dumb question here about your ELSEIF program :confused:. Lets say for example that variable supply_in= 251. Does the program exits the IF..ENDIF block after it encounters the lines

ELSEIF supply_in> 250 then
max_duty = 155

or does it keep going through the rest of the ELSEIF lines in the IF..ENDIF block? I checked the manual but I didn't see the answer to my question.

Thanks,

Robert

Heckler
- 27th May 2011, 13:59
Darrel,

I have to say your coding examples are nothing short of excellent.

That is one place that I think the PBP manual could be improved. I came over from the basic stamp, their manual was quite good with examples.

The hardest thing for me to do is to go from a technical description of a given PBP command to a real world working piece of code. Whereas, once I see how to correctly use a given PBP statement, then I can usually write my way through my own code. Where I usually have trouble is with the syntax and good examples are invaluable. There seems to be a lot of wasted blank paper in the manual that could be filled up with more syntax examples.

If MElabs could produce a webpage where a person could goto and enter any given PBP statement and see a few (several) examples of good code, it would help the newbie greatly. I know there are a few of those over at MElabs but there could be more.

Please pass this along to the MElabs people :).

You are a real asset to the group... and I look forward to future releases of PBP that might?? include some of your excellent coding work implemented as new PBP statements.

dhouston
- 27th May 2011, 15:40
If there is a mathematical relationship between supply_in and max_duty, it might be more efficient to just compute max_duty as supply_in varies.

Also, if the relationship could be refined to eliminate the max _duty granular discontinuities (i.e. if it can vary in steps of 1 or any constant step), a loop might be better.

HankMcSpank
- 27th May 2011, 16:22
If there is a mathematical relationship between supply_in and max_duty, it might be more efficient to just compute max_duty as supply_in varies.

Also, if the relationship could be refined to eliminate the max _duty granular discontinuities (i.e. if it can vary in steps of 1 or any constant step), a loop might be better.


I'd considered that, but alas the supply_in vs the max_duty required is all over the shop....hence the multiple ifs!

Demon
- 27th May 2011, 18:54
Darrel,

Let me ask a very dumb question here about your ELSEIF program :confused:. Lets say for example that variable supply_in= 251. Does the program exits the IF..ENDIF block after it encounters the lines

ELSEIF supply_in> 250 then
max_duty = 155
...


That one''s easy (programmer by trade), it exits the nested IFs after assigning 155.

mister_e
- 27th May 2011, 19:16
The hardest thing for me to do is to go from a technical description of a given PBP command to a real world working piece of code. Whereas, once I see how to correctly use a given PBP statement, then I can usually write my way through my own code. Where I usually have trouble is with the syntax and good examples are invaluable.

This forum, PBPGroup, Rentron.com & Melabs website are full of handy code example, take a pick, modify them, try to make them better.

To me the PBP book is perfect. It explain what a specific command do. Just build a test program around it and you're all set. There's by far worst reference book... check MPASM assembler, most (see any) API/DLL reference... list is long ;)

Programming... It's like everything, practice makes "perfect", the more you do, the easier it gets. Call it experience if you like. It take months, years, decade... it's a never ending learning process... welcome on the dark side ;)

mister_e
- 27th May 2011, 20:11
OK, so let's go with Steve's idea and put it in EEPROM.

88 words.

supply_in VAR BYTE
max_duty VAR BYTE
ItemNo VAR BYTE
Temp VAR BYTE
'
supply_Max DATA 252,250,248,245,240,237,234,231,229,226,223,220,21 8,215,212,210,207,204,201,199,196,193,187,0
Set_duty DATA 154,155,156,157,159,160,161,163,165,167,169,172,17 5,179,181,182,184,188,191,195,214,238,251,255
'
FOR ItemNo = 0 TO (Set_duty - supply_Max)
READ (supply_max + ItemNo), Temp
IF supply_in > Temp THEN
READ (Set_duty + ItemNo), Temp
max_duty = Temp
EXIT
ENDIF
NEXT ItemNoI haven't tested it, but it looks right.
Check my work.

Option 2:
Could also shave it a lil more, but use a single and larger Lookup...



DATA @188, ....all duty result from 188........256 bytes available btw
.
.
.
.
if supply_in< 188 then
max_duty = 255
else
READ Supply_in, Max_duty
endif

couldn't be more simple I guess ;)

I know you love challenge Darrel :P

rsocor01
- 29th May 2011, 00:10
That one''s easy (programmer by trade), it exits the nested IFs after assigning 155.

Ooh, I see. Thank you Robert.

Demon
- 3rd June 2011, 01:02
When in doubt, use debug feature.

If you don't have a debug feature (using Wordpad instead of an IDE), then make one up. Just put in a bunch of LEDs on empty ports, and then make them blink different ways in different places in your code.

Or even better, get the easiest LCD on the market, the HD44780, and send debug messages (abbreviated syntax, just for example):



LCDOUT "Program start", var1, var2

Label_A:
LCDOUT "Label A", var1, var2
Program logic...
IF var1 < var2 then goto Label_A

Label_B:
LCDOUT "Label B", var1, var2
More program logic...
IF var1 < var2 then goto Label_B

LCDOUT "Program end", var1, var2


We do something similar as mainframe programmers; it's called using DISPLAY statements. There is no limit to what you can use as a debug feature. If it works for you, then it's perfect.

HankMcSpank
- 19th June 2011, 11:46
OK, so let's go with Steve's idea and put it in EEPROM.

88 words.

supply_in VAR BYTE
max_duty VAR BYTE
ItemNo VAR BYTE
Temp VAR BYTE
'
supply_Max DATA 252,250,248,245,240,237,234,231,229,226,223,220,21 8,215,212,210,207,204,201,199,196,193,187,0
Set_duty DATA 154,155,156,157,159,160,161,163,165,167,169,172,17 5,179,181,182,184,188,191,195,214,238,251,255
'
FOR ItemNo = 0 TO (Set_duty - supply_Max)
READ (supply_max + ItemNo), Temp
IF supply_in > Temp THEN
READ (Set_duty + ItemNo), Temp
max_duty = Temp
EXIT
ENDIF
NEXT ItemNo

I haven't tested it, but it looks right.
Check my work.

I originally shyed away from using suggestion, on account the initial idea provided rescued me back sufficient space, but alas, things have just got too tight, so I've just tried this latter suggestion...it worked first time & has rescued me back a good bit of space (room to breathe again!)

I'll admit I don't totally understand what's going one (other than we're storing stuff in EEPROM, then cleverly marrying it up), I'll addess my inner "huh?" demons & work this out soon, but for now I'm just chuffed the enigma works...as a bonus it's far easier for me to mate the values (the formatting on here clouds it, but it's as clear as day in reality)

Many thanks.