circuitcellar.com
Magazine Support   Digital Library   Products & Services   Suppliers Directory 
 
 





 

June 2006, Issue 191

Nontraditional Cursor Control
ATmega32-Based Motion Sensing


HIGH-LEVEL DESIGN

Two occasions during our senior year at Cornell University provided inspiration for our project. The first was when Bruce Land, our microcontroller programming professor, exclaimed, “I have free accelerometers, and they can be used to do cool things.” We immediately felt as though we should explore the possibility of basing a design on the accelerometers. We then thought for a while about the kinds of interesting devices into which we could integrate acceleration sensors. During our brainstorm session, inspiration dealt us a swift right hook. We agreed that a glove like the one Tom Cruise’s character used in the movie Minority Report (2002) would be an intuitive HCI that wouldn’t be impossible to make. Accelerometers seemed to be the ideal sensors for constructing a hand-mounted pointing device.

Our original plan was to use accelerometers to measure the acceleration of a user’s hand and then integrate that acceleration into a change in position. The math is simple. Using Verlet integration, we would approximate the integral of the acceleration to the second degree. Verlet integration interpolates between two measured accelerations, using the average slope between them to derive velocity. This is sometimes called trapezoidal integration. The equations are:

This approach, however, turned out to be a practical impossibility. Although we successfully implemented the Verlet scheme and watched a mouse cursor controlled by the scheme move on the screen as we had expected it to, the glove had to be held exactly at 0 g (or 1 g for Earth-normal) in all three directions. If gravity were allowed to affect the accelerometers at all, this acceleration added to the integral. With no negative acceleration to remove it, the change in position that we calculated grew boundlessly.

We needed gyroscopes to measure rotation from our calibration point so that we could remove the effects of rotation from our calculations and take into account only the lateral motion of the glove. Gyroscopes, however, are expensive. The cheapest ones come in ball-grid-array (BGA) packaging and can’t be soldered by human hands. We didn’t have access to a reflow soldering oven either, which is needed to attach BGA components.

So, we scrapped the idea of a gyroscope. Instead, we decided to construct a tilt mouse. Although it isn’t as impressive as a position-tracking device, the tilt mouse is easy to use (after some practice) and almost as neat as a position-tracking mouse. The process behind this scheme is straightforward. Simply measure the acceleration due to gravity on the mouse by sampling it with an ADC, and then multiply the sampled value by some constant to scale the output to a desirable level.

The Microsoft serial mouse protocol uses an 8-bit two’s complement number scheme to send data to the computer. The numbers output by the ATmega32 microcontroller’s ADC can be conveniently represented in the same number of bits, albeit in an unsigned format. As a consequence, we had to perform some bitwise math on the sampled values to scale the 0-to-255 range of the ADC to –128 to 127. We also had to make sure the output from the Analog Devices’s ADXL203 accelerometer was centered in the ADC sampling band. (In the next section, we’ll discuss exactly how this was done.)

In addition to scaling the output, we used a step filter on the data to make the mouse easier to use. Our accelerometer was so sensitive that the slightest hand motion would cause the device to output a nonzero acceleration. To give the user a more stable region around the zero point, we quantized all outputs below a certain level to zero and then normalized any outputs out of this cutoff range by the breadth of the cutoff range. For example, if the cutoff were |10|, the intersection of all numbers greater than –10 and all numbers less than 10 would define the cutoff region. Any outputs outside this range would be normalized by 10 or –10, depending on whether the output were negative or positive, respectively.

In addition to position changes, the mouse detects button presses. We implemented four buttons in our mouse: Output On/Off, Left Click, Right Click, and Scroll Enable. Each push button is connected to a port pin on the ATmega32 microcontroller. When the output on/off button is pressed, the serial mouse output to the computer is enabled, reenabled, or disabled. This allows you to move your hand and not have the motion affect the mouse pointer. The left click button functions as a left click on a mouse. The right click button functions as a right click on a mouse. The scroll enable button disables all motion and other button outputs while it’s held down. It causes the accelerometer’s y output to be interpreted as a scroll wheel output to the computer.

The only hardware/software trade-off with which we had to deal was the sensitivity of our ADC. The granularity per sampling division of the ADC is approximately 19.5 mV per division. When we used accelerometers with sensitivities of approximately 50 mV/g for our position mouse, the outputs of the devices had to be normalized to the full ADC range of 0 to 5 V so that we would have good sensitivity on our device. We’ll explain this in the next section.

The ADXL2303 accelerometers we used for our tilt mouse output 1,000 mV/g, so the sensitivity was much higher. But we decided to normalize the range to 2,000 mV/g to gain even higher sensitivity, especially because we already had the necessary circuits designed and constructed.

Another hardware/software issue to consider is push button bouncing, or the inconsistent state in which some push buttons can remain for a certain amount of time after a transition. Our buttons were internally debounced (see Photo 2). This enabled us to remove the button press state machine from our code. We could simply read the value of the push button when we needed to measure it.

(Click here to enlarge)

Photo 2—Using debounced push buttons, we cut the complexity of our polling logic and code length significantly because the buttons’ states would become consistent more quickly than we polled them.

Our design follows two standards. We use the Microsoft serial mouse protocol and an RS-232 serial connection. RS-232 uses –12 and 12 V for high and low signals, respectively, and it idles at 12 V. The ATmega32 microcontroller outputs 5 V high and 0 V low serial (TTL level), so we had to use a serial level shifter chip to enable it to properly speak with the computer.

The Microsoft serial mouse protocol works differently. When the RTS line of the serial connection is pulled logic high and then falls logic low, the computer expects you to send an identifier string to determine the type of device being used. The protocol expects data at 1,200 bps, 8 data bits, 1 stop bit, and no parity. The controller sends it an “MZ” message, indicating the Microsoft serial scroll mouse. The computer may query you for this information multiple times; however, after approximately five times, you can stop sending it the identifier code because it will consider you to be identified.

The packet format is shown in Figure 1. L, R, and M are the left, right, and middle mouse buttons, respectively. A one indicates pushed. A zero indicates not pushed. Y7 (most significant) through Y0 (least significant) represent the 8-bit two’s complement mouse delta Y, with positive Y pointing to the bottom of the screen. X is the same format as Y, with positive X pointing to the right of the screen. Z is also in the same format as Y, with positive Z being scroll up, except that Z is measured in 4-bit two’s complement. The first 1 bit in every packet is an extra stop bit. From what we’ve seen, some implementations set this bit high and some set it low. We listened to the data coming off of a genuine Microsoft serial mouse. It set the bit high, so we chose to set it high.

(Click here to enlarge)

Figure 1—Each packet sent using the Microsoft serial mouse protocol has this format. L, R, and M are the status of the buttons. The 8-bit Y and X represent the change in mouse position from the time of the previous packet.