Better ways to write repeated code
g3cwi
Posts: 262
Hi
I am working on a barometric trend display Object. It works well but I can't help thinking that the code is way too long. Can anyone help on ways to streamline some of the lengthy tests etc?
Thanks
Richard
I am working on a barometric trend display Object. It works well but I can't help thinking that the code is way too long. Can anyone help on ways to streamline some of the lengthy tests etc?
Thanks
Richard
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ALTITUDE = 145 'Your altitude in metres ASL 'EEPROM locations for hourly observations R0 = $9003 R1 = $9007 R2 = $900b R3 = $900f R4 = $9013 R5 = $9017 R6 = $901b R7 = $901f R8 = $9023 R9 = $9027 R10 = $902b R11 = $902f R12 = $9033 R13 = $9037 R14 = $903b R15 = $903f R16 = $9043 R17 = $9047 R18 = $904b R19 = $904f R20 = $9053 R21 = $9057 R22 = $905b R23 = $905f Time = $9063 'Flag for initial boot detection Flag = $9067 'Storage for trend values T3 = $906b T1 = $906f Ti = $9073 'By Richard Newstead, G3CWI, June 2012 OBJ bar : "29124_altimeter" rtc : "DS1302_full" SN : "Simple_Numbers" DEBUG : "Debug_LCD03" EEPROM: "I2C_ROMEngine" Var byte hour, minute, second Long time_long,Trend3,Trend1,Trendi PUB Start 'Start everything running rtc.init( 4, 5, 6 ) 'define ports for Real Time Clock bar.start_explicit( 0, 1, true ) bar.set_resolution( bar#highest ) 'Set to highest resolution. DEBUG.start( 15, 9600, 4 ) '4 lines serial LCD EEPROM.ROMEngineStart( 29, 28, 0 ) Initialise_EEPROM Main Pub Main | p DEBUG.CLS DEBUG.Backlight(true) DEBUG.Cursor(0) Display repeat rtc.readTime( @hour, @minute, @second ) 'read time from DS1302 'Update everything once a minute IF minute<>EEPROM.ReadLong(Time) p := bar.average_press 'Get the average pressure. EEPROM.WriteLong(Time, minute) 'Store time time_long := hour * 10000 + minute * 100 + second 'Concatenate 'Store hourly readings Case time_long 000000:EEPROM.WriteLong(R0, p) 010000:EEPROM.WriteLong(R1, p) 020000:EEPROM.WriteLong(R2, p) 030000:EEPROM.WriteLong(R3, p) 040000:EEPROM.WriteLong(R4, p) 050000:EEPROM.WriteLong(R5, p) 060000:EEPROM.WriteLong(R6, p) 070000:EEPROM.WriteLong(R7, p) 080000:EEPROM.WriteLong(R8, p) 090000:EEPROM.WriteLong(R9, p) 100000:EEPROM.WriteLong(R10, p) 110000:EEPROM.WriteLong(R11, p) 120000:EEPROM.WriteLong(R12, p) 130000:EEPROM.WriteLong(R13, p) 140000:EEPROM.WriteLong(R14, p) 150000:EEPROM.WriteLong(R15, p) 160000:EEPROM.WriteLong(R16, p) 170000:EEPROM.WriteLong(R17, p) 180000:EEPROM.WriteLong(R18, p) 190000:EEPROM.WriteLong(R19, p) 200000:EEPROM.WriteLong(R20, p) 210000:EEPROM.WriteLong(R21, p) 220000:EEPROM.WriteLong(R22, p) 230000:EEPROM.WriteLong(R23, p) 'Using obs, calculate 3 hour trend Case time_long 000001..010000:Trend3:=EEProm.Readlong(R0)- EEProm.Readlong(R21) 010001..020000:Trend3:=EEProm.Readlong(R1)- EEProm.Readlong(R22) 020001..030000:Trend3:=EEProm.Readlong(R2)- EEProm.Readlong(R23) 030001..040000:Trend3:=EEProm.Readlong(R3)- EEProm.Readlong(R0) 040001..050000:Trend3:=EEProm.Readlong(R4)- EEProm.Readlong(R1) 050001..060000:Trend3:=EEProm.Readlong(R5)- EEProm.Readlong(R2) 060001..070000:Trend3:=EEProm.Readlong(R6)- EEProm.Readlong(R3) 070001..080000:Trend3:=EEProm.Readlong(R7)- EEProm.Readlong(R4) 080001..090000:Trend3:=EEProm.Readlong(R8)- EEProm.Readlong(R5) 090001..100000:Trend3:=EEProm.Readlong(R9)- EEProm.Readlong(R6) 100001..110000:Trend3:=EEProm.Readlong(R10)-EEProm.Readlong(R7) 110001..120000:Trend3:=EEProm.Readlong(R11)-EEProm.Readlong(R8) 120001..130000:Trend3:=EEProm.Readlong(R12)-EEProm.Readlong(R9) 130001..140000:Trend3:=EEProm.Readlong(R13)-EEProm.Readlong(R10) 140001..150000:Trend3:=EEProm.Readlong(R14)-EEProm.Readlong(R11) 150001..160000:Trend3:=EEProm.Readlong(R15)-EEProm.Readlong(R12) 160001..170000:Trend3:=EEProm.Readlong(R16)-EEProm.Readlong(R13) 170001..180000:Trend3:=EEProm.Readlong(R17)-EEProm.Readlong(R14) 180001..190000:Trend3:=EEProm.Readlong(R18)-EEProm.Readlong(R15) 190001..200000:Trend3:=EEProm.Readlong(R19)-EEProm.Readlong(R16) 200001..210000:Trend3:=EEProm.Readlong(R20)-EEProm.Readlong(R17) 210001..220000:Trend3:=EEProm.Readlong(R21)-EEProm.Readlong(R18) 220001..230000:Trend3:=EEProm.Readlong(R22)-EEProm.Readlong(R19) 230001..000000:Trend3:=EEProm.Readlong(R23)-EEProm.Readlong(R20) 'Using obs, calculate 1 hour trend Case time_long 000001..010000:Trend1:=EEProm.Readlong(R0)- EEProm.Readlong(R23) 010001..020000:Trend1:=EEProm.Readlong(R1)- EEProm.Readlong(R0) 020001..030000:Trend1:=EEProm.Readlong(R2)- EEProm.Readlong(R1) 030001..040000:Trend1:=EEProm.Readlong(R3)- EEProm.Readlong(R2) 040001..050000:Trend1:=EEProm.Readlong(R4)- EEProm.Readlong(R3) 050001..060000:Trend1:=EEProm.Readlong(R5)- EEProm.Readlong(R4) 060001..070000:Trend1:=EEProm.Readlong(R6)- EEProm.Readlong(R5) 070001..080000:Trend1:=EEProm.Readlong(R7)- EEProm.Readlong(R6) 080001..090000:Trend1:=EEProm.Readlong(R8)- EEProm.Readlong(R7) 090001..100000:Trend1:=EEProm.Readlong(R9)- EEProm.Readlong(R8) 100001..110000:Trend1:=EEProm.Readlong(R10)-EEProm.Readlong(R9) 110001..120000:Trend1:=EEProm.Readlong(R11)-EEProm.Readlong(R10) 120001..130000:Trend1:=EEProm.Readlong(R12)-EEProm.Readlong(R11) 130001..140000:Trend1:=EEProm.Readlong(R13)-EEProm.Readlong(R12) 140001..150000:Trend1:=EEProm.Readlong(R14)-EEProm.Readlong(R13) 150001..160000:Trend1:=EEProm.Readlong(R15)-EEProm.Readlong(R14) 160001..170000:Trend1:=EEProm.Readlong(R16)-EEProm.Readlong(R15) 170001..180000:Trend1:=EEProm.Readlong(R17)-EEProm.Readlong(R16) 180001..190000:Trend1:=EEProm.Readlong(R18)-EEProm.Readlong(R17) 190001..200000:Trend1:=EEProm.Readlong(R19)-EEProm.Readlong(R18) 200001..210000:Trend1:=EEProm.Readlong(R20)-EEProm.Readlong(R19) 210001..220000:Trend1:=EEProm.Readlong(R21)-EEProm.Readlong(R20) 220001..230000:Trend1:=EEProm.Readlong(R22)-EEProm.Readlong(R21) 230001..000000:Trend1:=EEProm.Readlong(R23)-EEProm.Readlong(R22) Case time_long 000001..010000:Trendi:=p-EEProm.Readlong(R23) 010001..020000:Trendi:=p-EEProm.Readlong(R0 ) 020001..030000:Trendi:=p-EEProm.Readlong(R1 ) 030001..040000:Trendi:=p-EEProm.Readlong(R2 ) 040001..050000:Trendi:=p-EEProm.Readlong(R3 ) 050001..060000:Trendi:=p-EEProm.Readlong(R4 ) 060001..070000:Trendi:=p-EEProm.Readlong(R5 ) 070001..080000:Trendi:=p-EEProm.Readlong(R6 ) 080001..090000:Trendi:=p-EEProm.Readlong(R7 ) 090001..100000:Trendi:=p-EEProm.Readlong(R8 ) 100001..110000:Trendi:=p-EEProm.Readlong(R9 ) 110001..120000:Trendi:=p-EEProm.Readlong(R10) 120001..130000:Trendi:=p-EEProm.Readlong(R11) 130001..140000:Trendi:=p-EEProm.Readlong(R12) 140001..150000:Trendi:=p-EEProm.Readlong(R13) 150001..160000:Trendi:=p-EEProm.Readlong(R14) 160001..170000:Trendi:=p-EEProm.Readlong(R15) 170001..180000:Trendi:=p-EEProm.Readlong(R16) 180001..190000:Trendi:=p-EEProm.Readlong(R17) 190001..200000:Trendi:=p-EEProm.Readlong(R18) 200001..210000:Trendi:=p-EEProm.Readlong(R19) 210001..220000:Trendi:=p-EEProm.Readlong(R20) 220001..230000:Trendi:=p-EEProm.Readlong(R21) 230001..000000:Trendi:=p-EEProm.Readlong(R22) 'Write trends to EEPROM so preserved in case of power down EEPROM.WriteLong(T3,Trend3) EEPROM.WriteLong(T1,Trend1) EEPROM.WriteLong(Ti,Trendi) Display Pub Display | sp, cm, p p := bar.average_press cm := ALTITUDE * 100 sp := bar.sealevel_press(p, cm) DEBUG.cls DEBUG.str(string("QNH :")) 'Print sea-level pressure heading. DEBUG.str(bar.formatn(sp, bar#MILLIBARS | bar#CECR, 6)) ' Print sea-level pressure in millibars, clear-to-end, and CR. DEBUG.nl 'Print medium-term trend narrative Debug.Str(string("3hr :")) Case EEPROM.Readlong(T3) -9999..-600:Debug.Str(string("Very rapid fall")) -599..-360 :Debug.Str(string("Falling rapidly")) -359..-160 :Debug.Str(string("Falling")) -159..-10 :Debug.Str(string("Falling slowly")) -9..9 :Debug.Str(string("Steady")) 10..159 :Debug.Str(string("Rising slowly")) 160..359 :Debug.Str(string("Rising")) 360..600 :Debug.Str(string("Rising rapidly")) 600..9999 :Debug.Str(string("Very rapid rise")) Other :Debug.Str(string("Error")) DEBUG.nl 'Print short-term trend narrative Debug.Str(string("1hr :")) Case EEPROM.Readlong(T1) -9999..-600:Debug.Str(string("Very rapid fall")) -599..-360 :Debug.Str(string("Falling rapidly")) -359..-160 :Debug.Str(string("Falling")) -159..-10 :Debug.Str(string("Falling slowly")) -9..9 :Debug.Str(string("Steady")) 10..159 :Debug.Str(string("Rising slowly")) 160..359 :Debug.Str(string("Rising")) 360..600 :Debug.Str(string("Rising rapidly")) 600..9999 :Debug.Str(string("Very rapid rise")) Other :Debug.Str(string("Error")) DEBUG.nl 'Print instantaneous trend narrative Debug.Str(string("inst:")) Case EEPROM.Readlong(Ti) -9999..-600:Debug.Str(string("Very rapid fall")) -599..-360 :Debug.Str(string("Falling rapidly")) -359..-160 :Debug.Str(string("Falling")) -159..-10 :Debug.Str(string("Falling slowly")) -9..9 :Debug.Str(string("Steady")) 10..159 :Debug.Str(string("Rising slowly")) 160..359 :Debug.Str(string("Rising")) 360..600 :Debug.Str(string("Rising rapidly")) 600..9999 :Debug.Str(string("Very rapid rise")) Other :Debug.Str(string("Error")) Pri Initialise_EEPROM | p 'Fill EEPROM with default data 'if not already filled p := bar.average_press If EEPROM.Readlong(Flag)<>$5555 'check fill flag EEPROM.WriteLong(R0, p) EEPROM.WriteLong(R1, p) EEPROM.WriteLong(R2, p) EEPROM.WriteLong(R3, p) EEPROM.WriteLong(R4, p) EEPROM.WriteLong(R5, p) EEPROM.WriteLong(R6, p) EEPROM.WriteLong(R7, p) EEPROM.WriteLong(R8, p) EEPROM.WriteLong(R9, p) EEPROM.WriteLong(R10, p) EEPROM.WriteLong(R11, p) EEPROM.WriteLong(R12, p) EEPROM.WriteLong(R13, p) EEPROM.WriteLong(R14, p) EEPROM.WriteLong(R15, p) EEPROM.WriteLong(R16, p) EEPROM.WriteLong(R17, p) EEPROM.WriteLong(R18, p) EEPROM.WriteLong(R19, p) EEPROM.WriteLong(R20, p) EEPROM.WriteLong(R21, p) EEPROM.WriteLong(R22, p) EEPROM.WriteLong(R23, p) EEPROM.WriteLong(Flag,$5555) 'get starting minutes and store rtc.readTime( @hour, @minute, @second ) EEPROM.WriteLong(Time, minute)
Comments
EEPROM.WriteLong(R0, p)
EEPROM.WriteLong(R1, p)
EEPROM.WriteLong(R2, p)
could be something like
repeat a from 0 to ?? 'spin syntax a little rusty here
EEPROM.WriteLong(($9003+a), p)
And just for argument sake I would have longs start at long boundaries, so
Not sure if it is needed, but old habits die hard
Your algorithm ought to be able to handle any number of hours. From two to thousands (assuming you have the memeory to store the data).
You might want to include some out of bound checks if you make the number of samples easy to change (by changing a constant at the beginning of the program).
Just got around to implementing these changes. Thanks for the ideas.
Cheers
Richard
This is in the CON method: is there a more elegant way of defining these locations?
Cheers
Richard
Remember that I am very dim. I guess that is a method? i.e.
If so, I am guessing that you don't think that I need to define the locations in the Con block at all?
Or have I missed the point entirely?
Cheers
Richard
[Edit - I am begining to think that is exactly what you mean. There is really no need to define the locations]
Thanks for all the help - this has been a very useful learning exercise.
Added to OBEX:http://obex.parallax.com/objects/868/[URL="http://obex.parallax.com/objects/868/]"]
[/URL]
Cheers
Richard
You can make some optimizations, limiting the number of reads/writes from/to the EEPROM:
1) Read the needed values first, and then calculate the trends.
2) Trend1 and Trend3 only need to be re-calculated and written when you write the new hourly value.
like this: