High Level Design
Our design approach made use of an accelerometer, a graphics LCD, and the AT90s8515 mcu (see hardware). The project could essentially be divided into two parts:
Decoding the output from the accelerometer (return a speed, as well as directions of motion)
The output from the accelerometer is two square waves, one of which is shown in Figure 1. Each axis, x- and y-, has an associated square wave. The duty cycle of the square wave is proportional to the acceleration experienced by the chip. By measuring the duty cycle, we are able to calculate the acceleration at any given time, and hence the tilt on the module. We can then translate the tilt into a speed on the ball, which is set using method get_speed() (see software for details).
Figure 1- Accelerometer output
Drawing the maze on the LCD and handling the motions of the ball
The LCD portion of the design had to contend with two main issues:
· Storing the maze
Assuming we could draw a sufficiently complex maze, we needed some way to store information about it. Specifically, we needed to know about which paths were open, and which paths were blocked. With 512 bytes of RAM and 8K of Flash, memory is very limited on the AT90s8515. Meanwhile, the LCD we used is a 320x200 pixel display. Of course, the option was there to use the LCD's built-in controller for extra memory space. However, we wanted to have several mazes to choose from, meaning that we needed some way of storing a succinct representation of the other mazes on the AT90s8515. The scheme we arrived at was to divide the LCD into an array of Y rows and X columns. Each element of this array would be either ‘on’ (blocked), or ‘off’ (open). With 12 rows and 13 columns, we were able to create mazes of reasonable complexity.
· Moving the ball
The issue of respecting the bounds of the maze was inherently resolved by our definition of the maze. The ball would simply never be drawn in an element of the maze array that was ‘on’. A more challenging concern was that of varying ball speeds for different degrees of tilt. An initial proposal was to speed up the refresh rate of the game for higher speeds and slow it down for lower speeds. We arrived at a more elegant solution by reasoning that, since speed was the quotient of distance and time, we could more easily vary speed by varying the distance traveled than by changing the (game refresh) time. Figure 2 illustrates our implementation for a three-speed ball.
Figure 2 - Different Ball Speeds