Shop OBEX P1 Docs P2 Docs Learn Events
Sine Cosine and Brads — Parallax Forums

Sine Cosine and Brads

DiscoveryDiscovery Posts: 606
edited 2014-06-11 06:47 in BASIC Stamp
Would someone please explain why and how negative numbers generated by the Sine and Cosine functions in the Basic Stamp say BS2e cannot be used in math computations? Specifically, I am using a FOR/NEXT statement to generate the quadrature components of the Sine and Cosine to plot a circle parametrically. The parametric operator is to Brad. The plotter draws line segments in all directions. If X2 is smaller than X1, it draws the line segment from right to left. Meaning that the plotter recognizes negative numbers.

The plotter can draw a perfect quadrant using the following code:

FOR j = 0 to 64
X = COS(j)
Y = SIN(j)
GOSUB Plotter 'The plotter plots the very small line segments of (X2-X1,Y2-Y1)
NEXT

The plotter has no trouble plotting any line in any direction, (X2-X1,Y2-Y1); (X3-X2,Y3-Y2); etc. but these lines are produced with pBasic code so it appears that two different types of negative numbers are used.

How can I convert the negative numbers from SIN and COSINE to work with pBasic code?

Sincerely,

Discovery

Comments

  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-05-14 17:05
    Here are three short programs that might help, increasing order of complexity:

    1) zero to 255 brads, with sin and cos as values in the range of +/-126, note use of SDEC to display the negative values.
    [SIZE=1][FONT=courier new]' {$STAMP BS2pe}
    ' {$PBASIC 2.5}
    j VAR WORD
    x VAR WORD
    Y VAR WORD
    '
    FOR j = 0 TO 255 STEP 2
     X = COS(j)
     Y = SIN(j)
     DEBUG CR,DEC j, TAB, SDEC X, TAB, SDEC Y
     'GOSUB Plotter 'The plotter plots the very small line segments of (X2-X1,Y2-Y1)
    NEXT
    END[/FONT][/SIZE]
    

    2) zero to 359 degrees, converted to brads, result displayed as above in range +/-127.
    [SIZE=1][FONT=courier new]' {$STAMP BS2pe}
    ' {$PBASIC 2.5}
    j VAR WORD
    x VAR WORD
    Y VAR WORD
     sX VAR BIT
     sY VAR BIT
    FOR j = 0 TO 359 STEP 3
     X = COS (j*32/45)    ' factor 32/45 converts 0-360 to 0-256
     Y = SIN (j*32/45)
     DEBUG CR, DEC j, TAB, SDEC X, TAB, SDEC Y
    'GOSUB Plotter 'The plotter plots the very small line segments of (X2-X1,Y2-Y1)
    NEXT
    END[/FONT][/SIZE]
    

    3) zero to 359 degrees, converted to brads, result converted to range of +/- 99 and displayed in range +/- 0.99
    [SIZE=1][FONT=courier new]' {$STAMP BS2pe}
    ' {$PBASIC 2.5}
    j VAR WORD
    x VAR WORD
    Y VAR WORD
     sX VAR BIT
     sY VAR BIT
    FOR j = 0 TO 359 STEP 3
       X = COS (j*32/45)    ' factor 32/45 converts 0-360 to 0-256
       Y = SIN (j*32/45)
       sX = X.BIT15            ' sign of the result
       sY = Y.BIT15
       X = 25 * ABS X /32    ' factor 25/32 converts result from 0-127 scale to 0-100 scale
       Y = 25 * ABS Y /32
       X = -sX ^ X + sX       ' twos complement conditional on sign bit
       Y = -sY ^ Y + sY
     DEBUG CR, DEC j, TAB, REP "-"\sX,"0.",DEC2 ABS X   ' display value with decimal point
     DEBUG TAB, REP "-"\sY,"0.",DEC2 ABS Y
    'GOSUB Plotter 'The plotter plots the very small line segments of (X2-X1,Y2-Y1)
    NEXT
    END[/FONT][/SIZE]
    
  • DiscoveryDiscovery Posts: 606
    edited 2014-05-15 06:29
    Thanks Allen,

    I would like to understand what is happening to the SIN and COSINE function output when they produce negative results. If you run the following program on a BS2:

    Note that the Sine and Cosine data will plot a perfect quarter circle then it fails to produce the correct output for the remaining quarter circles. Could you add the necessary code to what I supplied to correct the problem?

    Sincerely,

    Discovery


    ' {$STAMP BS2pe}'
    {$PBASIC 2.5}
    j VAR BYTE
    x VAR WORD
    Y VAR WORD
    FOR j = 0 TO 70
    X = COS(j)
    Y = SIN(j)
    DEBUG DEC3 j," ",DEC3 X," ,DEC3 Y," ",CR
    NEXT

    You will get the following output.
    000 127 000
    .
    .
    .
    061 009 127
    062 006 127
    063 003 127
    064 000 127
    065 533 127
    066 530 127
    067 527 127
    068 524 126
    069 520 126
    070 517 126
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-05-15 07:46
    Display the result using SDEC3. (Signed Decimal).

    FOR j = 0 to 255 ' a full circle
    ..
    DEBUG DEC3 j," ",SDEC3 X," ,SDEC3 Y," ",CR ' for the negative values
    ..

    PBASIC uses 16 bit twos complement.
    DEC modifier:
    0 to 65535 are all positive numbers
    SDEC modifier:
    0 to 32767 are positive, and 32768 to 65535 come out as negative values from -32768 to -1.
    Within the twos complement representation, SIN and COS output numbers -127 to +127.

    What do you have to send to the plotter? What range of values and format?


  • DiscoveryDiscovery Posts: 606
    edited 2014-05-15 20:27
    Hi Allen,

    I am aware that the SDEC will display the correct answer but for my plotter it uses signed decimal numbers.

    The plotter is actually an X-Y stepper motor positioned plasma cutter covering a seven foot by four foot area. I am running tests using a BS2. However, since 16 bits is not enough to cover the seven foot range with .01" accuracy, I plan to migrate to the propeller for the 32 bit capability. I may start migrating the BS2 program to the propeller tomorrow.

    Do you anticipate any similar problems with the propeller?

    Sincerely,

    Discovery
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-05-15 22:58
    It helps to hear about the underlying goal. The Propeller has much better support for twos complement numbers, trig functions, and far more significant digits.

    You can convert the values from the Stamp sin and cos to signed decimal values, but you are quite right, 8 bits of precision will be woefully inadequate for the plasma cutter.
  • DiscoveryDiscovery Posts: 606
    edited 2014-05-16 05:40
    Hi Allen,

    Here is my problem. The code that I wrote in pBasic for operating the X and Y stepper motors works by subtracting the new X position from the old X position (same for the Y change) then converts the change into stepper motor counts. If say the new position on X is 6" and the old position is 2" the delta change is positive so the stepper direction is set to clockwise and the difference is multiplied by the pulses per revolution and the pitch of the screw. The pulses are then sent to the stepper motor. If the opposite was the case where the old value was 6" and the new was 2" then the difference is negative. This condition is detected and the stepper motor direction is set for counter clockwise and the difference receives an ABS operation to take the absolute value. This number is then scaled for pulses and sent to the stepper motor. The code is rather robust so that all line segments can be plotted in any direction.

    Now, when I use the sin and cos functions in pBasic, when the functions output a negative result...I figured that I could use the ABS function for the magnitude and the negative sense for direction. But this does not work. When I plot the circle on the X-Y machine it produces a beautiful one quarter circle...as soon as the cos outputs a negative, the plotter stops driving the cos and continues with the sin. I figure that something is different with the negative output of the sin and cos as opposed to just taking the difference between two numbers that generate a negative result.

    I am not a good C programmer (FORTRAN, BASIC, LOGO...no problem) and I really have a hard time programming the propeller on the activity board. I get error messages that just don't make sense. The reference material does not provide a good enough code example. The manuals remind me of the old IBM manuals. If you were a trained IBM programmer then the manuals were good enough but not good enough to train someone from scratch.

    So, why is it that my method does not work for the negative sin and cos outputs?

    Discovery
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2014-05-16 15:20
    Well, it should work. Probably a program bug. A variable set to be a byte, when it should be a word. Something. Can you post the code that converts the number to direction and counts?

    More accurate sin and cos can be done on the on the Stamp 'p series, by putting a much larger lookup table with interpolation in one of the extra slots.

    I've stuck with Spin on the Propeller and can't help with the C implementation, sorry.
  • DiscoveryDiscovery Posts: 606
    edited 2014-05-16 16:40
    Rats...I was hoping you might be an expert "C" programmer and could lend some assistance.

    I will take a look at posting the code that does the direction and count work.

    I will be out for a couple days.

    Discovery
  • DiscoveryDiscovery Posts: 606
    edited 2014-05-16 18:53
    Allen,
    While in the shower...I think the reason for the sine cosine problem was made clear. When the sine or cosine functions generate a negative number my code takes the negative number and subtracts it from the previous number. This negative-negative operation produces a very large result which drives the stepper until the plotter reaches table limit.

    I will make a change to the code and verify if this is the mechanism...when I return to the shop.

    Discovery
  • DiscoveryDiscovery Posts: 606
    edited 2014-06-11 06:47
    When using the Basic Stamp built-in Sine and Cosine functions, the the negative terms do not subtract properly and erroneous results occur.

    When I use my HP calculator to compute the sine terms and store them as constants in the Basic Stamp, my plotting program has no problem with the subtraction and as a result the plotter describes a perfect circle. Multiplying by a scale factor sets the size of the circle. The problem was solved but not the way I wanted it solved.

    Discovery
Sign In or Register to comment.