Shop OBEX P1 Docs P2 Docs Learn Events
Speeding up code execution - help with slow program — Parallax Forums

Speeding up code execution - help with slow program

ArchiverArchiver Posts: 46,084
edited 2001-07-18 16:24 in General Discussion
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

Comments

  • ArchiverArchiver Posts: 46,084
    edited 2001-07-18 08:49
    Hi,

    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/
  • ArchiverArchiver Posts: 46,084
    edited 2001-07-18 08:50
    A big part of the problem is that _all_ of your if-then decisions are
    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
  • ArchiverArchiver Posts: 46,084
    edited 2001-07-18 09:19
    Hi Tracy,

    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
  • ArchiverArchiver Posts: 46,084
    edited 2001-07-18 16:14
    >Hi Tracy,
    >
    >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
  • ArchiverArchiver Posts: 46,084
    edited 2001-07-18 16:24
    Hi Tracy,

    The message regarding 'serialled in' appeared just
    above the min/max constant definitions.

    Greetings peter
Sign In or Register to comment.