PICAXE Cheat Sheet AND Optimisations

Flying-High with PICAXE Optimisations

PICAXE 08M2+ BASIC Commands


Full Programming Manual can be found in the PICAXE Editor 6 via Help button.

OUTPUT

HIGH or SWITCH ON Switch an output pin high ( on)

High 2 'turns pin 2 on

LOW or SWITCH OFF Switch an output pin low (off)

Low 3 'turns off pin 3

TOGGLE Toggle the hi/lo state of an output pin

Toggle 3 'changes pin 3 from high to low or low to high

PULSOUT Output a timed pin inverted pulse

Pulsout 0,3 'pin 0, 30 microsec

PWM Provide a pulse width modulation output

PWM 1, 20, 8 'pin 1,20/255 duty,8 cycles

SOUND Make sound(s) 0 =quiet, 255 = hiss.

Sound 4,(90,10) 'sound pin 4, ~4kHz,~100ms

LET PIN(S) Set multiple pin(s) at same time

Let pins = %00000101

INPUT

PULSIN Measure input pulse duration (uS)

Pulsin 4,0 ,w2 'pin 4 input, logic low triggered

READADC Read analog Pin (0 - 160) into a variable

Read 1, b2 'read pin 1 voltage on pin 1 into b2

TIME DELAY

PAUSE Wait up to 65535 ms ( 65.5 secs ) + ~1 ms o'hd.

Pause 100 ' pauses ~100ms =0.1s

WAIT Wait for up to 65 secs

Wait 3 'wait for 3 seconds

SLEEP 2.3 second low power delay (1 to 65535)

Sleep 3600 'sleep > 1 hr

NAP Short low power 20uA ( <2.3 secs)

Nap 3 'sleeps for 144ms

END Power down stop until reset

End 'indefinite power down sleep

I/O PIN CONTROL

OUTPUT Set a pin as an output

Output 1 'make pin 1 an output

INPUT Set a pin as an input

Input 4 'make pin 4 an input

REVERSE Reversethe I/O state of a pin

Reverse 4 'change pin 4 from OP > IP or IP > OP

LET DIRS = Simultaneously set all pin directions (1 = OP)

Dirs = %0000001011 'make pins 4, 2 & 0 outputs

Note: Pins 1 to 4 are INPUT by default on power up until set by program command controlled by an output command such as high low sound


PROGRAM FLOW

IF...THEN Jump to new program line depending on condition

If b3 < b2 then ledoff

FOR...NEXT Establish a for- next loop

For b2=0 to 100 step 2  'Counts even numbers

BRANCH Jump to address specified by output if in range ( akin to ON x GOTO )

GOTO Jump to a label

Goto loop ' Goes back to the main loop

GOSUB Jump to subroutine at address specified

Gosub test ' Heads to test subroutine

RETURN Returns to main prog. from gosub routine

Return ' Return to point just after subroutine call

Labels clarify and identify points in the program

FlashLED: ' Identify beginning of FlashLED module

VARIABLE MANIPULATION

LET Assigns a value to a variable, does limited L-R maths

Let w0 = b2 * 22 / 7 ' Pi

LOOKUP lookup indexed data specified by offset & store

lookup 1,(6,7,8) ' takes 7

LOOKDOWN Search values for a target's match number & store in variable. Akin to $strings

RANDOM Generate a pseudo-random number

Random b1 ' Randomise b1

SERIAL I/O

SERIN Serial data input

Serin 4 ,n2400,b1 ' read byte on pin 4 into b1 @24000bd

SERIN Serial data input - qualified

Serin 4 ,n2400,("A"),b1 ' read byte after A

SEROUT Serial data output ( to 2400bps)

Serout 0, n2400, (65) ' sends ASCII 65 (A)

INTERNAL EEPROM ACCESS

( Note this used for both prog. & data storage ! Care – since program overwriting may occur)

EEPROM Store data in EEPROM before download

eeprom 0,("hello") ' store from location 0 hello

READ Read data EEPROM into variable

Read 100,b2 ' get byte in address 101into b2

WRITE Write variable into data EEPROM

Write 101,b3 ' put byte b3 into address 101

MISCELLANEOUS

DEBUG Displays variable value on attached PC screen

Debug b0 ' read shows b0 value on VDU

REM Remarks, Semicolons (;) or apostrophe (') preceed remarks/comments, & also colons (:) as usual in BASIC

SYMBOL Assign a value to a new symbol name. symbol RED_LED = 7symbol COUNTER = B0 Uses no extra memory space!


Legs Pins and Function
LEGPINNOTES
1Plus Power+Ve Power Supply, +3V to +5V
2SerialInput only for program download
3Pin 4Input or Output
4Pin 3Input only
5Pin 2Input or Output
6Pin 1Input or Output or Analogue input
7Pin 0Output or program serial/debug out
8Minus Power-Ve Power supply (0V)
PICAXE 08 Pinout
PICAXE 08 Electrical Characteristics
  • 3 VDC from 2 x AA alkaline battery in switched
    battery box is the recommended power supply
  • Current draw = 600uA idle no load
  • Current draw = 100uA sleep/nap no ld
  • Digital out high = Supply –0.1V OC
  • Digital out high = 12mA out to –ve
  • Digital out low = 0.0 Volt OC
  • Digital out low = 27mA in from +ve
  • Digital In 1 = High >= 0.9 Volt
  • Digital In 0 = Low <= 0.85Volt
  • ADC In 0V=0, 1.5V=128, >2V=160(max)
  • PWM Out 0 = 0V, 128=1.5V, 255=3V
Simplified Getting Started
  1. Download or install software
  2. Start programmer: Start>Programs>
    Revolution Education>Program Editor
  3. You may like to copy the start menu shortcut
    to the desktop for easy access
  4. If Needed install USB – Serial Adaptor using the
    the correct supplied driver.
  5. Start the program
  6. View>Options Change Mode to PICAXE-08
  7. Select Serial Port Tab and choose Com Port
  8. Click OK

Loop Back Serial Test

Insert LED +ve (long lead) into the middle

socket (data to PICAXE pin 2) of the

programming lead. Insert the short lead into the outer

(return data to PC pin 1).

Press F8 to open the Serial Coms screen.

Type in some characters and click on the
send button. The LED will flash and data
should appear in the top window.

Notes and Tips
  • At 3 volts the chip can’t be damaged.
  • Test each new instruction by itself.
  • Use debug to check your program.
  • Forget about chip leg numbering as
    soon as possible! Think software pins.
  • Filename.bas = basic language program
  • Filename.cad = flow chart program.
  • Example *.bas and *.cad programs can be found:
    File > Open > Samples
Function Keys

F1 Quick Short Syntax Help

F4 Simulate Flow Chart

F5 Convert Flow Chart to Basic

F5 Load Basic Program into PICAXE

F6 Re Activate Debug Screen

F8 Serial Communications Screen

F9 Data Logger Screen

Quick Links for additional information about PICAXE.

Typical Hookup

PICAXE 08 Hookup

PICAXE Optimisations

Tips and Tricks for Making Your Code Fit

Program optimisation is an art, but based upon scientific principles and technical observations.

Download PDF

Before considering optimisations for PICAXE code, it is important to realise that most optimisations will make your program code less readable, less understandable, less maintainable, and harder to debug than unoptimised code.

It is therefore recommended that all but the simplest optimisations should be left until your code has been completed, tested and debugged. This may not however always be possible when you are running out of program code space before your code is finished. In such circumstances it is recommended to apply as few optimisations as possible to make your program code fit.

Unless there is a real need to perform optimisation it is often better practice to leave the code unoptimised. And if you do implement any optimisations it is wise to document what you have done, and why, in your program source code, if you wish to understand the code when you return to it at a later date, or pass it on to another PICAXE programmer.

Most of the lower-end PICAXE's are pretty constrained devices when it comes to the amount of program code which they can hold; quite often just 128 or 256 bytes of program which may have to be shared with EEPROM data. It can therefore be a challenge to make your program fit into the available space - There is nothing worse than adding a single line of code only to find that you have suddenly exceeded the maximum amount of memory available.


The art of making a program fit into the available space is called 'optimisation', and there are two sorts; optimising for speed of execution, and optimising for minimal program code space. The two are often mutually exclusive as a compact program, usually with loops, needs all those loops unrolling into repeated sequential code to gain a speed advantage, and vice-versa. For the PICAXE however, it is quite common that optimisations to reduce code space will also speed up the program because of the way the PICAXE holds its program in memory.

Unlike a traditional microcontroller where a single instruction takes multiple numbers of locations in program code memory, the PICAXE uses a system where the instructions are not of a fixed size. This means that the shorter the instructions it needs to use the more that can be fitted into the available code memory, and the shorter the instructions, the quicker ( in general ) they are to execute.

The optimisations detailed here are all designed to reduce the program code size and hopefully increase the speed of execution. Speed may not always be increased though because, if an instruction is placed into memory such that it overlaps two consecutive memory locations, and that's quite likely, then it will take slightly longer to execute. The loss of execution speed may be regained elsewhere by other optimisations which improve it, and it is a small price to pay to make the program fit which is often far more important than the raw execution speed.


Numbers

The first thing to know is that the larger the value of a constant ( a number ), the more program memory bits it will use; a 0 or 1 requires four bits, 2 to 15 requires seven bits, 16 to 255 require 11 bits while 256 to 65,535 require 19 bits. Using the smallest numbers you can may achieve great savings.

Suppose you want to take the inputs from Pin 6 and Pin 5 and turn these into a value in 'b0' of between 0 and 3. One obvious solution would be ...

b0 = pins & %01100000 / %00100000

It works, but the '%01100000' is a number which requires 11 bits in total to represent it. If we do the division before the '&' masking we can use ...

b0 = pins / %00100000 & %00000011

It still works, but because '%00000011' only requires seven bits, we just saved four bits ( over 30% ) which can be used elsewhere.


Pin Numbers

The size of numbers is also important when it comes to instructions which operate on input and output pins; "HIGH", "LOW", "PULSIN", "PULSOUT", "SERIN", "SEROUT" and others.

Using pins 0 or 1 adds just four bits to the instruction whereas using pins 3 to 7 adds seven bits. Designing your hardware so your most commonly referred to pins within the code are Pin 0 and Pin 1 can have a significant effect across a complete program.


Numbers in Variables

Variables require seven bits to represent themselves, so if you are using a large number a multiple number of times it can make sense to put that value into a variable and use the variable where the number would have been ...

w0 = w1 & $1000 + $1000

can be rewritten as ...

w2 = $1000
w0 = w1 & w2 + w2

Although the initial assignment into 'w2' adds extra code, the net result is a saving of bits. Of course, the more frequently a number is used, the greater the saving in total.


Optimising Variables

There are very few options for optimising variables. Unlike numbers they do not use different sized representations depending on the variable used.

The only real optimisation which can be achieved is in assignments where the variable being assigned to also appears as the first variable immediately on the right hand side of the '=' ...

b0 = b0 + b1
    b0 = b0 + 1

are more program code space efficient than ...

b0 = b1 + b0
    b0 = 1 + b0

Assignments using FOR

A rather clever trick, which can only be used in your program if you are not otherwise using FOR..NEXT loops is to replace simple assignments which have no mathematical operations to them with a 'FOR' statement ...

b0 = 29
    b1 = b0

Can be replaced by ...

FOR b0 = 29 TO 29 ' b0 = 29
    FOR b1 = b0 TO b0 ' b1 = b0

All the 'FOR' part of the FOR..NEXT loop does is to initialise what would be an index variable with the value which appears immediately after the '=', the value after the 'TO' is redundant and could actually be anything at all. The clever part of the FOR..NEXT loop is all associated with the 'NEXT', which we won't be using, but the 'FOR' part assignment is a lot shorter than the proper way of doing it.

There are two problems with this optimisation; firstly it is not easily seen that it is an optimisation and not some coding error without some additional commentary explaining it, and it will not work if you do need to use FOR..NEXT loops in your program, as the compiler is likely to complain when you do a Syntax Check or attempt a download.


Redundant Assignment Operations

It is important to remember that the PICAXE compiler performs very few optimisations itself, and it will generate code to do whatever you ask it to ...

b0 = 0 + 0 + 0 + 0 + 0

will generate four completely redundant additions of zero, even though they will not have any effect upon the value assigned to 'b0'. The same occurs if you divide or multiply by one and in a number of other cases.

While it is relatively easy to spot redundant operations such as the example above, it is much harder to spot them when named constants defined by 'SYMBOL' are used ...

SYMBOL y = b0
    SYMBOL x = b1
    SYMBOL M = 2
    SYMBOL C = 1

    y = M * x + C

In this case there is no redundancy, but if M were zero or one, or C were zero then there would be redundancy.

Named constants are a double-edged sword; while making your code more readable and modifiable, they can also have the unwanted side-effect of using up excess program space. The choice between using named constants or not is not an easy one to make.


Negative Numbers and Constant Arithmetic

Although the PICAXE deals only with positive numbers, two's complement arithmetic means that negative numbers can be represented, and are often useful as in the following code ...

GoUp:
        b0 = 1
        GOTO Go

    GoDown:
        b0 = 0 - 1 ' b0 = -1

    Go:
        b1 = b1 + b0

The PICAXE does not allow 'b0=-1' and this has to be derived by using 'b0=0-1' as in the above example. This uses an unnecessary 9 bits of program code. When we are subtracting one constant from another, we will end up with another constant, so by pre-calculating that result ( 0-1 is $FF in this case ) we can simply replace the 'b0=0-1' with the equivalent constant, 'b0=$FF'.

The same pre-calculations can be applied whenever the PICAXE is being instructed to perform constant arithmetic itself, for example ...

w0 = w0 * 2 * 1000 / 4

becomes ...

w0 = w0 * 500

This technique is commonly known as "Constant Folding".

There are special cases to be careful of ...

b0 = b0 * $8000 / $8000

In this example it would appear that multiplying by a number and then dividing by that same number is a pointless operation which achieves nothing, however there is much more to it than first meets the eye.

All arithmetic is performed using 16-bits, and a large multiplication, as above will cause a result greater than 16-bits. Those bits above the bottom 16-bits are lost, and this can often be used to great effect. The above code is actually a very poor way to do 'b0 = b0 & 1', and constant folding would not give the result expected.

The same issues can apply with division followed by multiplication ...

b0 = b0 / 4 * 4

This is equivalent to 'b0 = b0 & $FC', and again, constant folding will not give the result desired.


Conditional Assignments

Often you will want to set a variable's value depending upon some condition or other, in a pseudo design language ...

IF pin0 = 0 THEN
        b0 = $0F
    ELSE
        b0 = $F0
    END IF

Using the PICAXE programming language, a reasonable implementation of the example is as follows ...

IF pin0 <> 0 THEN SetToF0
            
    SetTo0F:
        b0 = $0F
        GOTO SetDone
            
    SetToF0:
        b0 = $F0
            
    SetDone:

This can be optimised to ...

b0 = $0F
        IF pin0 = 0 THEN SetDone
        b0 = $F0

    SetDone:

The same technique can be used when setting or clearing Digital Outputs but care must be taken to ensure that 'glitches' caused by setting the Output incorrectly before setting it correctly does not cause problems with the attached hardware ...

LOW 0
        IF b0 = 0 THEN SetIoDone
        HIGH 0
    
    SetIoDone:

Optimised FOR..NEXT loops

There is very little which can be done to optimise FOR..NEXT loops; they use a fairly large amount of program space, but then the equivalent inline code where a variable is initialised, incremented or decremented and a conditional branch to the start of a loop uses just the same amount.

The only significant savings can be made where a FOR..NEXT loop takes an index variable between two pre-defined numbers, which is the case with most ...

PrintSixteenStars:
        FOR b0 = 1 TO 16
            SEROUT TX_PIN, TX_BAUD, ("*")
        NEXT
        RETURN

The FOR..NEXT loop is defined as 'FOR b0 = 1 TO 16' because the loop needs to be executed sixteen times; loop 1, loop 2, and so on through to loop 16.

Because the index variable 'b0' is not actually used within the loop, and is effectively used as a simple count of how many times it has gone through the loop, it could equally be '11 TO 26' or '2 TO 17', but the optimum is '0 TO 15', because, as we know, the program code space taken up by numbers depends upon the value of the number and 0 and 1 use less program code than 2 and above, and 2 to 15 use less code space than 16 and above.

Although the change of the starting value from 1 to 0 makes no saving, changing 16 to 15 saves four bits.

It is not always easy to optimise the FOR.NEXT values, especially where the index value needs to be used within the loop, but you will be coding for maximum space saving if your FOR..NEXT loop starts with value 0, and failing that, at value 1.


Redundant GOTO RETURN's

Having a 'GOTO' to a 'RETURN' statement is wasteful as the GOTO can simply be replaced by a 'RETURN' ...

GOTO Finished

    Finished:
        RETURN

Redundant GOSUB RETURN's

A 'GOSUB' followed by a RETURN can simply be replaced by a 'GOTO' to the subroutine. Not doing so is wasteful in three of ways; it requires more code space, it takes longer to execute, and it eats into the number of GOSUB's you may be allowed to have in your program.

GOSUB MyRoutine
    RETURN

Should simply become ...

GOTO MyRoutine

Wasteful GOSUB Allocation

If you are using a PICAXE which can support 256 GOSUB's but are using only 16 or less, then you should configure the compiler to use just 16 GOSUB's as this will reduce the program code required for each GOSUB.


LOOKUP versus READ and EEPROM

The 'LOOKUP' command can, in some circumstances, be fairly program space hungry and can sometimes be implemented with less program memory used by using of 'READ' and 'EEPROM'. The two following code examples both turn a value of 0 to 3 held in 'b0' into a character "A" to "D" put into 'b1' ...

Convert:
        LOOKUP b0,("A","B","C","D"),b1
        RETURN

    Convert:
        READ b0,b1
        EEPROM 0,("A")
        EEPROM 1,("B")
        EEPROM 2,("C")
        EEPROM 3,("D")
        RETURN

Duplicated Textual Strings

It is worthwhile noting that specifying textual strings as opposed to individual characters makes no program space saving. In the above example, using 'EEPROM 0,("ABCD")' would save no program space at all.

Duplicated strings are however another entirely different matter, and are most likely to occur when using the 'SEROUT' command to send information to an LCD or PC ...

PlayerWins:
        SEROUT TX_PIN,TX_BAUD,("You are the winner")
        SEROUT TX_PIN,TX_BAUD,(CR,LF)
        RETURN

    ComputerWins:
        SEROUT TX_PIN,TX_BAUD,("I am the winner")
        SEROUT TX_PIN,TX_BAUD,(CR,LF)
        RETURN

Reasonably long duplicated strings may be removed into a separate, common routine while still producing a net saving of program space ...

PlayerWins:
        SEROUT TX_PIN,TX_BAUD,("You are")
        GOTO TheWinner

    ComputerWins:
        SEROUT TX_PIN,TX_BAUD,("I am")

    TheWinner:
        SEROUT TX_PIN,TX_BAUD,(" the winner")
        SEROUT TX_PIN,TX_BAUD,(CR,LF)
        RETURN

Consecutive SEROUT's

The 'SEROUT' command is fairly program space hungry and large savings can be made by combining consecutive 'SEROUT' commands into one ...

TheWinner:
        SEROUT TX_PIN,TX_BAUD,(" the winner")
        SEROUT TX_PIN,TX_BAUD,(CR,LF)
        RETURN

becomes ...

TheWinner:
        SEROUT TX_PIN,TX_BAUD,(" the winner",CR,LF)
        RETURN

Duplicated Code

As with removing duplicated strings above, the same can be applied to any duplicated code ...

RoutineOne:
        w0 = w0 * 2
        w1 = w1 + 1000
        RETURN

    RoutineTwo:
        w0 = w0 * 2
        w1 = w1 - 1000
        RETURN

The 'w0=w0*2' and RETURN are common to both routines, and as the assignment to 'w1' is not dependant upon 'w0' the two routines can be re-ordered and optimised ...

RoutineOne:
        w1 = w1 + 1000
        GOTO CommonCode

    RoutineTwo:
        w1 = w1 - 1000

    CommonCode:
        w0 = w0 * 2
        RETURN

SEROUT Pin Numbers

As mentioned earlier; referencing pins 0 and 1 uses less program code than any other pins, so if you have a number of 'SEROUT' statements it makes sense to design your hardware so that they are all reference Pin 0 or Pin 1 wherever possible.


Redundant Code

As the PICAXE will generate code for redundant operators during assignments, it will also generate code for redundant statements; those statements which are never executed.

If you have any statements which are there because they, "may be used later", but are not presently used, then it is wise to comment them out of the code until they are needed. It can often be difficult to spot redundant code, especially when it is a subroutine which is never called, and was written when you thought you may need it.


The END Statement

Do not put an 'END' statement as the last statement of your source code; the compiler will always automatically insert one at the end of your program whether it is needed or not.


PICAXE is a trademark of Revolution Education Ltd. These PICAXE pages are produced entirely independently of Revolution Education Limited and may not reflect the opinion of Revolution Education Limited or its agents. The information provided is based upon and derived from information published by Revolution Education Limited, other sources of PICAXE information and the author's own experiments and prior experience. The views expressed by the author do not necessarily represent those of Revolution Education Limited or its agents. While every effort has been made to ensure that the information on these PICAXE pages is accurate and correct, the author can accept no responsibility for any errors or omissions which do occur. The information provided is used entirely at your own risk.


First published Copyright (C) 2004 - The Happy Hippy on Thursday the 25th of February, 2004 at 14:38:14
Last upload was on Sunday the 25th of July, 2004 at 16:36:45
Edited and used with consent for Ralph Bayer VE3XRM on Thursday the 19th of October, 2023 at 11:13:14


22 Page Views [1]