A more program space efficient way of doing ta whole heap of IFs????
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....
Code:
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?
Re: A more program space efficient way of doing ta whole heap of IFs????
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).
Re: A more program space efficient way of doing ta whole heap of IFs????
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.
Code:
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
Re: A more program space efficient way of doing ta whole heap of IFs????
Here's another way.
Oddly enough, it's 191 words.
Code:
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,218,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,175,179,181,182,184,188,191,195,214,238,251,255],max_duty
Re: A more program space efficient way of doing ta whole heap of IFs????
OK, so let's go with Steve's idea and put it in EEPROM.
88 words.
Code:
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,218,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,175,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.
Re: A more program space efficient way of doing ta whole heap of IFs????
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!
Re: A more program space efficient way of doing ta whole heap of IFs????
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.
Re: A more program space efficient way of doing ta whole heap of IFs????
Quote:
Originally Posted by
Demon
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.
Re: A more program space efficient way of doing ta whole heap of IFs????
Quote:
Originally Posted by
Darrel Taylor
Code:
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
Re: A more program space efficient way of doing ta whole heap of IFs????
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.
Re: A more program space efficient way of doing ta whole heap of IFs????
Quote:
Originally Posted by
dhouston
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!
Re: A more program space efficient way of doing ta whole heap of IFs????
Quote:
Originally Posted by
rsocor01
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.
Re: A more program space efficient way of doing ta whole heap of IFs????
Quote:
Originally Posted by
Darrel Taylor
OK, so let's go with
Steve's idea and put it in EEPROM.
88 words.
Code:
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,218,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,175,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.
Option 2:
Could also shave it a lil more, but use a single and larger Lookup...
Code:
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
Re: A more program space efficient way of doing ta whole heap of IFs????
Quote:
Originally Posted by
Demon
That one''s easy (programmer by trade), it exits the nested IFs after assigning 155.
Ooh, I see. Thank you Robert.
Re: A more program space efficient way of doing ta whole heap of IFs????
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):
Code:
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.
Re: A more program space efficient way of doing ta whole heap of IFs????
Quote:
Originally Posted by
Darrel Taylor
OK, so let's go with
Steve's idea and put it in EEPROM.
88 words.
Code:
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,218,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,175,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.