Menu

Sine Function

Anonymous
2014-03-20
2014-03-20
  • Anonymous

    Anonymous - 2014-03-20

    Hello All,

    Attached is the code for a Sine function, and a main program to demo it. The function itself is very short and sweet. The demo portion is the long part, just to show you the results on an LCD.

    This is totally generalized. The argument may be positive, negative or zero, and there is no limit on the size of the argument, either. The results are accurate to four decimal places.

    The lookup table for quadrant I is stored in program memory, and the usual trigonometric identities are used to expand this to include all quadrants, and for positive or negative angles of any size. It really is universal.

    It seems that storing a table of words in EEPROM is buggy in GC Basic. At least, I wasn't able to make that work. So, I just stored the table in program memory which works just fine.

    Thomas Henry

    ;Implementing the Sine function in GC Basic
    ;Thomas Henry -- 3/19/2014
    
    ;This program demonstrates the Sine function by printing
    ;out its values for arguments from -720 degrees
    ;to 720 degrees, in one-degree increments. The actual
    ;function itself is very short. The main business of the
    ;demo program is tied up in formatting the results to
    ;appear neatly on an LCD.
    
    ;This Sine function is completely general purpose. It can
    ;handle positive, negative or zero arguments of any
    ;arbitrary size.
    
    ;The values returned are valid to four decimal places,
    ;equivalent to most printed tables, and more than accurate
    ;for most engineering purposes.
    
    ;The values are maintained as signed integers, scaled up by
    ;a factor of 10000. A lookup table stored in program
    ;memory is used.
    
    ;----- Configuration
    
    #chip 16F88, 8              ;PIC16F88 running at 8 MHz
    #config mclr=off            ;reset handled internally
    #config osc=int             ;use internal clock
    
    ;----- Constants
    
    #define LCD_IO      4       ;4-bit mode
    #define LCD_RS      PortB.2 ;pin 8 is LCD Register Select
    #define LCD_Enable  PortB.3 ;pin 9 is LCD Enable
    #define LCD_DB4     PortB.4 ;DB4 on pin 10
    #define LCD_DB5     PortB.5 ;DB5 on pin 11
    #define LCD_DB6     PortB.6 ;DB6 on pin 12
    #define LCD_DB7     PortB.7 ;DB7 on pin 13
    #define LCD_NO_RW   1       ;ground the RW line on LCD
    
    #define degree      223     ;ASCII code for degree mark
    
    ;----- Variables
    
    dim index as byte
    dim i, sign, value, arg as integer
    
    ;----- Program
    
    dir PortB out                 ;all outputs to the LCD
    
    for i = -720 to 720           ;values of sine from -720 to 720
      cls
      print "sin("                ;print the label
      print i                     ;and the argument
      LCDWriteChar degree         ;print degree mark
      print ")="                  ;and closing parenthesis
      locate 1,0                  ;move to the next line
    
      value = sin(i)              ;get the value of the sine
    
      if value = 0 or value = -1 or value = 1 then
        print value               ;handle whole number cases
      else
        if value < 0 then
          print "-"               ;a negative result
          value = -1 * value
        end if
    
        print "0."                ;format fractional number
    
        if value < 1000 then      ;left pad smaller results
          print "0"
        end if
        if value < 100 then
          print "0"
        end if
          if value < 10 then
          print "0"
        end if
    
        print value               ;then print the fraction
      end if
    
      wait 1 S                    ;pause to view
    next i
    
    ;----- Subroutines
    
    function sin(in arg as integer) as integer
      if arg < 0 then             ;sine is an odd function,
        sign = -1                 ;so negate negative argument
        arg = -1 * arg            ;and change sign of result
      else
        sign = 1                  ;else a positive argument
      end if
    
      arg = arg mod 360           ;reduce to 0 to 359 degrees
    
      if (arg > 270) then         ;Quadrant IV
        sign = -1 * sign
        arg = 360 - arg           ;make reference angle
      else
        if (arg > 180) then       ;Quadrant III
          sign = -1 * sign
          arg = arg - 180         ;make reference angle
        else                      ;Quadrant II
          if (arg > 90) then
            arg = 180 - arg       ;make reference angle
          end if
        end if                    ;Quadrant I by default
      end if
    
      index = [byte]arg+1         ;make index into table
      readTable sineTab, index, sin
    
      sin = sign * sin            ;create final result
    end function
    
    ;----- Data
    
    table sineTab as word
      ;Sine values for 0 through 90 degrees, scaled up by 10000.
      0
      175
      349
      523
      698
      872
      1045
      1219
      1392
      1564
      1736
      1908
      2079
      2250
      2419
      2588
      2756
      2924
      3090
      3256
      3420
      3584
      3746
      3907
      4067
      4226
      4384
      4540
      4695
      4848
      5000
      5150
      5299
      5446
      5592
      5736
      5878
      6018
      6157
      6293
      6428
      6561
      6691
      6820
      6947
      7071
      7193
      7314
      7431
      7547
      7660
      7771
      7880
      7986
      8090
      8192
      8290
      8387
      8480
      8572
      8660
      8746
      8829
      8910
      8988
      9063
      9135
      9205
      9272
      9336
      9397
      9455
      9511
      9563
      9613
      9659
      9703
      9744
      9781
      9816
      9848
      9877
      9903
      9925
      9945
      9962
      9976
      9986
      9994
      9998
      1
    end table
    
     
    • Anobium

      Anobium - 2014-03-20

      I had a look at the code regarding EEPROM and writing WORD values.

      The code today supports BYTE values only. It would be practical to add WORD (I just created a test version with WORD support) but it then caused an issues with pages et, and, it may mean you would on be able to store 126 WORDs in a table.

      Something for the summer to look into. I will add the list of things to investigate.

       
  • Anobium

    Anobium - 2014-03-20

    Very nice. Thank you. I just ported to 16F887a and terminal all this is very good code!

    Most grateful. This is code I could include in the Help File it this is acceptable to you?

     

    Last edit: Anobium 2014-03-20

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.