You are on page 1of 7

Adding Math Power to your PICAXE

1. Using the microMega Floating Point Unit - uM-FPU V2

The PICAXE range of microcontroller produced by Revolution Education are very easy to program using the PICAXE variant of the BASIC programming language. There are however some limitations with the PICAXE range when it comes to math capabilities. Namely: 1. There is a limit to the number of variables for holding values. 2. There is a limit to the number of math functions inbuilt to the various PICAXE chips. 3. The PICAXE native math capabilities are limited to positive integer values only. In terms of variables for the PICAXE chips, there are: 14 bytes/7 word variables on the simpler chips (M series) , -28byte/14 word variables on mid-range (X1) chips, and 56 bytes/28 words for the present top-end (X2) parts.

The PICAXE chips do have extra memory RAM and EEPROM storage locations that can be accessed by other commands (READ/WRITE, PEEK/POKE, etc) and again the number of these additional locations is generally proportion to the type of PICAXE chip that is M versus X1 versus X2 parts. All of the PICAXE chips have basic math functions such as add, subtract, divide and multiply, Min, Max, OR and AND. The X1 and X2 PICAXE parts also have some additional functions such as Sin, Cos, Sqr, Inv, and for the X2 parts only there is Atan. The uM-FPU co-processor chip has pre-programmed constants, it provides trigonometry functions and converts to and from values and ASCII strings. You can of course use multipliers in an endeavour to maintain one or two decimal places to try and improve math accuracy but a second issue arises in that the maximum value a PICAXE chip can handle is 65535, so math overflow can occur with more complex math calculations.

2.

Enter the uM-FPU V2

MicroMega Corporation is a small Canadian company who has produced a couple of math co-processors for use with microcontroller such as the PICAXE chips. Currently available are is the slightly older V2 chip and the newer V3.1 chips. This tutorial is focused on the uM-FPU V2 chip. The uM-FPU V2 is an 8 pin DIP chips which provides both i2c and SPI based communications. Again this tutorial is focused on using i2c comms to interface the co-processor chip to a PICAXE microcontroller. The use of i2c allows the use of any of the X type PICAXE chips form the 18X, through the X1 and X2 parts. The uM-FPU V2 includes sixteen 32-bit registers for storing values. The chip offers both fixed-point and floating-point operations. The chip's operations conform to the 32-bit IEEE 754 standard for floating-point math and it also performs 32-bit long integer calculations.

Additionally there are 1024 bytes of flash memory reserved for storing up to 63 user functions. Loading the user functions requires the use of the free IDE software available from the microMega website. The use of this flash memory is not considered in this tutorial. On the MicroMega website and also available form the Rev Ed website is a tutorial entitled Using uM-FPU V2 with the PICAXE Microcontroller. As such this tutorial is aimed at clarifying and expand upon the use of the uM-FPU V2 chip rather than just repeating information which is within the microMega documents. Everyone using the uM-FPU chips should also download the following documents: - uM-FPU Floating Point Coprocessor V2 datasheet - uM-FPU V2 Instruction Reference - The tutorial Using uM-FPU V2 with the PICAXE Microcontroller MicroMeg Corp also provides a software package called uM-FPU V2 IDE which amongst other things will allow you to write math formula and have them converted to PICAXE program code that you can copy and paste into the PIACE programming Editor. But here, we are diving in at the deeper end of the programming pool and writing our own uM-FPU code by hand using the mnemonics provided in the programming template.

The uM-FPU chips accept data as either binary values (using one or two bytes) or strings of ASCII characters. Commands are sent as one-byte or two-byte binary codes, which simplifies programming. Adding a uM-FPU is not going to speed up all of the maths for the PICAXE. Simple positive integer math calculations with values including intermediate values are less than 65535 will always be faster done inside the PICAXE. It must be remembered that there is an overhead to actually pass the values and command instructions via the i2c comms link (or SPI if that were used) to the uM-FPU chip and then more time to read the result back The uM-FPU comes into its own where there are values larger than 65535, negative values, or fractional/floating point values involved. The uM-FPU chip also excels where the math requirements are
repetitive and you can download constant values into the uMFPU registers which are then used over and over for new computations.

3.

Getting Started

MicroMega Corp has provided a PICAXE compatible template containing all the variable and constant aliases that you need to get started with the use of the uM-FPU V2 chips. It is recommended that you download and use that template to save a lot of typing and grief in future. 3.1 Adjust some variable Alias Names A couple of quick edits should be performed when you first open this template. Within the template uM-FPU opcodes definitions section, change the SYMBOL statements for Sin, Cos and Atan to read Sine, Cosine and Arctan respectively to avoid conflict with the inbuilt math functions of the X1 and X2 chip parts. If everyone does these same changes then the final program code will be more universal/portable whether used on an 18X or a 40X2, etc.

3.2

Add a small delay on initialisation

The provided template program code initializes the uM-FPU V2 and checks that the chip exists. If the chip does exist then the standard template program sends the chip version (uM-FPU V2) to the PC terminal window. Here again there is a small hiccup for PICAXE users. The problem may be in the Programming Editor Terminal Window code but something does not initialize fast enough for the user to see the returned chip version string. The author has identified this hiccup with PE version 5.2.11 running under Windows XP. This does not affect operation of the uM-FPU to PICAXE comms so when such an early response is not required a delay is not required. The solution is to add a brief delay at the start of the program. This can be done by adding one extra line of program in the initialization section. See the test in red below: '======================================================================== '-------------------- initialization ------------------------------------------'========================================================================

Init: pause 500 ; need a min of 300 for the Terminal Window or uM-PFU V2 to initialise correctly
reset1: i2cslave uMFPU, i2cfast, i2cbyte

3.3

Clearing the registers

One observation is that when data is mathematically added into the 32-bit registers, if that register has not previously been set to zero, then the results are not a number values. One solution is to firstly clear all the registers by the inclusion of the following program lines: FOR reg = 0 TO 15 ; clear the registers 0 to 15 writei2c 0, ( reg, XOP, LOADZERO, FSET) NEXT reg Another method for a specific register, is to effectively copy the first value into the A register with the lines: reg = SELECTA + X opcode = FSET+Y writei2c 0, ( reg, opcode) ; set Register A to uM-FPU register X ; command to make register A = reg Y as the B register ; giving register X = register Y

4.

Storing values into the uM-FPU V2 32-bit registers

One of the first things to do on starting a program is to initialise the uM-FPU chip. The provided template includes the necessary program code to do that. Register 0 of the uM-FPU is used as a temporary register by the internal math calculations and therefore cannot be considered as a permanent register to hold a constant or long term value. To store a value from the PICAE into one of the other 15 registers (1 to 15) the PIACXE code is in the form: dataWord = 32765 ; any value from 0 to 65535 can be entered here reg = SELECTA + X ; set Register A to uM-FPU register X, where X is 0 to 15 writei2c 0, ( reg, LOADUWORD, dataHigh, dataLow, FSET )

The variables dataWord, reg, dataHigh and dataLow are pre-defined in the microMega provided programming template, as are the operators SELECTA, LOADUWORD and FSET. The command LOADUWORD can be changed here to suit the requirements. If only one bytes is to be sent then the command LOADUBYTE can be used with just the dataLow (or dataByte) value. It is also possible to send a negative value to the uM-FPU chip if one considers the PICAXE values as a signed integer number. This is where the most significant bit of the binaryvalue is used as a (negative) sign bit. In this case; A byte variable has the range -128 to +127 A word variable has the range -32768 to + 32767 For a negative value, the PICAXE must send the value as a positive value greater than the maximum positive value (+127 or +32767) For a negative word variable value, the negative value is represented by 65536 (negative value), thus -1 is sent as 65536 1 = 65535, -2 is sent as 65536 2 = 65534, etc. For negative byte values, the negative value is represented by 256 (negative value), When sending such signed values, the command LOADUWORD must be changed to the command LOADWORD or command LOADBYTE. It is also possible to send a floating point value from the PICAXE to the uM-FPU chip as an ASCII character string using the ATOF command. An example of this is shown in the previously reference microMega tutorial Using uM-FPU V2 with the PICAXE Microcontroller on page 5 where the value 1.8 is sent as an ASCII string and converted to a floating point number within the uM-FPU chip. Also the example in section 5.3 below.

5.

Performing Math Functions

Now that we can send values from the PICAXE chip to the uM-FPU V2 chip it is time to perform some math functions. 5.1 Simple Math Functions By way of example, say we send the values 1234 and 4321 to the uM-FPU chip and save these into registers 1 and 2 respectively. Now we can add, subtract divide or multiply these two values and save the results into other registers. To firstly send these two value to the uM-FPu chip we use the PICAXE program lines: dataWord = 1234 reg = SELECTA + 1 ; set Register A to uM-FPU register 1 writei2c 0, ( reg, LOADWORD, dataHigh, dataLow, FSET ) dataWord = 4321 reg = SELECTA + 2 ; set Register A to uM-FPU register 2 writei2c 0, ( reg, LOADUWORD, dataHigh, dataLow, FSET )

Now we can add the two values and save the result in register 3 with the PICAXE program lines: reg = SELECTA + 3 opcode = FSET+1 opcode2 = FADD + 2 writei2c 0, ( reg, opcode, opcode2 ) ; set Register A to uM-FPU register 3 ; command to make register A = reg 1 as the B register ; command to add to register A with reg 2 as the B register ; add giving register 3 = register 1 + register 2

As you can see, it is possible to include several math commands into a single write i2c program statement. If we wish to perform a division of 1234 by 4321 and save the result into the uM-FPU register 4, the PICAXE program lines are: reg = SELECTA + 4 opcode = FSET + 1 opcode2 = FDIV + 2 writei2c 0, (reg, opcode, opcode2) ; set Register A to uM-FPU register 4 ; code to set selected register = register 1 ; divide giving register 4 = register 1 / register 2

5.2 Trignometric Functions The PICAXE X1 and X2 parts do include trigonometric functions Sin, Cos and for the X2 parts only Atan. But this functions are limited to 90 one degree increments using a look-up table methodology with the result multiplied by 100 to give the equivalent of 2 decimal places. The uM-FPU can perform trig functions but do this in radians so there are two steps to find the value for an angle given in degrees. For example, if we wish to find the value for Sin of 45 degrees the PIACXE program code is: dataByte = 45 ; set angle as 45 degrees reg = SELECTA + 7 ; set Register A to uM-FPU register 7 opcode = LOADUBYTE ; command to load the opcode2 = FSET + 0 ; set Register A to uM-FPU register 0 writei2c 0, (reg, opcode, dataHigh, dataLow, opcode2, RADIANS, SINE) ; giving register 7 = SIN( Radians( 45 deg) ) Since the opcodes doe not include any offset to another register, seven byte can be saved from the PICAXE program by placing the opcode and opcode2 commands directly into the writei2c program line as: dataByte = 45 ; set angle as 45 degrees reg = SELECTA + 7 ; set Register A to uM-FPU register 7 writei2c 0, (reg, LOADUBYTE, dataByte, FSET, RADIANS, SINE)

5.3 Extended op-codes for uM-FPU V2 chip Some of the uM-FPU commands require an initial command ( XOP ) to indicate an extended function. The ArcSine, ArcCosine and ArcTangent are in this category. See the uM-FPU V2 datsheets and other documentation for the full list of these commands requiring the extension operator For example if we wished to calculate the ArcSine of 0.70711 then the PICAXE program lines are:

Note that the default micoMega program template only has two opcode command variables defined so the command for conversion from radians to degrees is directly placed into the writei2c program line in this example. reg = SELECTA + 8 writei2c 0, ( reg, ATOF, 0.70711, 0, FSET ) opcode = XOP opcode2 = ASIN writei2c 0, ( opcode, opcode2, DEGREES) ; set Register A to uM-FPU register 8 ; command to indicate an extended operation ; command to calculate the arcSine value in radians ; giving register 8 = ASIN(0.70711) in degrees

At the expense of readability, we can place more of the opcodes directly into one writei2c command and again save 7 bytes: reg = SELECTA + 8 ; set Register A to uM-FPU register 8 writei2c 0, ( reg, ATOF, 0.70711, 0, FSET, XOP, ASIN, DEGREES )

While in the above examples each result has been placed in a different register within the uM-FPU V2 chip, for many applications, the registers 1 to 15 may hold more permanent values or constatnts and the working register is register 0 when an intermediate value could be left pending the next part of the ongoing calculations.

5.4 Use of Parenthesis for equations The use of parenthesis in equations with the uM-FPU V2 is possible using the LEFT and RIGHT commands. The previously referenced microMega Corp tutorial Using uM-FPU V2 with the PICAXE
Microcontroller on page 12 covers the use of parenthesis, so no further examples are given here. The uM-FPU V2 includes 5 temporary registers which are used to hold intermediate values when parenthesis are included. Each time a LEFT command is used, the next available temporary register is invoked and used as Register A until a RIGHT command is actioned. Because there are 5 such temporary registers, if parenthesis are nested (one within another) to a depth of greater than 5 levels, the value of the Register A is set to a special value representing not a number.

6.0 Retrieving values from the uM-FPU V2 chip


So far, we have covered getting values into the uM-FPU V2 chip and performing some math functions. But we also need to be able to retrieve those final values from the uM-FPU chip back to the PICAXE for display on an LCD module or other purposes. MicroMega Corp has in the available PICAXE programming template provided a number of subroutines for calling data back from the uM-FPU chip in a format suitable for the value involved. Typically, the result of a calculation will be a floating point value so the most frequently called subroutine will be the call to print_floatFormat . This uses the FTOA command to convert the floating point number to an ASCII character string. Alternatively there is also the LTOA command for converting a Long Integer into an ASCII string. To retrieve the values it is first necessary to send some further data to the uM-FPU chip to define the format for the output presentation. This data is (for the provided programming template) placed in a variable called format.

The value for format has two digit decimal value using the following conventions: For the Floating Point format ASCII string, If format = 0 then the ASCII string will use as many digits/characters as necessary with up to 8 significant digits. If the number is very large, the exponential notation is used, for example: 12345E6. If the format is non-zero, then: the 10s digit indicates the total number of characters to be displayed inclusive of sign, decimal point and digits after the decimal point. The units digit indicates the number of digits that will be shown after the decimal point.

Thus for the value 1234.567 in Register A, with the format value of 6.3 this would equate to 1234.567 but as that requires 8 characters to display the uM-FPU will instead send back **.*** with the format value of 8.2 this would equate to _1234.56 and as that does fit within the specified 8 characters to display, so the uM-FPU will send back the ASCII string _1234.56 with a leading blank signified here only by the underscore character.

More examples on the effects of the format value are given in the microMega documentation. To retrieve the value from our earlier math example to calculate the arcsine of 0.70711 held in register 8, the PICAXE program lines will be: reg = SELECTA + 8 writei2c 0, (reg) format = 83 gosub print_floatFormat ; set Register A to uM-FPU register 8 ; specify a total of 8 character with 3 decimal places

The returned ASCII string for this will be __45.000 with two leading spaces

7. Conclusions
The uM-FPU V2 chips cost somewhat more that the PICAXE chips, and therefore whether you use i2c comms and an X/X1/X2 PICAXE chip or use SPI comms with a M series PICAXE, the uM-FPU will not be a chip that you add to every project. The above does not cover all of the functionality of the uM-FPU V2 chip but is sufficient to help you get started. There are additional commands including as LEFT and RIGHT which relate to parenthesis for use with more complex calculations. But when used it is a very useful chip to reduce the number of variables and complexity of the math calculations within the PICAXE chip. For some weather/environmental type modules such as the HopeRF humidity and barometric pressure sensors where there are complex math or math that could result in an overflow of the PICAXE math capabilities, then the UM-FPU is great. I would envisage that for a robot needing to measure distances and directions and undertaking complex calculations to determine the line of travel or position then the uM-FPU will be an advantage. Where GPS modules are involved, it is warranted to even go one step further and use the more powerful uM-FPU V3.1 which operates faster internally and can directly accept GPS output strings.