electronic game

advertisement
EE 331 Final Report
Group:
Brett Hysuik, Joshua Twarynski
Project:
Simon electronic game.
Block Diagram:
See attached schematic.
MCU Choice:
Initially the PIC16F684 was chosen because it is a midrange device that offers all the
features we needed. We required a minimum of 9 I/O ports and the 16F684 has 12 I/O pins. No
features other than controlling I/O pins were required, so a more complicated and expensive
device was unnecessary. One of the group members also owns the microcontroller and
development board, so it made sense to use something we already had. However during the
development of our project we broke a pin on the PIC16F684 MCU. We then decided to replace
it with the PIC16F84A. This MCU was chosen because it was a suitable midrange device. We
also chose the PIC16F84A because it allowed us to make minimal changes to our code even
thought we were using a different PIC family. A majority of class time was spent on the
PIC16F84A so we were able to adapt quickly to the new MCU.
Design Features:
The key features of the code design are the output sequence, the user defined inputs, via
push buttons, the level compare sequence, and the delay subroutines. The features of the
hardware design include the crystal oscillator, the push buttons and the LEDs.
Our version of the Simon electric game has four levels each with a unique sequence of
flashing LEDs. Each individual output for each level is stored in its own memory address and is
configured upon power up. There is a predefined pattern so if the game does reset then the levels
will stay the same. This was done to simplify the algorithm needed to compare the user inputs to
the level outputs in order to determine if the user has entered the correct sequence. A delay
subroutine was used to flash the lights for a set amount of time (less than one second) so the user
can actually comprehend the output sequence rather than the flashes being instantaneous.
Another delay subroutine is used between levels so the next level doesn’t instantly begin after
the user inputs a fourth value.
The user defined inputs are another key feature of our design. After each output
sequence of a level the user is expected to replicate the pattern of the flashing LEDs. This is
done through corresponding push buttons. Once the flashing output sequence has stopped the
white led will turn on and remain on, signalling to the user that the game is expecting an input.
The user will then press a button corresponding to the LED he or she thinks is the correct one in
the output sequence. While waiting for the user input, the program continually loops, testing to
see if a button has been pressed. Once the program has detected a button press it will then loop
continually until that button has been released. This is a key feature of the input because it
eliminates any disruption caused by the button being held for a period of time that is either too
short or too long. This combined with the delay subroutine being called after a button has been
pressed eliminates the problem of the button being held too long and registering that value again
for the next user input. Once the program has detected a button press it will then store a value
corresponding to one of the LEDs. Each level will require four inputs and since there are four
levels we used 16 memory addresses to store the user inputs. This also helped to simply the
algorithm used to compare the user inputs to the level outputs. As an example if the user pressed
the button corresponding to the red LED four times for the input to the first level (that is the
output for the first level) then in four separate memory addresses the 0th bit will be set to 1. (This
is because the red LED corresponds to the 0th bit. The blue LED corresponds to the 1st bit, the
green LED corresponds to the 2nd bit, and the yellow LED corresponds to the 3rd bit of the
memory addresses used to store the user inputs.
Once the user has pressed four buttons and therefore entered four corresponding input
values then the program will then compare the user inputs to the particular output sequence for
that particular level. The algorithm used to compare the user inputs to the level outputs is
relatively straight forward. Once the user has pressed four buttons for a particular level the
program will then compare those inputs to the output sequence generated for that level. This is
done by moving the first output of the level sequence into the working register and then AND the
working register with the value stored for the first input. If the values are the same then the
result will be 1. If the values are not the same then the result will be 0. The ZERO flag is then
tested to determine if the user has entered the correct corresponding value. If the value is correct
it will then test the second part of the output sequence. If the value is incorrect then the program
will go to the reset state, (this is the state that the game begins in). At the reset state all the LEDs
are lit, with the exception of the white LED. The program then loops until any button is pressed
and the game begins. If the user has entered the correct values for all four levels then the
program will flash each LED one at a time and then enter the reset state.
There are multiple delay subroutines implemented frequently in our project. They are
used to extend the time between levels, extend the time in which the LEDs are flashing and to
eliminate the problems that occur from pressing and holding a button for too long. Without the
delay subroutines this project would not be successful.
In our design we used a 4MHz crystal oscillator. We did not have any particular timing
constraints with our project so the common 4MHz crystal oscillator was an appropriate choice.
Our design also features 4 push buttons used for the user input. The push buttons are
implemented for the user to match the corresponding output sequence for the given levels.
We use five different coloured LEDs in our project. The red, blue, green, and yellow
LEDs are used for the level output sequences. The white LED is used to let the user know when
the program is ready to accept input. We also used resistors to limit the current through the
LEDs so we didn’t blow them by passing too much current through.
Design Challenges:
The major design challenges we face were accepting and storing the user input, along
with properly comparing the user input with the corresponding level output.
When accepting the user input we needed to implement a loop to detect that a button has
been pressed. Once the program detected this we needed to loop again until the button was
released. Before we implemented the second loop we encountered one particular problem. If a
button was pressed and held too long then the program would register multiple inputs instead of
just a single input. However this was overcome by adding the additional loop until the button
was released and by adding a short delay after each input. We also ran into problems when we
ran the program and failed to correctly pass all the levels, sending the game to the reset state.
Once this happened and the game was played again there were still values stored in the
corresponding input addresses that caused the game to malfunction. This was overcome by
clearing all the input addresses upon entering the reset state or the win game state.
We faced the challenge of correctly comparing the input values to the corresponding
level output values with our game. The comparing portion at times would malfunction until we
added the code to clear all the input addresses during the reset or win game states. Once we did
this the program worked properly and now moves on to the next level only if the user has entered
the correct input sequence corresponding to the particular level output sequence.
Design Shortcomings:
Our project has one major shortcoming. This is the fact that the four levels we have are
predefined and do not change. If the user plays the game a few times they should be able to
remember the output sequence for each level. We were unable to implement a random number
generator for the output sequences of the levels. This is due to our lack of depth and experience
with MCUs and assembly language. We thought about implementing this feature, however were
not able to develop an algorithm to successfully store and compare the output values to the given
input values. That is why we decided to implement predefined output sequences for each level.
In the future, this project could be expanded to include the above features.
Assembly Code:
See attached assembly code.
Work Distribution:
Both group members wrote the assembly code, with Brett focussing more on LED
outputs and Josh focussing on user input. Brett was able to develop the output sequences for the
four levels. He also successfully developed a few delay subroutines to ensure that the LED flash
time was neither too short nor too long and make sure that the next level didn’t begin instantly
after a fourth input was entered. Josh worked on the user input portion of the code allowing for
proper use of the push buttons and proper storage of the user inputs. Together we developed and
implemented a successful algorithm to compare the user inputs to the output sequences for each
level. Both of us worked together to debug and revise all parts of the code upon testing our
program. Both group members worked together to design the circuit and build the prototype.
Continually working together was the best way to distribute the work equally and build an
efficient product.
Block Diagram:
See the dedicated .BMP file for a better view of the schematic
Download