Working code but my layman approach uses too much code space


+ Reply to Thread
Results 1 to 5 of 5
  1. #1
    Join Date
    Oct 2005
    Location
    New Jersey
    Posts
    425

    Default Working code but my layman approach uses too much code space

    Trial and error led me to this code after my description just below. It works just like I need it to but there has to be a better way. The formula provided is this:
    Code:
    0.125*(M1*256+M2-0x0FA0)
    Seems simple, right? Not for me.....

    So if M1=15 and M2=160 the result is 0. Both are byte variables so a rollover from M2 will increase M1 by 1. Increasing this number will provide a positive number and decreasing it will provide a negative number. In addition to the difficulty I was having with the formula, I had to account for formatting on my screen so triple digit numbers needed to be formatted differently than double digit numbers. Any comments are appreciated!

    B1=256
    B2=4000
    MULT=125
    G3T and G4T are byte sized variables
    Code:
    SELECT CASE G3T 
            CASE 15
                SELECT CASE G4T                    
                    CASE IS < 160
                        DUMMY =MULT*((G3T*B1)+(G4T+B2))
                        MG2_NM = DIV32 100
                        MG2_NM=10000-MG2_NM
                        IF MG2_NM > 999 THEN
                            LCDOUT $FE, POS4-1,"-",DEC MG2_NM/10,".",DEC MG2_NM DIG 0
                        ELSE
                            LCDOUT $FE, POS4-1,"-",DEC MG2_NM/10,".",DEC MG2_NM DIG 0," "
                        ENDIF 
                    CASE IS >= 160
                        MG2_NM=(G4T*125)-20000
                        IF MG2_NM > 9999 THEN
                            LCDOUT $FE,POS4-1," ",DEC MG2_NM/100,".",DEC MG2_NM DIG 0 
                        ELSE 
                            LCDOUT $FE,POS4-1," ",DEC MG2_NM/100,".",DEC MG2_NM DIG 0," " 
                        ENDIF
                END SELECT
            CASE IS < 15
                DUMMY =MULT*((G3T*B1)+(G4T+B2))' GOOD FOR NEGATIVE NM, INCLUDING ZERO
                MG2_NM = DIV32 100
                MG2_NM=10000-MG2_NM
                IF MG2_NM > 999 THEN
                    LCDOUT $FE, POS4-1,"-",DEC MG2_NM/10,".",DEC MG2_NM DIG 0 
                ELSE
                   LCDOUT $FE, POS4-1,"-",DEC MG2_NM/10,".",DEC MG2_NM DIG 0," "
                ENDIF 
            CASE ELSE
                DUMMY = MULT*((G3T*B1)+(G4T-B2)) 
                MG2_NM = DIV32 100
                IF MG2_NM > 999 THEN
                    LCDOUT $FE,POS4-1," ",DEC MG2_NM/10,".",DEC MG2_NM//10
                ELSE
                    LCDOUT $FE,POS4-1," ",DEC MG2_NM/10,".",DEC MG2_NM//10," "               
                ENDIF              
        END SELECT
    If someone comes up with a one-line code I'm going to slit my wrists.....

    I have another issue that I'm having difficulty solving. I'm viewing data that comes at a very fast rate. The number is very jumpy because it changes quickly. I know I can average it but if I average say 5 measurements, it would seem good for those five measurements but when compared with the next five measurements I would think the number would still appear jumpy. What is a good way to make a measurement look smooth? It looks like the data is sent about 90 times a second.

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,373

    Default Re: Working code but my layman approach uses too much code space

    Hi,
    I don't follow your code that well but the formula...
    0.125*(M1*256+M2-0x0FA0)
    As far as I can see you're combining two bytes into a word where M1 is the high byte anf M2 the low byte. Then you subtract 4000 from that value and multiply 0.125. You can combine the two bytes into a word simply by creating a word variable and aliasing the high and low bytes. Subtracting 4000 is a no brainer and multiplying by 0.125 is the same as dividing by 8, dividing by 8 is the same as shifting the value 3 places to the right, right?
    Code:
    Result VAR WORD                 ' This is the "output" value.
    Value VAR WORD                  ' This is the "input" variable consisting of two bytes, namely... 
    M1 VAR Value.HighByte           ' ...M1,m which is the high byte and...
    M2 VAR Value.LowByte            ' ...M2, qhich is the low byte
    
    ' Now, if M1 is 15 ($0F) and M2 is 160 ($A0) Value is $0FA0 so the result, after subtracting 4000 ($0FA0) will be 0.
    
    Sign VAR BIT
    
    Result = (Value - 4000)         ' Subtract 4000
    Sign = Result.15                ' Remember if the value is negative.
    Result = ABS(Result)            ' Take the absolute value of Result.
    Result = Result >> 3            ' Divide that by 8
    If Sign THEN Result = -Result   ' If the original value (before dividing by 8) was negative, so is the result.
    Now, Result will be a signed two-complements number, if the high bit is set the value is negative, else it's positive. To display it on the LCD you can use the SDEC modifier, it will print it correctly with a negative sign in front (if negative of course). To display a fixed number of digits you can use for example SDEC3 which will display 3 digits (012 or -123 for example).

    Just be aware that incrementing M2 so it rolls over will not automatically increment M1, for that to happen you must increment Value.

    Not sure that's what you're really asking but I tried... :-)

    /Henrik.

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,373

    Default Re: Working code but my layman approach uses too much code space

    Hi again,
    I forgot the second part. You need what's called a rolling average or moving average. Darrel has a piece of code on his site, here and for more great info on integer math, including filters etc, take a close look at Tracy Allens BS2 math notes.

    /Henrik.

  4. #4
    Join Date
    May 2006
    Location
    Del Rio, TX, USA
    Posts
    343

    Default Re: Working code but my layman approach uses too much code space

    Like Henrik said, the formula is really subtracting 4000 from a WORD. So here's the way I tackled it:

    Code:
    wCalc   VAR WORD
    G3T     VAR wCalc[0]
    G4T     VAR wCalc[1]
    IF wCalc <4000 THEN     'Number will be negative
        DUMMY =MULT*(wCalc+B2)
        MG2_NM = DIV32 100
        MG2_NM=10000-MG2_NM
        LCDOUT $FE, POS4-1,"-"
    ELSE                    'Number will be positive or 0
        Dummy = MULT*(wCalc-B2)
        MG2_NM = DIV32 100
        LCDOUT $FE,POS4-1," "
    ENDIF
    IF MG2_NM < 100  THEN
        LCDOUT "  "
    ELSEIF  MG2_NM < 1000  THEN
        LCDOUT " "
    ENDIF
    LCDOUT DEC MG2_NM/10,".",DEC MG2_NM//10

  5. #5
    Join Date
    Oct 2005
    Location
    New Jersey
    Posts
    425

    Default Re: Working code but my layman approach uses too much code space

    Thanks for the help guys. Your posts helped out a lot.

Similar Threads

  1. I'm running out of code space example.
    By retepsnikrep in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 21st June 2010, 21:33
  2. How much code space do PBP statements use.
    By Darrel Taylor in forum Code Examples
    Replies: 5
    Last Post: - 13th February 2009, 22:31
  3. Running out of Code Space - or so it seems
    By Squibcakes in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 6th July 2006, 17:44
  4. Need more code space
    By Sphere in forum General
    Replies: 2
    Last Post: - 19th September 2005, 21:49
  5. Need more code space
    By ghutchison in forum General
    Replies: 1
    Last Post: - 12th February 2005, 21:54

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts