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