
































































































































































































































Stephen Peek | Peek Helicopters | Peek Fireworks | Peek House | Model Jet Club

Description
The cube uses a 5 x 5 x 5 matrix of single 3mm Clear Green LEDs. This is a good size to experiment with as the number of LEDs required at 125 keeps the cost down, doesn't take too long to assemble. The power requirement is under 1 amp and the use of just one colour keeps both the hardware construction and control software fairly simple.
Cube Video please click on picture below.
The Circuit
The LED cube is made up from 125 LEDs arranged into 5 layers of 25 LEDs each. The display itself is multiplexed so instead of requiring 125 connections it requires one to each of the five layers and 25 to each LED in a layer making a total of 30. The cube is refreshed by a software interrupt routine with each layer active for 2ms, so the entire cube is refreshed every 10mS (100Hz). This results in a display with no visible flicker. Only 8 I/O lines are needed to control the LED drivers for the cube which allows a tiny 14 pin PIC 16F688 microcontroller to control the whole cube. This microcontroller has an internal 8Mhz clock and 4Kwords of program memory.
Each of the LED layers is arranged in a 5 x 5 matrix and controlled by a transistor in an emitter follower configuration connected to the LED anodes. When the respective layer control output from the PIC goes high the base of the transistor is held at +5V and the emitter sits approximately 0.7 volts below this. The transistors used are BC637 NPN transistors, if an alternative is used it should be of similar specification, have an Ic rating of at least 1 amp and check the pin out. he cathodes of the LEDs are connected to IC2 & IC3. These are STP16CP05 low voltage 16-bit constant current sink drivers. The LED current is set by a single resistor connected to the RSET input of the IC (pin 23). The 680R resistor gives a LED current of ~28mA; this resistor can be altered to vary the current supplied to the LED's

The outputs of the current sink drivers are controlled by data loaded into the driver IC over a serial input. The two driver ICs are cascaded so the PIC simply clocks in 25 bits of data to control the LEDs in each layer then sets the respective layer driver output high.The capacitors provide power supply decoupling. C4 and C5 in particular are important and should be tantalum bead types located close to the driver ICs Diode D1 allows the PIC programmer when attached to J1 (ICSP header) to detect power on the target board while preventing it from actually powering the target. Depending on your particular programmer this diode may be omitted altogether, but if in doubt fit it. The power LED is not critical, you can use almost any 3mm LED for this, or omit it altogether if you don't want a power indicator. Pin header JP2 provide +5volt and Gnd connections and also brings out the PIC I/O port pins RA4 and RA5. RA4 is also connected to the switch S1 on the PCB. These are made available for those of you who want to add additional features to the software.
Power to the circuit is provided through the DC input jack J1. This should be connected to a 5 volt regulated power supply capable of supplying at least 1 amp. The power supply should also be able to maintain regulation while the load switches between 15mA to around 700ma every 2mS, all the plug-top style ones in my workshop work fine but if you have problems this is something to check. The J1 (ICSP header) allows in-circuit programming of the PIC microcontroller. It will work with the genuine Microchip PICKit2 Programmer.
PCB Layout Overlay and Mirrored LED Cube Circuit Board Circuit Diagram
Component List from
Copy and Past the Part Number into Find then click search, when item appears, click on the blue More Details > > and then scroll down until you see
the part number highlighted in yellow 47-3108
| Component | Description | Part/Code |
| R1,2 (order 1 pack) | Pack 100 680R 0.25W CF RESISTOR (RC) x1 £0.50 | 62-0366 |
| R3 (order 1 pack) | Pack 100 10K 0.25W CF RESISTOR (RC) x1 £0.50 | 62-0394 |
| R4 (order 1 pack) | Pack 100 270R 0.25W CF RESISTOR (RC) x1 £0.50 | 62-0356 |
| C1,2,3 | 100N 2.5MM X7R DIELEC.CERAMIC (RC) x3 £0.14 each, Total £0.42 | 08-1015 |
| C4,5,6 | 10UF 10V TANTALUM BEAD 5MM (RC) x3 £0.10 each, Total £0.30 | 11-0624 |
| Cube LED's (order 125) | L-7104SGC LED 3mm S/Bright Green (RC) x125 £0.06 each, Total £7.50 | 72-8970 |
| D1 | BAT85 SCHOTTKY DIODE 30V DO-34 (RC) x1 £0.11 | 47-3108 |
| Q1,2,3,4,5 | BC637 TRANSISTOR NPN 60V 1A TO-92 TRU RC x5 £0.06 each, Total £0.30 | 47-5538 |
| IC1 | PIC16F688-I/P MICROCONTROLLER (RC) & PCB | Programmed £17.50 |
| IC2,3 | STP16CP05M SO24 16 BIT LED DRIVER (RC) x2 £1.40 each, Total £2.80 | 82-0125 |
| LED1 | L-7104GD MINIATURE 3MM GREEN LED (RC) x1 £0.08 | 55-0105 |
| socket for IC1 | 14 PIN 0.3IN DIL SKT (RC) ALSO 22-0132 x1 £0.27 | 22-0155 |
| J1 | 2.1 PCB DC POWER SOCKET (RC) x1 £0.15 | 20-0970 |
| JP1 | 5 WAY R/A SINGLE ROW PLUG (RC) x1 £0.07 | 22-0710 |
| JP2 | 4 W SINGLE ROW PCB HEADER PLUG RC x1 £0.04 | 22-0505 |
| S1 | TACTILE SWITCH 6X6MM HEIGHT 5MM (RC) x1 £0.12 | 78-0621 |
| LED matrix sockets | 32 WAY TURNED PIN SIL SOCKET(RC) x1 £0.55 | 22-1703 |
| Power supply | 5V 1.5A MINI PLUGTOP SW MODE PSU RC x1 £6.75 | 85-2955 |
Rapid Components £20.96 + £4.95 P&P (Total £25.91)
PCB & Programmed PIC16F688 £17.50 + £2.00 P&P (Total £19.50)
Acrylic Display Case for project £12.50 + £2.50 P&P (Total £15.00)
Total for Project £60.41
Acrylic Display Cases for your Projects
in-perspex-tive acrylic display
200mm x 200mm x 200mm £15 Inc P&P
Assembling the PCB
Soldering the surface mount parts and assembling the LEDs into a cube are not jobs for a novice electronic kit builder, don't attempt this projects unless you are confident of your ability. Assembly is in two stages; control PCB and LED cube. It's easiest to assemble the LEDs into a cube using the PCB to hold it in place so I suggest the PCB is assembled first.
Fig 1 Check the PCB to make sure
all the holes have been drilled, and look for any etching faults, bridges,
breaks etc. before commencing with the assembly.
Fig 2 The design has deliberately been kept to a single sided PCB,
however this has meant 16 wire links are needed to interconnect tracks on
the copper side.
You should start by installing these wires.
Fig 3 The silk screen overlay for the PCB doesn't show the location
of the 16 link wires. The location of the links is indicated by the yellow
lines overlayed on the photo.
Fig 1 Fig 2 Fig 3
Fig 4/5 Break the SIL socket in to individual pins and then solder one in to each of the 25 LED holes and 5 layer drive connections.
(you can of course solder the LEDs of the cube directly to the PCB, however it makes repair and removal of the cube difficult should you have a fault or wish
to swap cubes)
Fig 6 Install the resistors and diode. Make sure the band on the
diode body is orientated the same way as shown on the PCB overlay.
Fig 7 Install the capacitors. Note that the Tantalum capacitors C4/5/6 must be fitted the correct way round. There will normally be a vertical line and/or '+' symbol
on the package above the positive lead (see fig 12).
Fig 4 Fig 5 Fig 6 Fig 7
Fig 8 Install the 5 transistors, again ensuring they are positioned as shown on the overlay.
Fig 9 Finish the upper side of the PCB by installing the LED, switch, pin headers and sockets.
Fig 8 Fig 9
At this point, apply 5 volts to the DC input jack. Use a multimeter to ensure there is 5 volts present between pins 1 and 14 of the IC1 socket. If not find the fault and correct it before proceeding.
Fig 10/11 Views of the assembled PCB from different angles.
Fig 12 Note the polarity marking on the Tantalum capacitor C5. Also the orientation of the PIC16F688.
Fig 10 Fig 11 Fig 12
Fig 1. You should now tin with solder the PCB tracks that carry the 5 volt supply and the connections from the transistors to the layer connector pins as shown in
this photo.
Fig 14 Now install IC2/3 to the copper side of the PCB. You must ensure the IC is fitted the correct way round. The photo shows a small dimple on the top of the
IC package (bottom left). This denotes pin 1.
Fig 13 Fig 14
Carefully align and centre the package over the solder pads, then solder the corner lead on one side. Check the package is still aligned and then solder the opposite corner on the other side of the package. If it's still aligned, proceed to solder the remaining leads. Repeat this with the second IC. Check there are no solder bridges between any of the leads. If you do get a bridge use some solder wick (copper braid) to remove it.
Tip: Use a 0.8mm chisel bit and 22swg solder for the SMD devices; 18swg solder and/or a larger bit are much more likely to lead to bridges and shorts.
The PCB you can buy from the online store has a solder resist mask which greatly reduces the chances of bridging, though you still need to take care.
Fig 15. Once both ICs have been soldered in to place you should give the copper side of the board a thorough visual inspection to check for solder bridges between
pads and tracks. It's a good idea to spray the copper side of the PCB with a conformal coating once assembly is complete to protect against corrosion.
If you've bought the PCB for this project from the online store it already has a protective coating so this isn't necessary.
Fig 15
Install PCB standoff or spacers into the four mounting holes at the corners of the PCB. These should provide enough clearance to ensure the board isn't resting on the two Surface Mount ICs.
You should also install the PIC16F688 into the IC1 socket at this point making sure it is fitted the correct way round.
Connect a 5 volt supply to the DC power input jack J1. The power LED1 should light. Measure the voltage between pins 1 and 14 of IC1 to ensure there is 5 volts present.
WARNING, You must use a 5 volt regulated power supply.
If you apply a higher voltage to the board you will destroy the PIC and driver ICs. While the PIC is easy to swap out, removing the two surface mount ICs will be very difficult and likely to result in damage to the PCB.
Assembling the LED Cube
It takes me about 02h30m to assemble the LEDs in a cube and that doesn't include assembly of the main PCB so you'll want to allow yourself plenty of time.To assemble the LEDs into a cube you will need to make a simple jig using a piece of MDF or similar material. You can download a PDF template for the jig here.
5mm LED cube
Fig 1 Carefully bend the leads on each LED as shown. The LED cathode should be cranked out so it is aligned with the side of the LED package. This is more
important with 5mm LEDs than 3mm LEDs which have a much narrower package. The anode should be bent to an angle of 90o. Take care bending the leads
to avoid stressing them as they enter the LED body.
Fig 2 The LED anodes run horizontally around the jig and are connected together. The LED cathodes are perpendicular to the jig. Install five LEDs into one row of
holes as shown. The last LED should have its anode lead bent round so it connects with the LED in the next row. Solder the anode of each LED to the next
LED.
Fig 3 Using a 5 volt power supply and resistor (anything from 120 to 330 ohms will work), test each LED to make sure it is not faulty or installed with anode/cathode
terminals reversed. With a 125 LEDs to assemble getting one the wrong way round as the tedium sets in is quite likely!
Fig 1. Fig 2 Fig 3
WARNING, If you skip this test and get the LEDs assembled into the cube then find an LED isn't working it will be extremely difficult to correct it.
Fig 4 Install LEDs into the next row and solder their anodes together.
Fig 5/6 Connect the anode terminal of the right most LED to the LED in the next row. You will also have the anode lead from the LED to the left meeting at this point.
Solder all three leads together as shown making sure the lead from the LED on the previous row clears the vertical cathode lead.
Fig 4 Fig 5 Fig 6
Fig 7 Continue to install LEDs in to each of the rows, soldering and testing as you go.
Fig 8 With all five rows completed solder a wire across all the rows to hold the layer in shape. This wire also serves as an electrical connection.
Fig 7 Fig 8 Fig 9
Carefully remove the assembled layer from the jig and put to one side. Repeat the previous steps for each of the five layers.
Fig 9-12 These pictures show the general arrangement of the LED cube.
Assemble the cube by inserting the cathode leads of the first LED layer into the sockets on the PCB.
Next attach the second layer to the first. The best way to do this is lie the PCB on its side. Solder the four corner LEDs of the second layer to the first layer.
With the four corners soldered, put the PCB flat on the work surface. Next work around the outside of the cube soldering the two layers together. Then work your way in to the middle of the cube soldering each LED to the one below. It's a bit fiddly getting into the middle of the cube but not impossible.
All the time keep looking across the LEDs from several directions to ensure the LEDs in the upper layer are level and aligned with those in the layer below; make any adjustments as needed. If you don't keep the layers level as you go the whole cube will be distorted by the time you get to the very top layer.
Repeat this until all five layers are connected together to form the cube.
Fig 10 Fig 11 Fig 12 Fig 13
Fig 13 Once all the layers are in place attach the five wires to the layer drive sockets as shown in the photo. Ensure the wires do not short on each other as they rise up through the cube. The sockets are spaced apart on the PCB to help with this. The connections are labeled L0 to L4, L0 being the lowest layer, L4 being the top.
Firmware
The HEX file is ready to program directly into a PIC 16F688. The zip file contains the source code which you can modify or just view to see how it works. If you are going to modify the code I recommend you download and install the Microchip MPLAB IDE which will allow you to edit, modify and program the PIC seamlessly.
|
Programming Details
Controlling the LED Cube Display
The problem with using a data lookup table to drive the LED cube is the amount of data needed. If the data is packed it requires 16 bytes to hold the state of the cube (125 / 8 = 15.625). Since the 16F688 PIC only has 4K words of program memory and the main code uses ~1455 words that only leaves about 2600 words for table data. This in turn is room for only 168 complete cube states to be held in memory so if you wanted the text 'PICPROJECTS' to be displayed, shifting from the back to the front of the cube it would require 16 bytes x 5 frames per letter x 11 letters = 880 bytes.
Clearly the table lookup method isn't going to allow you to do very much before program memory runs out. To get round this, the cube is controlled using a macro command language that controls a virtual drawing processor. Using code written with the macro commands defined for the cube drawing processor the same animation can be done in 60 bytes. (See example code dpcode.txt)
The instructions are implemented using assembler Macros, for this reason the instruction mnemonics have to be different to the PIC instruction set and MPASM assembler reserved words. The instruction Macro names and register names are uppercase and case sensitive. The Macro instructions are converted into either one or two PIC assembler retlw instructions at assembly time. When the PIC ledcube firmware runs it reads these back as table data, decodes the instruction based on bit-fields and then calls assembler functions to perform the required drawing processor operation.
The Drawing Processor has 72 instruction, 8 registers, and a 33 level user stack. The instruction set is similar to PIC assembler and you will need to have knowledge of PIC assembly language programming and the Microchip MPASM / MPLAB IDE if you intend to write your own routines using it. Also an understanding of postfix stack operation wouldn't hurt. Since the DP code is generated from MPASM macros and just ends up being assembled with the rest of the PIC program code, all the usual MPASM operators and number formats are available to use when writing code for the DP.
Demo Code
The pre-assembled HEX file for the LED cube projects contains some demo animation sequences. The Drawing Processor code for this is contained in the file
CubeProgram.inc Overview In the context of this project, a Voxel is a single LED within the cube whose position is defined by its X,Y & Z coordinates.
Registers
The DP has 8 registers; 4 general purpose and 4 special purpose. All registers are 8 bits wide and can hold a value in the range 0-255. However, instructions that use values in the special function registers expect the value to be within the range shown in the table below. Values outside this range may result in unpredictable code execution.
Timer |
Timer
There is a single user timer that counts from a preloaded value down to zero in 1 second intervals.
Stacks
The DP has two stacks, a user stack and a return address stack. The return address stack holds the return address for Jump to Subroutine (JSR) instructions and is not directly accessible. The user stack is 33 levels deep and can be used to push/pull any user register. It is also used to perform math and logical operations by pushing the values on to the stack, then executing the operation, the result being pushed back onto the stack. To that end DUP, DROP, SWAP, OVER and ROT stack operators are also implemented.This is a similar to the FORTH programming language and not by coincidence:-).
The user stack pointer has wrap around capability so unmatched push/pull operations won't overwrite memory outside the stack
This is important as the ADD/SUB/OR/AND/XOR operators always push the result of the operation onto the stack. This means you don't have to pull the result unless you need it, but you should remember it is on the stack if you have something else pushed on the stack previously. See also DROP instruction which discards the entry on the top-of-stack.
The user stack can hold a maximum of 33 entries.
Be aware that the PUSHXYZ and PULLXYZ instructions use 3 stack entries.
The return address stack does not wrap and has no over/under flow checking.
The return address stack can hold up to 8 return addresses.
Flags
Fcarry - Set if carry occurred during add instruction, cleared if no borrow occurred during subtract (same as underlying PIC operations)
Fzero - Set if result was zero, cleared if result was non-zero. Fzero flag is also modified by TSTVOX, CMP, Timer and external switch instructions.
Instruction Set
r - register name
k - literal, constant data or label
| Mnemonic | Description | Flags | Register |
| NOOP | No operation | ||
| MSET | Modify operations will set voxel to on | ||
| MCLR | Modify operations will set voxel to off | ||
| MINV | Modify operations will invert current voxel value | ||
| SETALL | Turn on all voxels in cube (independant of MSET, MCLR and MINV instructions) | ||
| CLRALL | Turn off all voxels in cube (independant of MSET, MCLR and MINV instructions) | ||
| INVALL | Invert all voxels in cube (independant of MSET, MCLR and MINV instructions) | ||
| SHOW | Transfer drawing buffer to display and load value in RHOLD register into hold timer | ||
| VOX k,k,k | Load RX, RY, RZ and modify voxel [ 0 <= k <= 4 ] | RX,RY,RZ | |
| VOXM | Modify voxel at current RX, RY, RZ co-ordinates | ||
| TSTVOX | Test voxel at current RX, RY, RZ
co-ordinates. Fzero clear if voxel on : Fzero set if voxel off |
Fzero | |
| CHYR r | Draw ASCII character specified in register r in the Y (vertical) plane | ||
| CHZR r | Draw ASCII character specified in register r in the Z (horizontal) plane | ||
| CHY k | Draw ASCII character value k in the Y (vertical) plane [32 <= k <= 95] | ||
| CHZ k | Draw ASCII character value k in the Z (horizontal) plane [32 <= k <= 95] | ||
| LINE k,k,k,k | Modify a line of voxels, specify x inc, y inc, z inc, length | RX,RY,RZ | |
| LINEX | Modify line of voxels across the whole X axis, located at RY,RZ | ||
| LINEY | Modify line of voxels across the whole Y axis, located at RX,RZ | ||
| LINEZ | Modify line of voxels across the whole Z axis, located at RX,RY | ||
| PLANEX | Modify all voxels in the YZ plane, located in the X-axis at RX | ||
| PLANEY | Modify all voxels in the XZ plane, located in the Y-axis at RY | ||
| PLANEZ | Modify all voxels in the XY plane, located in the Z-axis at RZ | ||
| ROTATEX | Rotate entire cube along a line at y=2, z=2 in the x-axis | ||
| SHXL | Shift entire drawing buffer left one voxel. | ||
| SHXR | Shift entire drawing buffer right one voxel. | ||
| SHYU | Shift entire drawing buffer up one voxel | ||
| SHYD | Shift entire drawing buffer down one voxel | ||
| SHZF | Shift entire drawing buffer forward one voxel | ||
| SHZB | Shift entire drawing buffer back one voxel | ||
| DECX | Decrement RX register, modulo 5 | Fzero | RX |
| DECY | Decrement RY register, modulo 5 | Fzero | RY |
| DECZ | Decrement RZ register, modulo 5 | Fzero | RZ |
| INCX | Increment RX register, modulo 5 | Fzero | RX |
| INCY | Increment RY register, modulo 5 | Fzero | RY |
| INCZ | Increment RZ register, modulo 5 | Fzero | RZ |
| DECR r | Decrement register, modulo 256 | Fzero | r |
| DECRSZ r | Decrement register, modulo 256, Skip next instruction if result is zero | r | |
| INCR r | Increment register, modulo 256 | Fzero | r |
| INCRSZ r | Increment register, modulo 256, Skip next instruction if result is zero | r | |
| PUSHR r | Push register contents onto top of stack | ||
| PULLR r | Pull top of stack and place contents into register | r | |
| PUSHXYZ | Push registers RX, RY, RZ on to stack | ||
| PULLXYZ | Pull registers RX, RY, RZ from stack | RX,RY,RZ | |
| DROP | Pull entry from top of stack and discard it ( a -- ) | ||
| SWAP | Swap top two entries on stack. ( a b -- b a ) | ||
| DUP | Duplicate entry on top of stack. (a b -- a a b ) | ||
| OVER | Operates on the stack : (a b -- a b a ) | ||
| ROT | Operates on the stack : ( a b c -- b c a) | ||
| TSTZ | Test value on top of stack and condition Fzero flag (a -- a ) : a==0 Fzero set, a != 0 Fzero clear | Fzero | |
| ADD | pulls two values from the stack, adds them together and pushes result back onto stack | Fzero Fcarry |
|
| SUB | pulls two values from the stack,
subtracts them and pushes result back onto stack order is (TopOfStack-1) - (TopOfStack) -> TopOfStack |
Fzero Fcarry |
|
| AND | pulls two values from the stack, performs a bitwise 'AND' result is pushed back onto stack | Fzero | |
| OR | pulls two values from the stack, performs a bitwise 'OR' result is pushed back onto stack | Fzero | |
| XOR | pulls two values from the stack, performs a bitwise 'XOR' result is pushed back onto stack | Fzero | |
| NOT | pull value from top of stack, perform bitwise 'NOT' operation on byte and push result back on to stack | Fzero | |
| CMP r, k | Compare register contents with k. If contents of r == k then Fzero Set, else Fzero Cleared. | Fzero | |
| LDXYZ k,k,k | Load RX, RY, RZ [ 0 <= k <= 4 ] (see also VOX k,k,k) | RX,RY,RZ | |
| LDR r,k | Load register with value k [0 <= k <= 255 ] | r | |
| LDRAND r,k | Load register with random number in the range [ 0 <= Random Number < k ] | r | |
| LDTMR k | Load timer with period in seconds [1 <= k <= 255 ] | ||
| ADDTRND k | Add random number in the range [ 0 <= Random Number < k ] to contents of Timer | ||
| SKIPZ | Skip next instruction if Fzero flag is set | ||
| SKIPNZ | Skip next instruction if Fzero flag is clear | ||
| SKIPC | Skip next instruction if Fcarry flag is set | ||
| SKIPNC | Skip next instruction if Fcarry flag is clear | ||
| SKIPTOUT | Skip next instruction if Timer == 0 | ||
| JUMP k | Jump to program address k | ||
| JSR k | Jump to subroutine at address k | ||
| RET | Return from subroutine | ||
| RANDSEED | Seed random number generator with non-zero value from TMR0 | ||
| SYNCEXT k | Wait for a falling edge on SW1 input before continuing program execution or timer out | Fzero | |
| TSTSW | Test SW1 input. Set Fzero flag if switch active (pressed), Clear Fzero flag if switch not active | Fzero |
Show
All drawing instructions operate on the drawing buffer. This allows a new image to be built up in the drawing buffer while the LED cube displays the contents of the display buffer. To transfer the drawing buffer into the display buffer you must use the SHOW instruction. When the show instruction is executed it will wait for the previous hold delay to complete if it is still active. It then sets the buffer transfer flag and waits for the display driver to copy the drawing buffer into the display buffer and clear the transfer flag. At this time the value in RHOLD is transferred into the hold timer and the instruction exits. RHOLD timer is period to wait x 10mS. If RHOLD is 0, the buffer is transferred at the next cube display refresh.
This command is blocking, program execution will not continue until the current hold timer has timed out and the interrupt display driver has transferred the buffer.
___________________________________________________________________________________________________________
MSET, MCLR, MINV instructions control the operation of VOX, PUT, LINE and PLANE instructions.
MSET turns on voxels
MCLR turns off voxels
MINV inverts the current voxel state
_________________________________________________________________________________________________________________________________________________________________
VOX RX, RY, RZ / VOXM / TSTVOX instructions operate on a single Voxel
The voxel is modified according to current mode set by MSET / MCLR / MINV instruction.
VOX RX, RY, RZ loads co-ordinates into RX, RY, RZ and modifies the voxel
VOXM modifies the voxels using current RX, RY and RZ co-ordinates
TSTVOX test the voxel at the current RX,RY,RZ co-ordinates and then sets the Fzero flag.
Fzero flag is cleared if the voxel is on, Fzero is set if the voxel is off.
__________________________________________________________________________________________________________________________________________
SETALL, CLRALL and INVALL instructions operate on the entire cube
These instructions operate independently of the current Voxel mode set by the MSET, MCLR, MINV instructions.
__________________________________________________________________________________________________________________________________________
Stack Operations
Stack Notation:
( stack before -- stack after ) e.g. SWAP ( a b -- b a )
PUSHXYZ ( -- Z Y X)
PULLXYZ ( Z Y X -- )
These instructions two instructions push and pull the X,Y and Z registers to/from the user stack in a single command. The order the registers are pushed onto the stack is X-Y-Z, so the Z register is at the TOS after a PUSHZYX instruction.
PUSHR Rn ( -- Rn)
PULLR Rn ( Rn -- )
Push or pull the single register to/from the top of the user stack
DROP ( a -- )
discards the top entry from the stack
SWAP ( a b -- b a )
swaps the top two values on the stack
DUP ( a -- a a )
duplicates the top entry onto the top of the stack
OVER (a b -- a b a )
inserts copy of the top stack entry behind the second entry
ROT ( a b c -- b c a)
rotates the top three entries on the stack.
__________________________________________________________________________________________________________________________________________
LDTMR, ADDTRND and SKIPTOUT instructions control the operation of a user timer.
The timer is loaded with the number of seconds required for the timer period. It then counts down until it reaches zero and stops. The SKIPTOUT instruction tests the current value in the timer and will skip the next instruction when it reaches zero.
ADDTRND instruction adds a random value between 0 and k-1 to the value already in the timer.This allows the timer to be loaded with a random value between any two values, by using a LDTMR instruction followed by a ADDTRND instruction.
__________________________________________________________________________________________________________________________________________
SYNCEXT
The sync external instruction waits for a falling edge on the S1 input or a timeout before continuing program execution.
If the timeout value is set to 0, the instruction waits indefinitely for a falling edge before continuing. If the timeout value is set between 1 and 255, the instruction waits until either a falling edge is detected or the timer reaches 0. The timer decrements at one second intervals and is shared with the other timer instructions. The timer is not cleared if the instruction exits on a falling edge.
The Fzero flag is set if the instruction exits on a falling edge, and cleared if it exits on a time out.
SYNCEXT 0 ; wait indefinitely for falling edge on S1 input before continuing
SYNCEXT 12 ; wait for 12 seconds, or failling edge on S1 input before continuing
There is no software debouncing implemented on this control input, it expects a clean logic level signal.
TSTSW
The TSTSW instruction reads the logic level on the switch input. If the logic level is low (switch pressed) the Fzero flag is set, if the logic level is high (switch not pressed) the Fzero flag is cleared. This instruction is not blocking, the input is tested, the Fzero flag conditioned and code execution continues.
__________________________________________________________________________________________________________________________________________
DECRSZ and INCRSZ instructions do not modify the Fzero flag.
DECR and INCR instructions do modify the Fzero flag.
I appreciate this doesn't seem logical but it reflects the way the underlying PIC instructions work.
INCX, INCY, INCZ and DECX, DECY, DECZ instructions do modify the Fzero flag. These instructions use Modulo 5 for the increment/decrement so the number increments from 4->0 and decrements from 0->4.
It is important to note that the DECR, INCR, DECRSZ, INCRSZ can be used on all registers including RX, RY, RZ. However, this can lead to a value in the register that is outside the valid range of 0 =< Rxyz =< 4 since these instructions operate on the byte modulo 256. Instructions that follow and operate on the values in the RX, RY , RZ registers may cause the underlying PIC firmware to crash if the value is outside of the expected range.
__________________________________________________________________________________________________________________________________________
SHXL, SHXR, SHYU, SHYD, SHZF, SHZB instructions shift the entire drawing buffer one voxel in the direction specified. The voxels at the incoming edge of the shift are cleared (set to off)
Example for a Shift Down.
Before After

__________________________________________________________________________________________________________________________________________
LINE x_inc, y_inc, z_inc, length
This instruction modifies a line of voxels.
x_inc, y_inc and z_inc can have a value of -1, 0 or 1
The start point for the line is the current value in RX, RY, RZ
After the voxel at RX,RY,RZ has been modified:
RX = RX + x_inc : RY = RY + y_inc : RZ= RZ + z_inc : Length = Length -1
This repeats until Length == 0
The Line instruction will leave RX, RY and RZ values set to the finish point for the line. This allows consecutive line instruction to draw a new line starting from the end point of the previous line.
The increment/decrement operation on the registers are modulo 5 so the decrement will roll under from 0 back to 4 and the increment rolls over from 4 to 0
Example
| LDXYZ 0,0,0 LINE 1, 1, 1, 5 plots a line through the following voxels
|
MSET LDXYZ 0,4,2 LINE 0, -1, 1, 3 plots a line through the following voxels
|
||||||||||||||||||||||||||||||||||||||
MSET LDXYZ 2,2,2 LINE -1, 0, 1, 4 plots a line through the following voxels
|
MSET LDXYZ 0,0,0 LINE 0, 0, 1, 5 plots a line through the following voxels
|
___________________________________________________________________________________________________________
LINEX, LINEY, LINEZ
These instructions draw a full length line across one axis in the drawing buffer.
The voxels in the line will be set, cleared or inverted according to the current mode set by the most recent MCLR, MSET or MINV instruction.
These three instructions execute faster than using the LINE instruction.

LINEX Example of LINEX.
located in the Y-Z planes by the current values of RY and RZ
Values in RY and RZ registers locate the line in the YZ axis.
LINEY
located in the X-Z planes by the current values of RX and RZ The value of RX register is ignored.
LINEZ
located in the X-Y planes by the current values of RX and RY
The RX, RY and RZ register values are unchanged by these instructions
__________________________________________________________________________________________________________________________________________
PLANEX, PLANEY, PLANEZ
The PLANE instructions fill an entire plane in the drawing buffer.
The voxels in the plane will be set, cleared or inverted according to the current mode set by the most recent MCLR, MSET or MINV instruction.

Value in RX specifies position along the X-axis. Value in RY specifies position along the Y-axis. Value in RZ specifies position along the Z-axis.
__________________________________________________________________________________________________________________________________________
CHZ, CHZR, CHY, CHYR
A 5x5 character set has been defined for the ASCII characters in the range 32 to 95. This covers 0-9 and uppercase A-Z along with most symbols.
The characters can be drawn in the XY plane along the Z-axis or the XZ plane on the Y-axis.
There is no support for drawing characters in the YZ plane.
Character 'A' in the XY plane Character 'A' in the XZ plane
value in RZ positions character in the Z plane value in RY positions character in the Y plane

Given the way the PLANEY and PLANEZ commands work you would expect CHY and CHZ commands to work the opposite way round to the way they do and I wouldn't disagree but if I change it now it breaks any code people may have already written.
________________________________________________________________________________________________________________________
Finished RGB LED Cube 4x4x4 from www.lomont.org now being sold at www.hypnocube.com priced at £285 Inc P&P
4096 colours

Finished RGB LED Cube 8x8x8 from www.hypnocube.com priced at £1,000 Inc P&P
4096 colours click on picture for video