There are two ways of constructing a software design; one way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.
- C. A. R. Hoare

Our software was almost entirely programmed in C and made for implementation on a MEGA163 microcontroller. The MEGA163 was chosen since it allows us to use an internal analog to digital converter (ADC). Our primary need when developing the software was to produce a state machine that would reliably change voltages that can be produced fast enough that our eyes can not distinguish one output from another on the oscilloscope.

Calculating the speed we needed to refresh points, which would create an interrupt in our microcontroller, turned out to be easier than expected due to a little ingenuity. After realizing that computer monitors are constantly being refreshed without us noticing, we determined that we could take advantage of the same principle. It was determined that the monitor needs only flash at 75Hz avoid being detected by the most astute user. In part to play it safe, and even more to allow easier multiplication by us, we rounded this figure up to 100Hz. Since we are displaying 16 points to make a paddle, and there are three states, it was logically deduced that we would have to create interrupts at a rate of 16*3*100Hz = 4.8kHz. After completing our code however, it became apparant that we don't need to flash the ball for 16 cycles however, so this number can be reduced, but since the microcontroller is clocked so much faster anyways, speed did not turn out to be an issue. Our interrupt was thus set to be approximately 1/4.8KHz, or .208ms. This number was later rounded for simplicity to .208ms, and served as the basic delta t for our state diagram.

The software contains three states, two interrupts and an initialization. The timer 1 compare A interrupt controls transitions between states from our state machine. These states control the outputs to PORT B and PORT C, which are transformed by our Hardware Design to allow smooth input for the oscilloscope.

The interrupt for the ADC is also enabled by our software. This enable allows us to grab the voltage used to produce our paddle intermittantly from our voltage divider. The ADC interrupt is hardcoded so that we can ensure that we are grabbing the correct value from the voltage divider, and only when necessery. to avoid excessive delays.

The three states are paddle1, ball, and paddle2. Both paddle states are virtually the same, so I may not always go in depth with the second. The paddles states send PORT C (the y-axis) of the microcontroller an 8 bit number which can be converted to an analog signal for the oscilloscope. 16 points are sent out by incrementing the bottom position of the paddle (given via our Hardware Design) by 16 different offsets. These offsets are linearly increasing from between 0 and 51, which corresponds to 1V through our DAC. PORT B of our paddle states is set to 0 for paddle1, and 255 (~5V through our DAC) for paddle 2. In this way, the paddles are set at the side edges of the scope, and can move up and down by the user.

The ball state consists of the majority of our code. The state controls the motion of the ball as its name implies. The ball is hard coded to start off by moving towards player two after the user presses the start key (button 3). At this point, it begins a horizontal trajectory, until it either strikes the second paddle, or passes it. If it strikes the paddle, the ball begins moving towards player 1, except with some velocity in the vertical axis. This velocity is determined by the point where it strikes the second paddle, and can vary from -3 to 3 (the number is of course converted to a voltage through the DACs). If the ball passes the paddle, then it will remain there to indicate a point has been scored. In addition, a signal is sent out to the board's LEDs to signify the score in binary. The user can strike the ball and send it back again only after hitting button 3. This was coded in to allow for breaks, as well as to again make it easier to distinguish a score. We named this feature the "Beezer Rule" in honor of Abeezer Tapia, since he had to foresight to show us how a user can cheat =) Also after scores the users can reset the game by hitting button 3 and 4 simultaneously. The ball will imediately be transported to the middle of the screen and start off towards player 2 once more.

Oscilloscope PONG is hardcoded to have games up to 7. At this point, the game must be reset to play again. This reset feature works the same as the one described above.