Speeding up code execution - help with slow program
Archiver
Posts: 46,084
Hi All,
I've written a simple program that constantly grabs the data for each
channel of a 12bit adc (8 channel). Under testing, I seem to be able
to sample data at well over 20hz per channel.
I have now added some code that checks the value of each channel
against a pre-determined setpoint value, and if the value is outside
the pre set limits, an error routine toggles a led.
To do this, I've used a whole lot of if statements (16 in fact) that
are checked against every channels returned value.
As a result, the program now crawls along, barely averaging 3 hz /
channel. I'm sure there must be a better way to write the code, so if
anybody can help then I sure would appreciate it.
Cheers,
Simon
' This program grabs the data from an 8 chan 12 bit ABC. It then
' compares the returned value against the preset value, and if higher
' or lower, triggers an alarm.
' Set the constants
cs con 0
clk con 1
dio con 2
' Set the variables
Result var word
chan var nib
channel var word
' For this example set all the channel min and max values.
' These are normally serialled in
chan0min con 20
chan0max con 1564
chan1min con 0
chan1max con 1644
chan2min con 45
chan2max con 658
chan3min con 500
chan3max con 124
chan4min con 23
chan4max con 1565
chan5min con 7
chan5max con 4000
chan6min con 201
chan6max con 1878
chan7min con 204
chan7max con 1866
' Start the main program here
high cs
high dio
Loop:
low 7 ' Set led low (off)
for chan = 0 to 7
gosub GetData ' Get the data from the ADC
gosub CheckData ' Check that data is within
limits
serout 10\11,$54,[noparse][[/noparse]chan, ":", Result]
next
goto Loop
GetData:
lookup chan, [noparse][[/noparse]%11000,%11001,%11010,%11011,%11100,%11101,%
11110,%11111],channel
low cs
shiftout dio, clk, msbfirst,[noparse][[/noparse]channel\5]
shiftin dio, clk,msbpost,[noparse][[/noparse]Result\13]
high cs
return
CheckData:
' This is the bit that is really slow.
' Is there anyway of speeding this up?
if chan = 0 and ad < chan0min then Error
if chan = 0 and ad > chan0max then Error
if chan = 1 and ad < chan1min then Error
if chan = 1 and ad > chan1max then Error
if chan = 2 and ad < chan2min then Error
if chan = 2 and ad > chan2max then Error
if chan = 3 and ad < chan3min then Error
if chan = 3 and ad > chan3max then Error
if chan = 4 and ad < chan4min then Error
if chan = 4 and ad > chan4max then Error
if chan = 5 and ad < chan5min then Error
if chan = 5 and ad > chan5max then Error
if chan = 6 and ad < chan6min then Error
if chan = 6 and ad > chan6max then Error
if chan = 7 and ad < chan7min then Error
if chan = 7 and ad > chan7max then Error
return
error:
high 7 'Sets a led high (on) if outside limits
return
I've written a simple program that constantly grabs the data for each
channel of a 12bit adc (8 channel). Under testing, I seem to be able
to sample data at well over 20hz per channel.
I have now added some code that checks the value of each channel
against a pre-determined setpoint value, and if the value is outside
the pre set limits, an error routine toggles a led.
To do this, I've used a whole lot of if statements (16 in fact) that
are checked against every channels returned value.
As a result, the program now crawls along, barely averaging 3 hz /
channel. I'm sure there must be a better way to write the code, so if
anybody can help then I sure would appreciate it.
Cheers,
Simon
' This program grabs the data from an 8 chan 12 bit ABC. It then
' compares the returned value against the preset value, and if higher
' or lower, triggers an alarm.
' Set the constants
cs con 0
clk con 1
dio con 2
' Set the variables
Result var word
chan var nib
channel var word
' For this example set all the channel min and max values.
' These are normally serialled in
chan0min con 20
chan0max con 1564
chan1min con 0
chan1max con 1644
chan2min con 45
chan2max con 658
chan3min con 500
chan3max con 124
chan4min con 23
chan4max con 1565
chan5min con 7
chan5max con 4000
chan6min con 201
chan6max con 1878
chan7min con 204
chan7max con 1866
' Start the main program here
high cs
high dio
Loop:
low 7 ' Set led low (off)
for chan = 0 to 7
gosub GetData ' Get the data from the ADC
gosub CheckData ' Check that data is within
limits
serout 10\11,$54,[noparse][[/noparse]chan, ":", Result]
next
goto Loop
GetData:
lookup chan, [noparse][[/noparse]%11000,%11001,%11010,%11011,%11100,%11101,%
11110,%11111],channel
low cs
shiftout dio, clk, msbfirst,[noparse][[/noparse]channel\5]
shiftin dio, clk,msbpost,[noparse][[/noparse]Result\13]
high cs
return
CheckData:
' This is the bit that is really slow.
' Is there anyway of speeding this up?
if chan = 0 and ad < chan0min then Error
if chan = 0 and ad > chan0max then Error
if chan = 1 and ad < chan1min then Error
if chan = 1 and ad > chan1max then Error
if chan = 2 and ad < chan2min then Error
if chan = 2 and ad > chan2max then Error
if chan = 3 and ad < chan3min then Error
if chan = 3 and ad > chan3max then Error
if chan = 4 and ad < chan4min then Error
if chan = 4 and ad > chan4max then Error
if chan = 5 and ad < chan5min then Error
if chan = 5 and ad > chan5max then Error
if chan = 6 and ad < chan6min then Error
if chan = 6 and ad > chan6max then Error
if chan = 7 and ad < chan7min then Error
if chan = 7 and ad > chan7max then Error
return
error:
high 7 'Sets a led high (on) if outside limits
return
Comments
One possible solution is to define 256 data values where each bit in the
byte value would represent
wether the ad value is valid for each channel. Let me explain.
Value = b7 b6 b5 b4 b2 b2 b1 b0
The bit positions are your ad channels 7-0
The bit value is set for invalid ad value and cleared for valid ad value.
The ad value itself is used as the index in the data table.
So you have
Test var byte
AdData $00,$00,$00 '256 entries
Checkdata:
Read Addata+ad,test
If test<>0 then error
Return
Since now only one read is involved, it should be quite fast.
It occupies 256 EEPROM bytes though for the data.
Hope this helps.
Greetings peter
Oorspronkelijk bericht
Van: egroups@d... [noparse]/noparse]mailto:[url=http://forums.parallaxinc.com/group/basicstamps/post?postID=lZnAy9g2FBcYhDbAp_1DLeyBuWSaBDDsH-xShj0nO3lJsxK8kZVk2IYdrbmFVhd6t4nbCf0t_E6DtmzTrWGl9oc]egroups@d...[/url
Verzonden: woensdag 18 juli 2001 06:59
Aan: basicstamps@yahoogroups.com
Onderwerp: [noparse][[/noparse]basicstamps] Speeding up code execution - help with slow program
Hi All,
I've written a simple program that constantly grabs the data for each
channel of a 12bit adc (8 channel). Under testing, I seem to be able
to sample data at well over 20hz per channel.
I have now added some code that checks the value of each channel
against a pre-determined setpoint value, and if the value is outside
the pre set limits, an error routine toggles a led.
To do this, I've used a whole lot of if statements (16 in fact) that
are checked against every channels returned value.
As a result, the program now crawls along, barely averaging 3 hz /
channel. I'm sure there must be a better way to write the code, so if
anybody can help then I sure would appreciate it.
Cheers,
Simon
' This program grabs the data from an 8 chan 12 bit ABC. It then
' compares the returned value against the preset value, and if higher
' or lower, triggers an alarm.
' Set the constants
cs con 0
clk con 1
dio con 2
' Set the variables
Result var word
chan var nib
channel var word
' For this example set all the channel min and max values.
' These are normally serialled in
chan0min con 20
chan0max con 1564
chan1min con 0
chan1max con 1644
chan2min con 45
chan2max con 658
chan3min con 500
chan3max con 124
chan4min con 23
chan4max con 1565
chan5min con 7
chan5max con 4000
chan6min con 201
chan6max con 1878
chan7min con 204
chan7max con 1866
' Start the main program here
high cs
high dio
Loop:
low 7 ' Set led low (off)
for chan = 0 to 7
gosub GetData ' Get the data from the ADC
gosub CheckData ' Check that data is within
limits
serout 10\11,$54,[noparse][[/noparse]chan, ":", Result]
next
goto Loop
GetData:
lookup chan, [noparse][[/noparse]%11000,%11001,%11010,%11011,%11100,%11101,%
11110,%11111],channel
low cs
shiftout dio, clk, msbfirst,[noparse][[/noparse]channel\5]
shiftin dio, clk,msbpost,[noparse][[/noparse]Result\13]
high cs
return
CheckData:
' This is the bit that is really slow.
' Is there anyway of speeding this up?
if chan = 0 and ad < chan0min then Error
if chan = 0 and ad > chan0max then Error
if chan = 1 and ad < chan1min then Error
if chan = 1 and ad > chan1max then Error
if chan = 2 and ad < chan2min then Error
if chan = 2 and ad > chan2max then Error
if chan = 3 and ad < chan3min then Error
if chan = 3 and ad > chan3max then Error
if chan = 4 and ad < chan4min then Error
if chan = 4 and ad > chan4max then Error
if chan = 5 and ad < chan5min then Error
if chan = 5 and ad > chan5max then Error
if chan = 6 and ad < chan6min then Error
if chan = 6 and ad > chan6max then Error
if chan = 7 and ad < chan7min then Error
if chan = 7 and ad > chan7max then Error
return
error:
high 7 'Sets a led high (on) if outside limits
return
To UNSUBSCRIBE, just send mail to:
basicstamps-unsubscribe@yahoogroups.com
from the same email address that you subscribed. Text in the Subject and
Body of the message will be ignored.
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
executed for every channel each time through the loop. It would be
better to branch to the appropriate if-then statement based on the
channel number. Or here is another way to do it, by first using a
lookup with the current channel, to get the appropriate min and max
values into two variables. Then compare with the ADC result...
In the loop that reads the channels
lolimit var word ' variables for the current min and max
hilimit var word
low 7 ' led off
for chan = 0 to 7
' here come the channel-specific min and max:
lookup chan,(chan0min,chan1min,...,chan7min),lolimit
lookup chan,(chan0max,chan1max,...,chan7max),hilimit
gosub GetData ' Get the data from the ADC
' returns result, now check...
checkdata:
if result>lolimit and result<hilimit then okay
high 7 ' led on, error
okay:
next
Another observation:
The lookup from chan to channel can be simplified, from,
> lookup chan, [noparse][[/noparse]%11000,%11001,%11010,%11011,%11100,%11101,%
> 11110,%11111],channel
to
channel=%11000+chan
that should run faster.
Dispensing with the subroutines for getdata and checkdata (just put
them in line with the main loop) will run faster. (Unless there is
some other good reason to reuse them as subroutines in another part
of your program.)
--
-- regards,
Tracy Allen
electronically monitored ecosystems
mailto:tracy@e...
http://www.emesystems.com
>Hi All,
>
>I've written a simple program that constantly grabs the data for each
>channel of a 12bit adc (8 channel). Under testing, I seem to be able
>to sample data at well over 20hz per channel.
>
>I have now added some code that checks the value of each channel
>against a pre-determined setpoint value, and if the value is outside
>the pre set limits, an error routine toggles a led.
>
>To do this, I've used a whole lot of if statements (16 in fact) that
>are checked against every channels returned value.
>
>As a result, the program now crawls along, barely averaging 3 hz /
>channel. I'm sure there must be a better way to write the code, so if
>anybody can help then I sure would appreciate it.
>
>Cheers,
>
>Simon
>
>
>' This program grabs the data from an 8 chan 12 bit ABC. It then
>' compares the returned value against the preset value, and if higher
>' or lower, triggers an alarm.
>
>' Set the constants
>
>cs con 0
>clk con 1
>dio con 2
>
>' Set the variables
>
>Result var word
>chan var nib
>channel var word
>
>' For this example set all the channel min and max values.
>' These are normally serialled in
>
>chan0min con 20
>chan0max con 1564
>chan1min con 0
>chan1max con 1644
>chan2min con 45
>chan2max con 658
>chan3min con 500
>chan3max con 124
>chan4min con 23
>chan4max con 1565
>chan5min con 7
>chan5max con 4000
>chan6min con 201
>chan6max con 1878
>chan7min con 204
>chan7max con 1866
>
>
>' Start the main program here
>
>high cs
>high dio
>
>Loop:
> low 7 ' Set led low (off)
> for chan = 0 to 7
> gosub GetData ' Get the data from the ADC
> gosub CheckData ' Check that data is within
>limits
> serout 10\11,$54,[noparse][[/noparse]chan, ":", Result]
> next
>goto Loop
>
>GetData:
> lookup chan, [noparse][[/noparse]%11000,%11001,%11010,%11011,%11100,%11101,%
>11110,%11111],channel
> low cs
> shiftout dio, clk, msbfirst,[noparse][[/noparse]channel\5]
> shiftin dio, clk,msbpost,[noparse][[/noparse]Result\13]
> high cs
>return
>
>CheckData:
>
> ' This is the bit that is really slow.
> ' Is there anyway of speeding this up?
>
> if chan = 0 and ad < chan0min then Error
> if chan = 0 and ad > chan0max then Error
> if chan = 1 and ad < chan1min then Error
> if chan = 1 and ad > chan1max then Error
> if chan = 2 and ad < chan2min then Error
> if chan = 2 and ad > chan2max then Error
> if chan = 3 and ad < chan3min then Error
> if chan = 3 and ad > chan3max then Error
> if chan = 4 and ad < chan4min then Error
> if chan = 4 and ad > chan4max then Error
> if chan = 5 and ad < chan5min then Error
> if chan = 5 and ad > chan5max then Error
> if chan = 6 and ad < chan6min then Error
> if chan = 6 and ad > chan6max then Error
> if chan = 7 and ad < chan7min then Error
> if chan = 7 and ad > chan7max then Error
>return
>
>error:
> high 7 'Sets a led high (on) if outside limits
>return
I like the lookup solution for the min/max values.
The original message however also stated thet these values
are normally serialled in. Is there an easy way to alter those
min/max values in eeprom, i.e how to find out where and how they
are stored?
Greetings peter
>
>I like the lookup solution for the min/max values.
>The original message however also stated thet these values
>are normally serialled in. Is there an easy way to alter those
>min/max values in eeprom, i.e how to find out where and how they
>are stored?
>
>Greetings peter
I don't see that in Simon's original message--the set points were
declared as constants. If the setpoints needed to be modified at run
time, I would put them in as DATA words instead of as a LOOKUP. Read
them out and modify them using the channel number *2 as the index.
-- Tracy
The message regarding 'serialled in' appeared just
above the min/max constant definitions.
Greetings peter