F19: Smacman
Contents
- 1 Grading Criteria
- 2 SMACMAN
- 3 Abstract
- 4 Objectives
- 5 Introduction
- 6 Delivery Schedule
- 7 Parts List & Cost
- 8 Design & Implementation
- 9 Game Casing
- 10 Testing & Technical Challenges
- 11 Conclusion
- 12 References
Grading Criteria
- How well is Software & Hardware Design described?
- How well can this report be used to reproduce this project?
- Code Quality
- Overall Report Quality:
- Software Block Diagrams
- Hardware Block Diagrams
- Schematic Quality
- Quality of technical challenges and solutions adopted.
SMACMAN
Abstract
Our team has created a unique 2 player game involving a central screen of 64x64 LED matrix and two auxiliary controllers. The two opponents will face one another and will have a paddle on their side. A ball will travel between players which they have to deflect away. Additionally, each player will have a “monster” that will continuously move towards the ball and try to eat the ball. If a monster eats the ball, that opponent of the owner of the monster will lose. Therefore, it is beneficial for a player to try to place the ball closer to their monster and further away from the opponent’s monster in order to score. Additionally, if the ball contacts the side of the screen behind the player’s paddle, they will also lose. As the game progresses, the speed of the ball will increase and eventually, there will be variation in the movement of monster. The controllers(xBee--XB24-AWI) will be wireless and communicate with the master board which runs the game and drives the 64x64 LED matrix.The MP3 module(VS 1053) reads music files from an SD card and plays the music through a speaker interfaced with the board in the background.
Objectives
The main objective of the project is to develop a 2D two player Smacman game. Other milestones to achieve are as below:
- Change the direction and speed of the monster differently at different levels, depending on the direction of the ball on LED Matrix in real time.
- The controller which does wireless transfer of accelerometer values is used to control the movement of the ball
- Play music in the background and game sounds using MP3 Decoder.
- Design PCB for Master and the Controller which will interface all the peripheral devices to the SJ-two boards.
Introduction
The project is broadly divided into three nodes:
1. Master Node: The master node (one SJ2 board) receives the data from the controller nodes via XBee module which is used to control the paddle movement which will eventually control the game. It recursively polls to receive control packets from the controller nodes and updates the paddle movements as per user's input. The master node also controls visual display on the LED Matrix and the game logic.
2. Controller Node: The controller node (two SJ2 boards) consist of the XBee modules which transmits control packets to the master node using fault-tolerant broadcast wireless UART protocol.
3. Music Node: The music node (one SJ2 board) provides background music to the game which enhances the experience of the game.
About the game
- Both Players should try to hit the ball with the paddle placed on their side.
- Press switch on the controller SJ-Two board to start the game.
- Tilt the controller left or right to move the paddle.
- Hit the ball with your paddle before the monster eats it to get a score.
- To manipulate the speed and the direction of the ball move the paddle in the same or in the opposite direction of the ball.
- Avoid the monster of opposite player to eat the ball in your side, if this happens then the game is over, else the ball continues to move between the paddles.
- The speed of the monster increases when the ball will move in opposite direction to catch the ball.
- Level 1 has the monster of opposite player moving at your side along the edges. If any player exceeds a score of 33 then me move to Level 2.
- Level 2 has the monster of opposite player moving along x-axis at your side. If any player exceeds a score of 66 then me move to Level 3.
- Level 3 has the monster of opposite player moving along x-axis and y-axis at your side. If any player reaches a score of 100 then that player wins the game.
- Both the Players can play and pause the game anytime and resume from where the game was paused.
Team Members & Responsibilities
- Nick Schiffer
- XBEE, Controller Functionality, Communication Architecture, Game Logic Development, Enclosures, PCB Designing.
- Mohit Ingale
- LED Driver, Game Logic Development, Enclosures, PCB Designing.
- Ayesha Siddiqua
- Graphic Driver, Game Logic Development.
- Shreya Patankar
- Splash Screen Graphics Driver, Game Logic Development, MP3 Decoder, Wikimedia Update.
Delivery Schedule
Project Repository Link: Github Project
Week# | Date | Task | Status | Actual Completion Date |
---|---|---|---|---|
1 | 10/1/2019 |
|
|
|
2 | 10/15/2019 |
|
|
|
3 | 10/22/2019 |
|
|
|
4 | 10/29/2019 |
|
|
|
5 | 11/5/2019 |
|
|
|
6 | 11/12/2019 |
|
|
|
7 | 11/19/2019 |
|
|
|
8 | 11/26/2019 |
|
|
|
9 | 12/3/2019 |
|
|
|
10 | 12/10/2019 |
|
|
|
11 | 12/17/2019 |
|
|
|
Parts List & Cost
Item# | Part Desciption | Vendor | Qty | Cost |
---|---|---|---|---|
1 | SJTwo Boards | Purchased from Preet | 4 | $200.00 |
2 | 64x64 RGB LED Matrix | Sparkfun | 1 | $75.00 |
3 | Wiring Components and Cable | Waveshare | 1 | $20.00 |
4 | 3D printer filament spool(s) | HATCHBOX | 2 | $40.00 |
5 | XBEE Modules | From Preet and Adafruit | 3 | $27.00 |
6 | Batteries | Local | 2 | $4.00 |
7 | I2C 7-seg screens | Adafruit | 2 | $18.00 |
8 | XBee Programmer Boards | Waveshare | 3 | $35.00 |
Design & Implementation
Hardware and PCB Design
PCB Design
There are many softwares available for PCB design, among them Eagle is more popular. We chose EasyEDA for PCB design over Eagle because, it is an online free software so we din't have to worry about the license. We faced many issues while using this software but we found a good tutorial on youtube. The issues which we faced are discussed in the issue section of this wiki.
The steps involved in the PCB design process are described in the next section.
Schematic Design:
Our project can be divided into two main circuits, first is game display circuit and second is a console circuit. We decided to design separate PCB for both circuits as doing so can make wiring easy and improve the user experience.
Master Controller PCB schematic:
We have created on top PCB to mount on SJTwo board. One circuit will do the wire interfacing of SJTwo board to xbee, mp3 decoder, led matrix. This is the master board and it will recieve values from all the controllers and peripherals. This is our Main Circuit. We Also have a power jack to power all the peripheral devices so that we don't have to power SJOne board from PC while we are playing the game.
Controller PCB schematic:
We have created on top PCB to mount on SJTwo board. One circuit will do the wire interfacing of SJTwo board to xbee of the two game controllers which will in turn send the values of accelerometer to the master Xbee interfaced PCB. We Also have a power jack to power all the peripheral devices so that we don't have to power SJTwo board from PC while we are playing the game.
PCB Layout:
After schematic design, the most important step is to connect the PCB layout. In EasyEDA components is not automatically associated with it's PCB footprint, so it's user's responsibility to connect right PCB footprint with the right components. In our case, we did not have the footprint of JLC connector and Rocker switch. so, we created it in a different window and saved it. The amazing feature of KiCAD is once we have done with PCB layout we can visualize PCB in 3D by pressing just one button. Below are actual screenshots of both, PCB layout & their 3D model.
PCB layout Designed on EasyEDA:
Printed PCB :
We chose JLC PCB to manufacture our PCB because, it is the cheapest and convenient option available for any prototype PCB manufacturing. It just cost us $2 for quantity of 10 PCB and $12 for shipment. We received manufactured PCB in just 3 days. Followings are actual photos of manufactured & assembled PCBs.
Hardware Interface
Hardware design diagram above gives an overview of the entire system which consists of the two SJ-One controllers: one board is used as Control Module and other board is used as the Display Module.
- The Console Module uses the onboard accelerometer on SJ-One which is interfaced via I2C protocol. The calibrated accelerometer values are then used to determine the basket position on the LED Matrix.
- The Display Module SJ-One board is used to control a 32*32 RGB LED Matrix.This matrix displays the basket, eggs shot from the cannon.The movement of the basket is as per the orientation value received from the Control Module, through Wireless Module. It also consists of Peizo buzzer which is controlled via PWM pin.
Hardware Components Design, Description Implementation
RGB LED Matrix
A 64x64 RGB LED Matrix Panel is used as a display. It has 4096 full-color RGB LEDs. Each LED can be independently addressed and controlled. It requires at 13 digital GPIOs to control the LED matrix. The led matrix has 2 IDC connectors DATA_IN and DATA_OUT on the back, we can cascade multiple panels and make a huge screen together. The LED display is constructed using a decoder to decode address rows. A 64 bit Shift register should be clocked for enabling the color. When the row is low we need to select which all pixels in the column are to be configured with the required color. This is done by clocking the 64Bit shift register. There are 6 64Bit registers each for R1 R2 B1 B2 G1 G2. A single clock is interfaced to all these 6 64bit shift registers. So at once we shift and fill the required color for the column display. Once the clocking and shifting the register is completed we need to latch this data to the register. The register data is sent out to all the row lines and that Row line which is pulled low by the decoder will receive this data and corresponding pixels are turned on.
RGB LED matrix pins:
S.NO | RGB LED pins | Function |
---|---|---|
1 | R1 | High R data |
2 | G1 | High G data |
3 | B1 | High B data |
4 | R2 | Low R data |
5 | G2 | Low G data |
6 | B2 | Low B data |
7 | A | Row select A |
8 | B | Row select B |
9 | C | Row select C |
10 | D | Row select D |
11 | E | Row select E |
12 | CLK | Clock signal. |
13 | OE | Output enables to cascade LED panel. |
14 | LAT | Latch denotes the end of data. |
15 | VCC | 5V |
16 | GND | GND |
Row Selection
The RGB matrix has a 5:32 decoder. This decoder takes 5 bits as input and decodes the corresponding row to be kept low. There are five address inputs to the display marked A, B, C, D and E. Based on the truth table, only one input is active (low) at a time. The outputs of the decoder are connected to a P-Channel MOSFET because the decoder itself can only handle low currents and cannot drive a row of LEDs directly. The P-Channel MOSFET provides the high current needed to drive a row of LEDs. The decoder outputs are shared between every 32 outputs. Since, the 5-to-32 address decoder select rows in parallel like 1 and 33, 2 and 34, repeating that pattern until row 32 and 64.
Column Selection
The column data is stored in a 64-bit serial-in, a parallel-out shift register. The shift register is designed to work with LEDs and implements a constant-current system that ensures the LED brightness remains uniform. R1 G1 B1 is used for configuring the color for the top half of the display and R2 G2 B2 for the bottom half of the display. For 64 rows using with 32 outputs of the decoder, we must have unique data for each row pair. When Row 1 and Row 33 are selected, we must provide each row with unique data. This forces us to use two different shift registers for each row pair, an upper register, and a lower register. Because of this, the display is divided into an upper half and a lower half. The data is shifted into the top half via the R1, G1 and B1 signals on the connector. The bottom halves data is supplied by the R2, G2 and B2 signals on the connector. Then, since our display is 64 pixels wide, we use 64-bit shift registers to hold all 64 bits of pixel data for a single row. Each half of the display is controlled by 3 shift registers, one for each color. First, Row 1 and Row 33 are selected then 64 bits of data are shifted into each color’s shift register (R1, G1, B1), and then latched. At the same time, 64 bits of data are also shifted into each color’s shift register for the bottom half (R2, G2, B2), and then latched. The process repeats 31 more times, each time incrementing the rows are selected until every line has been updated.
In order to display something on the LED panels the following steps need to be performed by the driver
- Shift the pixel data for row 1 into the top column drivers and the pixel data for row 33 into the bottom column drivers using the R1, G1, B1, R2, G2, and B2 data inputs and the SCLK shift clock signal.
- Clear the blanking signal to blank the display.
- Set the address input to 1.
- Latch the contents of the column driver's shift registers to the output registers using the LATCH signal.
- Make the blanking signal high to display rows 1 and 33.
- Repeat the process for each of the pairs of rows in the display for 31 times.
Specifications:
The LED display used in our project is a 64*64 pixel panel with a pixel pitch of 3mm. More specifications are tabulated.
- Operating voltage: DC 5V
- Average power consumption: <500W/㎡
- Maxim Power Consumption: <1000w/㎡
- Pixel: 64x64=4096
- Level of viewing Angle: ≧160°
- Control mode: Synchronous control
- Drive mode: 1/16 scan rate
- Repetition frequency: ≧60Hz
- White Balance Brightness: ≧1200cd/㎡
- Refresh frequency : ≧300Hz
- MTTF: ≧5000 hours
- Service Life: 75000~100000 hours
- Pixel pitch: 3mm
- Thickness: 11mm
Code Snippet for score the update to the controller:
void set_players_score(uint8_t score_green, uint8_t score_blue) {
uint16_t transfer_score = 0; green_player_score = score_green; blue_player_score = score_blue; transfer_score = (score_blue * 100) + score_green; printf("Transfer Score = %i\n", transfer_score); controller_comm__update_player_score(CONTROLLER_COMM__ROLE_PLAYER_2, transfer_score); controller_comm__update_player_score(CONTROLLER_COMM__ROLE_PLAYER_1, transfer_score);
}
Code Snippet for updation of LED matrix:
void led_matrix__update_display() {
for (int i = 0; i < 32; i++) { led_matrix__disable_display(); led_matrix__disable_latch(); led_matrix__select_row(i); // will select i and i + 32 rows at same time
for (int j = 63; j >= 0; j--) { // shift data with MSB getting shifted-in first ((frame_buffer[i][RED_PLANE] >> j) & 1) ? gpio__set(r1) : gpio__reset(r1); ((frame_buffer[i][GREEN_PLANE] >> j) & 1) ? gpio__set(g1) : gpio__reset(g1); ((frame_buffer[i][BLUE_PLANE] >> j) & 1) ? gpio__set(b1) : gpio__reset(b1);
((frame_buffer[i + 32][RED_PLANE] >> j) & 1) ? gpio__set(r2) : gpio__reset(r2); ((frame_buffer[i + 32][GREEN_PLANE] >> j) & 1) ? gpio__set(g2) : gpio__reset(g2); ((frame_buffer[i + 32][BLUE_PLANE] >> j) & 1) ? gpio__set(b2) : gpio__reset(b2); gpio__set(clk); gpio__reset(clk); // shift in all 3 color bits at once for top half/bottom half registers led_matrix__enable_latch(); led_matrix__disable_latch(); } // at this point, all 3 shift registers should be filled with corresponding row data in frame_buffer led_matrix__enable_latch(); // push shift register contents down to output registers led_matrix__enable_display(); delay__us(250); } led_matrix__disable_display();
}
Code Snippet for score the detecting collision with the pacman:
if (blue_collided == 1) { blue_collided = clear_blue_collided(); score_blue += cummulative_score; set_players_score(score_green, score_blue); change_game_state_to = IN_SCORE_STATE; xQueueSend(*(ball_parameters.state_queue), &change_game_state_to, 0); cummulative_score = 1; SMACMAN__DEBUG_PRINTF("BLUE player score: %d GREEN player score: %d\n", score_blue, score_green); set_blue_pacman_start(); set_green_pacman_start(); ball_setup(&ball); } if (green_collided == 1) { green_collided = clear_green_collided(); score_green += cummulative_score; set_players_score(score_green, score_blue); change_game_state_to = IN_SCORE_STATE; xQueueSend(*(ball_parameters.state_queue), &change_game_state_to, 0); cummulative_score = 1; SMACMAN__DEBUG_PRINTF("BLUE player score: %d GREEN player score: %d\n", score_blue, score_green); set_blue_pacman_start(); set_green_pacman_start(); ball_setup(&ball); }
MP3 Decoder
In our project,we have calibrated the accelerometer based on the values of X,Y and Z co-ordinates corresponding to different orientations of the accelerometer to control the horizontal movement of the paddle in the game to hit the ball . This has also helped us decide and control the speed of the basket. As shown in the code snippet below the x movement on the right is determined based on the x co-ordinate and the console sensitivity which you wish to set.Similarly movement on the left can also be calculated for further use. |
Code snippet for Accelerometer Calibration:
static void controller_comm__master_request_accel(controller_comm_s controller, controller_comm__role_e player_to_request) {
controller_comm__message_s request_message = {0};
request_message.recipient = player_to_request;
request_message.sender = CONTROLLER_COMM__ROLE_MASTER;
request_message.message_type = CONTROLLER_COMM__MESSAGE_TYPE_REQUEST_ACCEL_VAL;
if (player_to_request == CONTROLLER_COMM__ROLE_PLAYER_1) {
request_message.data = controller_comm__player_1_score;
}
else if (player_to_request == CONTROLLER_COMM__ROLE_PLAYER_2) {
request_message.data = controller_comm__player_2_score;
}
controller_comm__send_message(controller, request_message);
return;
}
Wireless Module:
Testing & Technical Challenges
Issues, Challenges and solutions to get past them
1. RGB LED Matrix Display driver
a) Setting up the LED Matrix was a bit of a challenge. Started with glowing a single row and column. Getting the initial hold on the exact row and column position was a bit tricky as one can easily get confuse on the starting and ending row and column. Once we got over it we moved on to design game objects separately.
b) Flickering of led matrix was solved by doing the following:
- The frequency of refreshing the led matrix was increased to show smooth transition from one frame to another.
- Led matrix is very sensitive to the inputs provided to it. Initially the flickering was thought to be because of the data lines and row selection lines. But later with further diagnoses it was discovered that the power supply line was creating issues. Changing the adapter eliminated the flickering.
c) As the game consists of many objects that exist simultaneously on the screen clearing the trail of each object was bit of a problem.
- Initially clearing the LED matrix from time to time assigned to one task. But later each object dealt with its own clearance, which eliminated the effect of clearance of one object with the display of other objects.
d) Pacman and Ball detection of the bounadry:
- Pacman object detecting the boundary and making the decision of moving left or right was a bit tricky. Started with one boundary condition and then proceeded with the rest boundary conditions.
e) Updating the movement of each object on the LED matrix was clumsy in the beginning as individual objects where updated as soon as a movement was detected in the object.
- But when the frequency of refreshing rate was increased the update of the LED matrix was moved to one task which led to the smooth movement of the objects on the screen.
e) The varying Pacman velocity with the ball movement in the lower and the upper half of the matrix was difficult.
- Set and get functions are used to get the updated position of the ball for each movement.
2. Challenges in the designing of the controller modules for the paddle movement and to get score from the master
a) SJ2 UART frames were corrupted while sending over XBEE.
- The XBEE firmware parameters had to be carefully calibrated to match the SJ2 as well as using a 38400 bps bit rate. The SJ2 UART driver had to be slightly modified match as well.
b) UART is not meant to be a broadcast protocol.
- A custom wireless broadcast/multi-node wireless protocol and driver had to be designed to be robust with dropped frames and packets being handled gracefully. (Described above)
3. Designing the MP3 Decoder a) Earlier we used the ssp2 Driver written by Preet for SPI interfacing to write the data to MP3 Decoder. but somehow we were not able to detect the slave properly because of which we could not communicate with the decoder.
- Resolution : We wrote our own simple SPI driver which sends the data to the MP3 Decoder for playing the music in background.
b) While reading data from the SD Card sometimes we faced few issues like hardware error occured in disk i/o and physical drive cannot work.
- Resolution : The default driver was using mount later option for SD Card we changed it to mount immediately and the issue got resolved.
4. Dimensions of power pins for the PCB design
a) Accommodate the exact dimensions of the 5V Power pin on the PCB design.
- Since there is no datasheet available for the 64x64 RGB LED Matrix, hence it was a difficult task. We used a basic approximation to determine the pin dimensions that would fit inside the PCB design such that it works just fine.
4. Integration Issues
a) Controller Logic and Game Logic were developed independently.
- Careful time and consideration had to be taken to ensure that the APIs were able to be stitched together. This actually ended up going smoother than we had anticipated. The Inter-board communication driver was designed to handle almost everything regarding the controllers, providing very abstract and simple APIs. This allowed for relatively smooth integration.
b) After game and controller logic, the main SJ2 did not have enough processing power to adequately driver the music functionality.
- A standalone SJ2 board was used for the game soundtrack. This eased the load on our main board which was starting to effect our gameplay.
Conclusion
At the start, project was a jigsaw puzzle wasn't as easy to implement as we thought of. We only had bits and pieces of knowledge about few thing and we were totally unaware of how to put it together to get through. But we were finally successful in implementing our idea of building a game. This project has helped us to gain practical exposure in building a real time embedded system and implement the concepts which we learnt in class in practical. This project gave us a platform to utilize all LPC drivers and Free RTOS knowledge which we learnt in our course work and what are the key things to consider while building a real time system. We are thankful to Preet, who motivated and guided us through out the course work. This is surely going to help us for our interview preperation and in grabbing an internship.
Project Video
Project Source Code
References
Acknowledgement
Any acknowledgement that you may wish to provide can be included here.
References Used
WIRELESS CONTROLLER
MP3 DECODER
RGB LED Matrix Interfacing and Designing
- Datasheet and LED Matrix parameters
- Power and pin connections
- Reference for setting up and testing LED Matrix
General/Miscellaneous
Appendix
You can list the references you used.