Calculating Right Triangles with PICAXE BASIC

With the X1 series of PICAXE microcontrollers, Revolution Education added SIN (sine), COS (cosine) and SQR (square root) along with a number of other arithmetic functions to PICAXE BASIC. The X2 series included the additional ATAN (arctangent) function. Trigonometric and related functions have applications in many fields of science and technology and the new functions are a powerful addition to the PICAXE lexicon. Robotics hobbyists are sure to put them to use in navigation systems where they are invaluable in such tasks as range finding, triangulation, localization and mapping. In this article SQR and the trigonometry functions will be presented in the solving of right triangles. The examples and explanations should establish a fundamental understanding of their function and be easily expanded and integrated with your own applications.

One-Minute Trigonometry Refresher

The laws of trigonometry, and the geometry of triangles in general, center around the proportional constancy of similar triangles. It doesn't matter what size a triangle is, if the proportions (or ratios) among the various sides are the same then the respective angles of the triangle will be the same. Likewise, if the angles making up the triangles are the same, then the proportions of the respective sides will be the same. This proportional constancy allows for the "solving" of triangles - using the known sides and angles to deduce the unknown sides and angles.

Triangles with one angle equal to 90 are a special class of triangle called the right triangle. The hypotenuse is the longest side of a right triangle and is the side opposite the right angle. The Pythagorean theorem says that the hypotenuse squared equals the sum of the squares of the remaining two sides. Using this constant ratio allows the solving for one side of a right triangle when the other two sides are known.

The trigonometric functions define the ratios of the sides of a right triangle and the interior angles. In addition to the hypotenuse, the sides are designated in relation to the angle in question as "opposite" and "adjacent" to that angle. By defining these ratios, right triangles can be solved in many more situations than by the Pythagorean theorem alone. Here we will be concerned with a subset of the trigonometric functions as summarized in the following table:

Function PICAXE BASIC Command Description
Sine SIN opposite/hypotenuse
Cosine COS adjacent/hypotenuse
Tangent n/a opposite/adjacent or sin/cos
Arctangent ATAN returns the angle defined by tangent

In times gone by, these ratios were found in large tables in the back of trigonometry textbooks. Today with calculators, computers, and PICAXEs, the ratios are conveniently stored for us. Solving a right triangle becomes a simple matter of rewriting the equation from the above table for the unknown value. If, for example, the angle and hypotenuse are known and the opposite is to be solved, then the equation could be setup as:

               opposite = sin(angle) * hypotenuse

Trigonometry PICAXE Style

PICAXE math functions are restricted to unsigned integer calculations - in other words no negatives numbers and no fractions or decimals. These restrictions are an issue in trigonometry where the values for sine and cosine will range between -1 and 1, and the accuracy of the calculations will depend on the number of significant digits provided. To get around the problem, the sine and cosine lookups return a value equal to 100 times the actual value. This transformed value allows for calculations to be made to 2 digit accuracy which as we will see shortly gives reasonably good results. However, the transformed value must be addressed in your code. When a value is to be multiplied by a PICAXE SIN or COS value, the result must be divided by 100. When a value is to be divided by a PICAXE SIN or COS value, that value must be multiplied by 100 prior to the division. These adjustments will be seen and explained in the code examples.

The PICAXE lookup tables for SIN and COS are based on 45 steps in each 90 quadrant. Results for calculations based on angles with odd number degrees will be slightly less accurate. The extent of the inaccuracy will depend on the angle being measured and the particular function being implemented. As sine and cosine values approach 1 or -1 the rate of change between degrees is negligible and results should be as accurate as the two digit value will provide. However as sine and cosine values approach 0, the rate of change is more pronounced and slight inaccuracies will result.

Negative values are indicated by setting the 7th bit of the value high which has a net effect of giving a result that is 128 greater than it should be. As a proper result would never be greater than 100, it is a simple matter to place a test in your code when negative sines and cosines are a possibility. If SIN or COS returns a number greater than 100, then either subtract 128 from the number returned or use the CLEARBIT command to set the 7th bit back to 0 and treat the result as a negative within the context of the program. The problem of negative sines and cosines won't affect us here because the other interior angles of our right triangles will never exceed 90 meaning sine and cosine will always be positive.

The ATAN function employs a similar strategy to the SIN and COS functions, however it is the input to the function rather than the output that is multiplied by 100. Given the tangent of an angle multiplied by 100, ATAN returns the value of the angle. The precision of ATAN is limited to whole number results. Also, as the function will return values from 0 to 45, additional programming steps will be necessary when doing calculations on larger angles.

The SQR function returns the square root of the number provided. When the actual result is not a whole number, the value returned is rounded down.

About the Examples

The code samples which follow were successfully implemented on a PICAXE 20X2 using Programming Editor version 5.2.10. Although the X1 and X2 series chips support parenthesis in equations, that feature is not used in the examples. As per the standard PICAXE BASIC, the equations written as they are will execute from left to right with no additional rules for order of operations applied. The examples send the results to the Program Editor's terminal using the serout line on the programming cable. It may be necessary to set the baud rate on your terminal to 9600.

Example Using SQR To Apply the Pythagorean Theorem

The first code example demonstrates using SQR and the Pythagorean theorem to solve a right triangle where the opposite and adjacent sides are known and the hypotenuse is unknown. (Technically the additional sides here are not opposite and adjacent since we are not solving for an angle - they are simply sides - they are labeled as they are for convenience and to set the groundwork for later examples.)

If the equation to solve for hypotenuse were set out in human readable form for it would look something like this:

This is not a difficult equation to express in BASIC.


  ;---------------------------------------------
  ;example using SQR to apply the pythagorean theorem
  ;---------------------------------------------

  #picaxe 20x2
  #terminal 9600

  ;---------------------------------------------
  ;assign 16 bit word variables
  ;---------------------------------------------

  symbol opposite = w0                            
  symbol adjacent = w1
  symbol hypotenuse = w2

  ;---------------------------------------------
  ;set the known values for opposite and adjacent
  ;---------------------------------------------

  opposite = 17                                   
  adjacent = 12

  ;---------------------------------------------
  ;derive the unknown hypotenuse using the Pythagorean theorem
  ;---------------------------------------------

  hypotenuse = opposite * opposite                ;square 1st side
  hypotenuse = adjacent * adjacent + hypotenuse   ;square 2nd side - add to result
  hypotenuse = sqr hypotenuse                     ;square root of accumulated total

  ;---------------------------------------------
  ;send the results to the terminal
  ;---------------------------------------------
  pause 250                                     ;allow the terminal time to open
  sertxd ("Opposite = ", #opposite, 13, 10)     
  sertxd ("Adjacent = ", #adjacent, 13, 10)
  sertxd ("Hypotenuse = ", #hypotenuse, 13, 10)

  end

If you execute the above code on a PICAXE 20X2, you should get a result of 20 for the hypotenuse. The actual value of the hypotenuse would be something closer to 20.809, but as PICAXE will only work in whole numbers the result was rounded down to 20. In many cases this result might be good enough, however other times greater accuracy will be desired. To gain accuracy here you can simply adjust the scale. If, for example, you recode the above and substitute 170 for the opposite and 120 for the adjacent, the result will be 208. You'll notice in these examples that the length measurements are not provided in any specific unit of measure - they might be millimeters, centimeters, inches, or nautical miles - regardless, the ratios in the triangles are the same.

Example Using SIN To Find The Unknown Opposite Side

As noted earlier the sine of an angle is equivalent to the opposite side divided by the hypotenuse. In this example we will use that relationship to solve for a right triangle in which angle in question is 36, the hypotenuse is 60, and the opposite side is unknown. This triangle is illustrated below.

The equation will be opposite = sin(x) * hypotenuse. Once again this is fairly easy to implement in PICAXE BASIC.


  ;---------------------------------------------
  ;example using SIN to find the unknown opposite side
  ;---------------------------------------------

  #picaxe 20x2
  #terminal 9600

  ;---------------------------------------------
  ;assign 16 bit variables for sides and
  ;       8 bit variable for angle
  ;---------------------------------------------

  symbol opposite = w0                            
  symbol hypotenuse = w1
  symbol angle = b4 

  ;---------------------------------------------
  ;set the known values for angle and hypotenuse
  ;---------------------------------------------

  angle = 36                                   
  hypotenuse = 60

  ;---------------------------------------------
  ;derive the unknown opposite side using sine
  ;---------------------------------------------

  opposite = sin angle * hypotenuse/100   ; multiply sine of angle and hypotenuse
                                          ; divide result by 100 because the
                                          ; PICAXE value for SIN is 100
                                          ; times the actual sine of the angle

  ;---------------------------------------------
  ;send the results to the terminal
  ;---------------------------------------------
  pause 250                                     ;allow the terminal time to open
  sertxd ("Angle = ", #angle, 13, 10)     
  sertxd ("Hypotenuse = ", #hypotenuse, 13, 10)
  sertxd ("Opposite = ", #opposite, 13, 10)

  end

The first thing to note about this implementation is that the result was divided by 100 to adjust for the value of SIN. A small price to pay for the ability to use trigonometry with integer math!

If you run this sample you will get a result of 35 for the opposite side which is an acceptably accurate result. Here we'll come upon the limits of PICAXE trigonometric accuracy. Using 2 digit whole numbers, PICAXE returns 59 for the sine value of the 36 angle. Microsoft Excel provides a sine value of 0.587785252 for a 36 angle, and if you were to run the same equation you would get a result of 35.26711514 for the opposite leg. If you changed the scale and ran the PICAXE code again using 600 for the hypotenuse the result would be 354, a result which is closer but still slightly off. Increasing the scale further in this equation would not provide better accuracy.

Example Using COS To Find The Unknown Hypotenuse

Using cosine parallels the use of sine very closely except that the calculations are in relation to the adjacent rather than the opposite side of the angle in question. Therefore to solve for an unknown adjacent side the PICAXE would be setup exactly as in the prior example using COS and adjacent in the place of SIN and opposite. In this example we'll turn the equation around and solve for the unknown hypotenuse. For the example we'll use values of 59 for the angle and 25 for the length of the adjacent side. The equation takes the form hypotenuse = adjacent / cos(x).


  ;---------------------------------------------
  ;example using COS to find the unknown hypotenuse
  ;---------------------------------------------

  #picaxe 20x2
  #terminal 9600

  ;---------------------------------------------
  ;assign 16 bit variables for sides and
  ;       8 bit variable for angle and temp
  ;---------------------------------------------

  symbol adjacent = w0                            
  symbol hypotenuse = w1
  symbol angle = b4 
  symbol temp = b5

  ;---------------------------------------------
  ;set the known values for angle and adjacent
  ;---------------------------------------------

  angle = 59                                   
  adjacent = 25

  ;---------------------------------------------
  ;derive the unknown hypotenuse using cosine
  ;---------------------------------------------

  temp = cos angle                  ; PICAXE won't divide by COS
  hypotenuse = adjacent * 100       ; multiply by 100 to scale for PICAXE COS
  hypotenuse = hypotenuse / temp    ; divide by COS to determine the length
                                    ; of the hypotenuse
                                          
                                      
                                       
  ;---------------------------------------------
  ;send the results to the terminal
  ;---------------------------------------------

  pause 250                                 ;allow the terminal time to open
  sertxd ("Angle = ", #angle, 13, 10)
  sertxd ("Adjacent = ", #adjacent, 13, 10)
  sertxd ("Hypotenuse = ", #hypotenuse, 13, 10)

  end

The most significant change in this code as compared to the SIN example, is that in this case we multiply the known value (adjacent) by 100 prior to performing the calculation with the COS value. Since the result is being calculated by division rather than multiplication, multiplying adjacent by 100 keeps the value in the correct proportion to the COS of 59. The Programming Editor generated an error when trying to divide by a COS value, so the code places the value in a variable named "temp" prior to performing the division. Note here that the result of this calculation is not as accurate as the example used for SIN. This code will return a value of 50 for the hypotenuse when the actual value is closer to 48.5. Refer to the "Trigonometry PICAXE Style" section above for the discussion of accuracy and odd valued angles as SIN or COS approach 1 or -1.

Example Using ATAN To Find An Unknown Angle

The final example here will use the arctangent function to solve for an unknown angle when the lengths of the opposite and adjacent sides are known. Implementing ATAN will be moderately more complex than the earlier examples. Since ATAN takes as its input a value equal to 100 times the tangent, the known values will need to first be used to calculate the tangent of the angle while taking care that it is properly scaled. Referencing the table provided earlier, tangent = opposite/adjacent. Opposite will be multiplied by 100 to maintain the scale. Also of concern is the fact that ATAN only returns results for angles between 0 and 45. This limitation is not too vexing here, because when solving for a right triangle, the remaining interior angles will always complement one another and one will always be less than or equal to 45. Therefore, if the angle to be solved is greater than 45, it is a simple matter to solve the remaining angle using ATAN and then subtract the result from 90. To determine whether the angle is greater or less then 45, the example code will compare the opposite and adjacent sides; if the opposite side is longer then the angle is greater than 45, if the adjacent side is longer then the angle is less than 45.


  ;---------------------------------------------
  ;example using ATAN to find an unknown angle
  ;---------------------------------------------

  #picaxe 20x2
  #terminal 9600

  ;---------------------------------------------
  ;assign 16 bit variables for sides and
  ;       8 bit variable for angle and temp
  ;---------------------------------------------

  symbol opposite = w0                            
  symbol adjacent = w1
  symbol angle = b4 
  
  ;---------------------------------------------
  ;set the known values for opposite and adjacent
  ;---------------------------------------------

  opposite = 72
  adjacent = 42                                   


  ;---------------------------------------------
  ;derive the unknown hypotenuse using cosine
  ;---------------------------------------------
  if opposite <= adjacent then
  angle = opposite * 100/adjacent
  angle = atan angle
  else
  angle = adjacent * 100/opposite   ;atan only solves angles up to 90 degrees 
  angle = atan angle                ;so if the opposite leg is greater
  angle = 90 - angle                ;than adjacent solve for the other corner
                                    ;and then subtract the result from 90       
     

   endif                                          
                                      
                                       
  ;---------------------------------------------
  ;send the results to the terminal
  ;---------------------------------------------

  pause 250                                 ;allow the terminal time to open
  sertxd ("Opposite = ", #opposite, 13, 10)
  sertxd ("Adjacent = ", #adjacent, 13, 10)
  sertxd ("Angle = ", #angle, 13, 10)

  end

Since the sample data provided indicated an angle greater than 45, the second condition of the IF...THEN construct executes and solves for the opposite angle which is then subtracted from 90 to provide 60 as the solution to the angle in question. You may wish to run the example again using other values. Perhaps the most confusing element in the code is that when solving for the opposite angle, the roles of the adjacent and opposite are reversed making it appear that the tangent is being incorrectly calculate as adjacent/opposite. In fact, these are just the names of the variables - the side that was labeled "adjacent" in the code is in fact the "opposite" when solving for the other angle.

Hopefully by now the application of the new functions is clear. While not every possible scenario was included in the examples, you should be able to build upon the formulas that were used here to arrive at solutions to a wide variety of right triangle problems, as well as other applications of the trigonometry functions. Good luck with your projects!



Other Articles You Might Find Enjoyable

PICAXE USB to Serial Conversion

Introduction to the PICAXE Microcontroller

Adding Memory with i2c EEPROMs

Guide to PICAXE Selection

Robot Obstacle Detection and Avoidance with the Devantech SRF05 Ultrasonic Range Finder

Setting Up A Differential Drive For Your PICAXE Project

Basic PICAXE Servo Interfacing

Understanding Variables and Symbols in PICAXE BASIC


Things to Do Here

All PICAXE Articles
Home
Links



Sully Station Technologies

Parts, Tools and Supplies for the Electronics Experimenter