It is no secret that our PAK-VI lets you connect a PS/2 keyboard to a Basic Stamp. The example code you can find in our document library uses the PAK-VI to generate Morse code using a standard keyboard. I've seen other people use the PAK-VI and a wireless keyboard to command a robot. I've also heard of people interfacing "keyboard wedge" scanners using the PAK-VI.
When I first designed the PAK-VI, I tested using the chip with a PS/2 mouse. It worked, but I didn't really develop the idea and although the literature says it can be done, I've never really provided an example. Well, this month marks the end of that! I'm going to show you how to interface a mouse to a BS2 or any micro using the PAK-VI.
Why would you want a mouse on a Basic Stamp? A track pad or a track ball can allow you adjust analog values in a very intuitive way. In addition, you can gut a mouse and get a very nice X/Y position system. I've always thought this would be a cheap way to "close the loop" on a homemade CNC mill, for example. With some mechanical linkage, you could even use a mouse to track the movement of a robot.
The normal PS/2 mouse sends three byte packets. This is unlike the keyboard which sends scan codes. When you reset the mouse, it sets its output off. If you want to listen to the mouse, you have to enable it. Since none of this relates to ASCII characters, you'll want to set the PAK-VI to raw mode before you do anything.
The mouse has two modes you can set. Stream mode just spits position packets out as the mouse moves. The PC uses this mode, but for the Stamp it isn't very handy. Luckily, the mouse also supports a remote mode. In this mode, the mouse accumulates position information. When you ask for the information, the mouse sends a three byte packet and resets the position information. That way you don't have to constantly monitor the mouse for input. However, the mouse can only track differences of +/- 255 counts, so you have to read the mouse often enough to prevent overflow (there is an error indicator if you wait too long).
The first byte of each packet contains several status bits, defined in my program like this:
yover var p1.bit7 ' y overflow
xover var p1.bit6 ' x overflow
ysign var p1.bit5 ' y sign
xsign var p1.bit4 ' x sign
midbtn var p1.bit2 ' button flags
rightbtn var p1.bit1
leftbtn var p1.bit0
As you might expect, the xover and yover variables tell you if you've had an overflow. The flags that end with btn indicate when a particular button is pressed.
The xsign and ysign flags are 1 when the corresponding value is negative (meaning the mouse direction is "backwards" from the positive direction. However, when a quantity is negative, the mouse sends the data (the 2nd byte is the x data and the 3rd byte is the y data) in 2's compliment format. So you either have to sign extend the data or convert it to a magnitude before you use it. My code converts it to a magnitude.
The connections required are Stamp pin 15 to the PAK's output, pin 14 to the PAK's input, and pin 13 to Enable2.
I hooked an Alps Glidepoint trackpad to a PAK-VI and ran the program below. Here's the screen shot:
The program shows the accumulated X and Y positions, plus the button status. As you read through the program here are a few fast facts to keep in mind:
Sending $02 to the PAK-VI puts it in raw mode |
|
Sending $0B to the PAK-VI causes it to send the next byte directly to the mouse |
|
$F0 sets remote mode |
|
$EB requests a motion packet |
|
$FA indicates a successful reply from the mouse |
|
The expression ((xreg-1)^$FF) computes the magnitude of a negative number in xreg |
Other commands that I did not use include:
0xF3 - Set the sample rate. The mouse responds with "acknowledge" (0xFA) then reads one more byte. After receiving the sample rate, the mouse responds with 0xFA and resets the movement counters. Valid sample rates are 10, 20, 40, 60, 80, 100, and 200 samples/sec. |
|
0xF2 - Get device ID. The mouse responds with "acknowledge" (0xFA) followed by 0 for a standard PS/2 mouse. The mouse also resets its movement counters. |
|
0xE8 - Set resolution. The mouse sends back an 0xFA and then waits for another byte. A 0 byte sets 1 count/mm, a 1 sets 2 counts/mm, and 2 sets 4 counts/mm, and 3 sets 8 counts/mm. |
'{$STAMP BS2} ' Mouse code for BS2 and PAK-VI pakout con 15 pakin con 14 baud con 84 fpin con 13 keyin var byte ' This assumes a 3 byte packet ' Some mice can do 4 byte packets ' (mainly those with wheels) but ' you have to turn on that mode p1 var byte ' mouse status xreg var byte ' raw x motion xmov var word ' x accumulator yreg var byte ' raw y motion ymov var word ' y accumulator ' flags in p1 yover var p1.bit7 ' y overflow xover var p1.bit6 ' x overflow ysign var p1.bit5 ' y sign xsign var p1.bit4 ' x sign midbtn var p1.bit2 ' button flags rightbtn var p1.bit1 leftbtn var p1.bit0 high fpin ' Reset PAK and wait for device reset serout pakout,baud,[$FF] pause 500 xmov=0 ymov=0 ' Enter raw mode serout pakout,baud,[2] ' Set remote mode serout pakout,baud,[$0B,$F0] serin pakin\fpin,baud,[keyin] ' should get $FA if keyin=$FA then top Debug "Didn't get $FA from remote mode set",cr top: ' read movement packet serout pakout,baud,[$0B,$EB] serin pakin\fpin,baud,[keyin,p1,xreg,yreg] if keyin=$FA then parse debug "Didn't get $FA on mouse poll",cr goto top parse: if yover or xover then overflow if xsign=0 then xplus ' convert negative number xmov = xmov - ((xreg-1)^$FF) goto doy xplus: xmov=xmov+xreg doy: if ysign=0 then yplus ' convert negative number ymov=ymov- ((yreg-1)^$FF) goto ydone yplus: ymov=ymov+yreg ydone: ' Display results debug cls, sdec xmov, " ", sdec ymov ,cr if leftbtn=0 then checkmid Debug "Left button down",cr checkmid: if midbtn=0 then checkr Debug "Mid button down",cr checkr: if rightbtn=0 then top Debug "Right button down",cr goto top overflow: Debug "Overflow occured",cr goto top
Site contents © 1997-2018 by AWC, Houston TX (281) 334-4341