Note: This document explains how to use a mouse in streaming mode. For more information about remote mode see: pak6mou.htm (but notice that pak6mou.htm uses the old PAK-VI which has a slightly different pinout than the PAK-VIa).

You probably know we make the PAK-VI which allows you to read a PS/2 keyboard from a Stamp or any other RS-232 capable device. We recently redesigned the PAK-VI and now it has twice the buffer it used to and it consumes much less power.

One of the application notes for the PAK-VI shows how to connect the PAK to a mouse and read it in remote mode. Remote mode prevents the mouse from flooding the Stamp with data, which is good because the mouse generates quite a bit of data.

This month I thought I'd look at how you might use a mouse or trackball just as a direction sensing device. In this case, you don't care about the flood of data because you aren't trying to accumulate a position, but just a direction.

The circuit is right out of the datasheet. Pin 8 goes to the pin of the Stamp that will receive the data. Pin 7 connects to the transmit pin of the Stamp. The Data and Clock pins go to the PS/2 connector of the mouse instead of the keyboard.

It is easy enough to shift the PAK into raw mode using software. However, you could also wire the IMODE pin high to force the chip to start in raw mode. However, I like to start in cooked mode. Why? Here's a troubleshooting tip: If you connect the PAK-VI to a keyboard and IMODE is grounded, the keyboard's LEDs will work the way you expect. If they don't then the PAK-VI is not working for some reason (faulty wiring, failure to oscillate, etc.). When you are sure the keyboard is responding, you can be sure that any problems you are having are between the Stamp and the PAK.

One note about the schematic: The software below will work with the older PAK-VI. However, the pin out is different (and there is no IMODE, for example). So for the original PAK-VI, just wire it up according to the old datasheet and the software should work (that's another reason I didn't want to rely on IMODE).

Keyboards and mice want to send data at their own rate. The PAK reads it and buffers it so the Stamp can draw the data at its own rate. To facilitate this, the Stamp software uses the flow control feature of the SERIN command. The ENABLE2 pin is connected to the SERIN flow control pin. Each time the Stamp wants a byte, it brings the pin low and the PAK sends a byte. Suppose you are reading on pin 14 and have flow control on pin 13. You should write:

SERIN 14\13,84,[somebyte]

Here's where the keyboard troubleshooting came to the rescue. I had hastily written:

SERIN 14/13,84,[somebyte]

The Stamp compiler didn't complain. It simply divided 14 by 13 (resulting in 1) and used pin 1 as the SERIN pin! Needless to say, this didn't work as I expected it to. However, since the keyboard lights were working, I knew the PAK was operating and could focus on the Stamp side where I had made a typo.

When you slip the PAK-VI in raw mode with a mouse attached, nothing happens. That's because the mouse is quiet until you enable it to send data. Remember that before you send any data to the mouse you have to escape it with a $0B character to prevent the PAK from trying to read it as a command. An $F4 command will wake the mouse up. It also causes the mouse to reply with a byte, so you'll want to read that byte back before trying to read the remaining data.

Each movement packet on a standard mouse has three bytes. The first byte contains several flags and button indicators. The second byte is the x movement and the third byte is the y movement. In this case, we only care about two things: if there was any x or y movement, and what direction the movement was in.

Looking at the last two bytes of the packet will answer the first question. If either byte is zero, the corresponding axis is not in motion. In the first byte, bits 4 and 5 represent the X and Y sign. So if either of these bits are set, it indicates a motion in one direction, and a clear bit indicates motion in the opposite direction.

Once you know the format, the code almost writes itself. The program outputs 4 LEDs on Stamp pins 4, 5, 6, and 7 to indicate direction and also prints out a compass heading on the debug terminal. In real life you might control a pair of servos or stepper motors. A trackball makes a great device for controlling motors this way.

The only problem is how to determine when to stop. The mouse doesn't normally send anything if you aren't moving it. There are two ways around this. One, you can have the operator press a mouse button to stop. That will send a packet with no motion (assuming you aren't moving the mouse while pressing the button). However, I chose a different tactic. I simply set a timeout value on the SERIN command. When the mouse hasn't sent any data for awhile, I clear the direction information (which would presumably stop the motors).

The Stamp Code


m1 var byte
m2 var byte
m3 var byte
nsew var nib
NORTH con %1000
SOUTH con %0100
EAST con %0010
WEST con %0001
leds var outb ' 4 LEDs for nsew
pak6in con 15
pak6out con 14
pak6hs con 13
pak6baud con 84  ' change to 240 for BS2P, BS2SX

' reset PAK and let it settle down
serout pak6out,pak6baud,[$FF]
pause 500
serout pak6out,pak6baud,[2,$b,$f4] ' set raw mode & wake up mouse
serin pak6in\pak6hs,pak6baud,[m1] ' throw away mouse ack
' (NOTE: could just hardware tie the PAK-6 to raw mode)

' read mouse packet
serin pak6in\pak6hs,pak6baud,1500,done,[m1,m2,m3]

' This code figures NSEW
if m2=0 then tryy
if m1.bit4 then dowest
nsew = nsew | EAST
goto tryy
nsew = nsew | WEST
if m3=0 then done
if m1.bit5 then dosouth
nsew = nsew | NORTH
goto done
nsew = nsew | SOUTH

' From here down, the code does output
if nsew<>0 then checkn
debug "-"  ' no motion
goto notwest
' You could also write the next test
' if nsew.bit3=0 
if ~ nsew & NORTH then checks
debug "N"
if ~ nsew & SOUTH then checke
debug "S"
if ~ nsew & EAST then checkw
debug "E"
if ~ nsew & WEST then notwest
debug "W"
debug cr
goto top

Site contents © 1997-2014 by AWC, 310 Ivy Glen, League City, TX 77573    (281) 334-4341