Difference between revisions of "F19: Smacman"

From Embedded Systems Learning Academy
Jump to: navigation, search
(Parts List & Cost)
(Design & Implementation)
Line 264: Line 264:
  
 
== Design & Implementation ==
 
== Design & Implementation ==
'''View our current progress here (this will be added to the wiki when completed):''' [https://github.com/nickschiffer/Smacman/wiki Github Wiki]
 
  
The design section can go over your hardware and software design.  Organize this section using sub-sections that go over your design and implementation.
+
=== Hardware and PCB Design ===
  
=== Hardware Design ===
+
=== PCB Design ===
1)There are two players in the game. These are 2 xbee nodes and they are connected to one main node and thus the topology for broadcast is set.
+
PCB is an important part of the embedded system, it is certainly true for this project as it reduced wire complexity and gave independent power to our circuit. There are many softwares available for PCB design, among them Eagle and KiCAD are more popular and both software are free for  students. We chose KiCAD (v5.10.0) for PCB design over Eagle because, it is opensource so we din't have to worry about the license. The second reason was that, all of our team members was new to PCB design so the learning curve was same for both software but we found a good tutorial series for KiCAD on youtube ( [https://www.youtube.com/playlist?list=PLEBQazB0HUyR24ckSZ5u05TZHV9khgA1O KiCAD tutorials] ). KiCAD has its own issues which are discussed in the issue section of this wiki.
2)MP3 player for game sound effects
+
The steps involved in the PCB design process are described in the next section.
 +
<BR/>
 +
 
 +
==== 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.   
 +
 
 +
===== Display PCB schematic: =====
 +
[[File:PCB Schematic 1 Game Display.png|700px|thumb|center|'''Game Display PCB Schematic''']]
 +
<BR/>
 +
 
 +
Display PCB has two independent circuits. One circuit is to connect SJOne board to LED panel connector and with two piezo buzzers. While another circuit is to connect one unused power cable of LED panel to SJOne board so that we don't have to power SJOne board from PC while we are playing the game. Our preliminary idea was to make this PCB, a Arduino kind of shield but for SJOne board. 
 +
 
 +
===== Console PCB schematic: =====
 +
[[File:PCB Schematic 2 Game Console.png|700px|thumb|center|'''Game Console PCB Schematic''']]
 +
<BR/>
 +
In this game, console is used to move the basket to catch fast falling eggs and if there were any wires attached to console then it is very inconvenient for the user to play. so, we decided to make PCB which can charge battery and power the console while the user is playing. As shown in figure, the heart of the circuit is microchip's MCP73831 LiPo battery charging management IC. One LED is connected to it's Status Pin which glows when the battery is charging. A mini USB B port is used to connect to power resource (PC or any 5V mobile charger)via USB cable to charge the battery. while playing the game, the user must connect USB A port to SJOne Board's mini USB B port. To use the console on battery power user must turn on/off switch.
 +
 
 +
==== PCB Layout: ====
 +
 
 +
After schematic design, the most important step is to connect the PCB layout. In KiCAD 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.
 +
 
 +
===== Display PCB layout: =====
 +
<center>
 +
<table>
 +
<tr>
 +
<td>
 +
[[File:Dispay PCB layout without CU.png|300px|thumb|center|'''Dispay PCB layout without Copper layer''']]
 +
</td>
 +
<td>
 +
[[File:Display PCB layout.png|300px|thumb|center|'''Display PCB layout  with Copper layer''']]
 +
</td>
 +
<td>
 +
[[File:Display PCB front 3D view.png|300px|thumb|center|'''Display PCB front 3D view''']]
 +
</td>
 +
<td>
 +
</tr>
 +
</table>
 +
</center>
 +
 
 +
 
 +
 
 +
===== Console PCB layout: =====
 +
 
 +
<center>
 +
<table>
 +
<tr>
 +
<td>
 +
[[File:Console PCB layout without CU.png|250px|thumb|center|'''Console PCB layout without Copper layer''']]
 +
</td>
 +
<td>
 +
[[File:Console PCB layout.png|264px|thumb|center|'''Console PCB layout with Copper layer''']]
 +
</td>
 +
<td>
 +
[[File:Console PCB front 3D view.png|300px|thumb|center|'''Console PCB front 3D view''']]
 +
</td>
 +
<td>
 +
</tr>
 +
</table>
 +
</center>
 +
 
 +
==== PCB manufacturing and soldering: ====
 +
 
 +
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 $17 for shipment. We received manufactured PCB in just 5 days. We order components from Moser the total BOM cost of both PCB is approx $25 including shipment. Followings are actual photos of manufactured & assembled PCBs.
 +
 
 +
<center>
 +
<table>
 +
<tr>
 +
<td>
 +
[[File:Console Actual.jpg|300px|thumb|center|'''Actual Console PCB''']]
 +
</td>
 +
<td>
 +
[[File:Actual Display PCB.jpeg|260px|thumb|center|'''Actual Display PCB''']]
 +
</td>
 +
<td>
 +
</tr>
 +
</table>
 +
</center>
  
 
=== Hardware Interface ===
 
=== Hardware Interface ===
1) Xbee interfaces using UART Bus.
 
  
2)MP3 player interface using SPI Bus.
+
[[File:Hardwareinterface.PNG|570px|thumb|center|'''Hardware Design Diagram''']]
 +
 
 +
 
 +
 
 +
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.
 +
 
 +
=== Software Design and Implementation ===
 +
 
 +
==== Display Module ====
 +
 
 +
'''RGB LED Matrix:'''
 +
<center>
 +
<table>
 +
<tr>
 +
<td>
 +
[[File:RGB_LED.PNG|400px|thumb|center|'''RGB LED matrix display''']]
 +
</td>
 +
<td>
 +
[[File:RGB32_32.jpg|400px|thumb|center|'''RGB Display'''']]
 +
</td>
 +
<td>
 +
</tr>
 +
</table>
 +
</center>
 +
 
 +
The Human Machine Interface is a display which is composed of 6mm pitch 1024 RGB LEDs arranged in a 32x32 matrix. 32 rows of the matrix is divided into 16 interleaved sections. Here the first section is the 1st and 16th 'row' (32 x 2 = 64 RGB LEDs), the second section is 2nd and 17th 'row' and so on. On the PCB is 12 LED driver chips. These are like 74HC595s but they have 16 outputs and they are constant current. 16 outputs * 12 chips = 192 LEDs that can be controlled at once, and 64 * 3 (R G and B) = 192. So now the design comes together. We can have 192 outputs that can control one line at a time, with each of 192 R, G and B LEDs either on or off. The LPC1758 controller selects which section to currently draw (using A, B, C and D address pins - 4 bits can have 16 values). Once the address is set, the controller clocks out 192 bits of data (24 bytes) and latches it. Then it increments the address and clocks out another 192 bits, etc until it gets to address #15, then it sets the address back to #0. To light up an individual pixel, appropriate row value is loaded on to the address pins A,B,C & D, Clock is set out to traverse the row and when required pixel is reached, the latch is set high to turn ON the LED.
 +
The hardware interface to the LED Matrix uses GPIO for all data and control lines. A GPIO clock is toggled to shift in data sitting at the Matrix's 6 data ports.
 +
 
 +
{| class="wikitable"
 +
! SJ One Board Pin
 +
! Name
 +
! Description
 +
|-
 +
| P0.0
 +
| addrA
 +
| Address Input A
 +
|-
 +
| P0.1
 +
| addrB
 +
| Address Input B
 +
|-
 +
| P2.6
 +
| addrC
 +
| Address Input C
 +
|-
 +
| P2.7
 +
| addrD
 +
| Address Input D
 +
|-
 +
| P1.29
 +
| Latch
 +
| Shift in row data/Active High
 +
|-
 +
| P1.28
 +
| Output Enable
 +
| Turn on selected rows/Active Low
 +
|-
 +
| P1.19
 +
| Clock
 +
| Shift clock
 +
|-
 +
| P1.22
 +
| R1
 +
| Top half red data
 +
|-
 +
| P0.26
 +
| G1
 +
| Top half green data
 +
|-
 +
| P1.23
 +
| B1
 +
| Top half blue data
 +
|-
 +
| P1.30
 +
| R2
 +
| Bottom half red data
 +
|-
 +
| P1.31
 +
| G2
 +
| Bottom half green data
 +
|-
 +
| P2.5
 +
| B2
 +
| Bottom half blue data
 +
|}
 +
 
 +
'''Piezo Buzzer:'''
 +
[[File:Piezo_2019_fall.JPG|200px|thumb|right|'''Piezo Schematic Diagram''']]
 +
[[File:Piezo buzzer 2019 fall.jpg|150px|thumb|center|'''Piezo Physical Diagram''']]
 +
Piezo electric buzzer are high performance buzzer that employ piezoelectric elements and are designed for easy incorporation into various circuits. These buzzers are designed for external excitation, the same part can serve as both a musical tone oscillator and a buzzer. In our project we are using this device to create musical tones by varying the operating frequency.The different range of operating frequency
 +
are generated from PWM peripheral. Different range of frequencies are maintained as constants ,these constants are fed to PWM,which generates square wave. The output of the PWM is driving the Piezo buzzer.
 +
 
 +
''' Code snippet for creating musical tones by varying frequency: '''
 +
<syntaxhighlight lang="c">
 +
int fire[]=
 +
{
 +
550,/*twice the freq of this and use always tempo as 40 */
 +
404,
 +
315,
 +
494,
 +
182,
 +
260,
 +
455,
 +
387,
 +
340
 +
};
 +
 
 +
void fire_sound_level(void){
 +
for(int i = 0;i < 8;i++)
 +
{
 +
uint8_t tempo = 40;
 +
while(tempo)
 +
{
 +
pwm.SetFrequency(fire[i]*2);
 +
pwm.SetDutyCycle(pwm.k2_1,50);
 +
pwm.PwmEnableMode(true);
 +
tempo--;
 +
}
 +
}
 +
pwm.PwmEnableMode(false);
 +
}
 +
</syntaxhighlight>
 +
 
 +
==== Control Module ====
 +
 
 +
'''Accelerometer:'''
 +
 
 +
[[File:CmpE244_S18_Detectable_Accelerations.png|400px|thumb|center|Accelerometer Detection]]
 +
 
 +
{|The SJ one board has an Accelerometer which is interfaced to the board using the I2C bus protocol.
 +
The MMA8452Q which is a smart low-power, three-axis, capacitive micromachined accelerometer with 12 bits of resolution is used in our project.
 +
Accelerometers are electromechanical devices that are used to sense acceleration that can be of various forms, for instance gravity.
 +
|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 Basket int the game to catch the eggs on the screen. 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: '''
 +
 
 +
<syntaxhighlight lang="c">
 +
 
 +
if (((x_coordiante > px_coordiante + CONSOLE_SENSITIVITY) && (x_coordiante <= CONSOLE_TILT_RANGE) ))
 +
{
 +
        boardOrientation=left;
 +
        bskObj.speed=BASKET_SPEED;
 +
        px_coordiante=x_coordiante;
 +
}
 +
    //left
 +
    else if((x_coordiante<px_coordiante-CONSOLE_SENSITIVITY && x_coordiante>=-CONSOLE_TILT_RANGE))
 +
{
 +
        boardOrientation=right;
 +
        bskObj.speed=BASKET_SPEED;
 +
        px_coordiante=x_coordiante;
 +
}
 +
else if(x_coordiante>CONSOLE_TILT_RANGE ){
 +
        boardOrientation=left;
 +
        bskObj.speed=BASKET_SPEED;
 +
}
 +
else if(x_coordiante<-CONSOLE_TILT_RANGE ){
 +
        boardOrientation=right;
 +
        bskObj.speed=BASKET_SPEED;
 +
    }
 +
else
 +
{
 +
        boardOrientation=invalid;
 +
        py_coordiante=y_coordiante;
 +
}
 +
 
 +
</syntaxhighlight>
 +
''' Wireless Module: '''
 +
[[File:nordic.PNG|350px|thumb|center|'''Nordic Wireless Block Diagram''']]
 +
 
 +
{|The on-chip Nordic nRF24L01+ is interfaced to the SJone board using Serial Peripheral Interface(SPI) bus protocol.
 +
The nRF24L01+ is a single chip 2.4GHz transceiver with an embedded baseband protocol engine, suitable for ultra low power wireless applications. The nRF24L01+ is designed for operation in the world wide ISM frequency band at 2.400 - 2.4835GHz.The nRF24L01+ supports an air data rate of 250  kbps, 1 Mbps and 2Mbps. The high air data rate combined with two
 +
power saving modes make the nRF24L01+ very suitable for ultra low power designs.
 +
The register map, which is accessible through the SPI, contains all configuration registers in
 +
the nRF24L01+ and is accessible in all operation modes of the chip.
 +
The embedded baseband protocol is based on packet communication and supports various modes from manual operation to advanced autonomous protocol operation. Internal
 +
FIFOs ensure a smooth data flow between the radio front end and the system’s MCU. Enhanced ShockBurst reduces system cost by handling all the high speed link layer operations.
 +
Whenever a data is to be transferred over the Nordic Wireless transceiver,a packet containing the required data is made and then transmitted using ''wireless_send()'' function to the address of the receiver node. On the other hand, the receiver node waits for the package to be received and once it receives the packet, the  data in the the form of X,Y and Z co-ordinates is extracted from the packet and then used to vary the basket position on the display module side. The code snippet below show basic implementation of the Wireless Transmitter and the Wireless Receiver tasks using the Nordic wireless transceiver.
 +
 
 +
|''' Code snippet for Wireless Transmitter: '''
 +
 
 +
<syntaxhighlight lang="c">
 +
 
 +
struct pckt
 +
{
 +
    int16_t x;
 +
    int16_t y;
 +
    int16_t z;
 +
    int16_t buttonPressed=0;
 +
};
 +
void WirelessTx(void *p)
 +
{
 +
      while(1)
 +
      {
 +
          pckt var;
 +
          var.x = AS.getX();/values from accelerometer*/
 +
          var.y = AS.getY();
 +
          var.z = AS.getZ();
 +
          pckt var;
 +
            while(1)
 +
            {
 +
                if(SW.getSwitch(1))
 +
                {
 +
                    var.buttonPressed=1;
 +
                    vTaskDelay(300);
 +
                }
 +
                else if(SW.getSwitch(2))
 +
                {
 +
                    var.buttonPressed=2;
 +
                    vTaskDelay(300);
 +
                }
 +
          wireless_send(REM, mesh_pkt_nack,(pckt*)&var, 8, 0);
 +
          vTaskDelay(50);
 +
            }
 +
      }
 +
}
 +
</syntaxhighlight>
 +
 
 +
''' Code snippet for Wireless Receiver: '''
 +
 
 +
<syntaxhighlight lang="c">
 +
 
 +
void wirelessRx(void* p)
 +
{
 +
    while(1)
 +
    {
 +
        mesh_packet_t rcvPkt;
 +
        int timeout_ms = 50;
 +
 
 +
        if(wireless_get_rx_pkt(&rcvPkt, timeout_ms)){
 +
 
 +
            iphObj.x_coordiante = (int16_t)(*((uint16_t*)(rcvPkt.data+0)));
 +
            iphObj.y_coordiante = (int16_t)(*((uint16_t*)(rcvPkt.data+2)));
 +
            iphObj.z_coordiante = (int16_t)(*((uint16_t*)(rcvPkt.data+4)));
 +
            iphObj.buttonPressed= (int16_t)(*((uint16_t*)(rcvPkt.data+6)));
 +
            if(iphObj.buttonPressed==1 )
 +
            {
 +
                xSemaphoreGive(playPauseHandler);
 +
            }
 +
            else if(iphObj.buttonPressed==2 )
 +
            {
 +
              xSemaphoreGive(resetGameHandler);
 +
            }
 +
        }
 +
        vTaskDelay(50);
 +
    }
 +
}
 +
</syntaxhighlight>
 +
 
 +
 
 +
==== Tasks and Flow Control ====
 +
 
 +
<center>
 +
<table>
 +
<tr>
 +
<td>
 +
[[File:Tasks list 2019 fall.JPG|185px|thumb|center|'''List of Free RTOS Tasks''']]
 +
</td>
 +
<td>
 +
[[File:Input handler 2019 fall.JPG|300px|thumb|center|'''Input Handler Class''']]
 +
</td>
 +
<td>
 +
</tr>
 +
</table>
 +
</center>
 +
 
 +
 
 +
<center>
 +
<table>
 +
<tr>
 +
<td>
 +
[[File:Display_handler_2019_spring.JPG|300px|thumb|center|'''Display Handler Class''']]
 +
</td>
 +
<td>
 +
[[File:Logic handler 2019 fall.JPG|315px|thumb|center|'''Game Logic Handler Class''']]
 +
</td>
 +
<td>
 +
</tr>
 +
</table>
 +
</center>
 +
 
 +
 
 +
''' Software Design in Display module:'''
 +
 
 +
''''Input_handler:''''  This is class, which contains all the functions which controls the position of the basket. Which is in turn depends on the console unit orientation value received from wireless task. This task also receives status of button press from the console unit. The values are received as a structure. Wireless task checks for button press and accordingly changes the state of game.i.e for button 1 press it pauses the game and for button 2 press it restarts the game. The accelerometer values are used to calibrate the basket horizontal movement.Depending upon the x-axis values of console the basket slides horizontally.
 +
 
 +
'''Display_handler:''' We have implemented the various functions to display the components used in our Game. It uses GFX matrix library to draw the shapes and pixel. Objects used in our game includes Baskets,Eggs,Cannon and Water. Apart form Object display Handler also has functions to implement the screens used in our Game like-Play/Pause screen,Game Over Screen,Win Screen.
 +
 
 +
'''Game_Begin:''' This is a task which divided into Logic Handler, Input Handler and Display Handler. Input Handler read the input,Logic Handler implements various algorithms to generate eggs with random behavior,checks for game Over condition,sliding the basket depending upon the direction received from Input handler,speed of sliding ,Logic to determine the catch or miss of Egg and increment the water level on every miss.Display Handler deals with displaying objects on screen. Each handler class have its manager functions which calls all the private functions of respective handler. From the game Task we call these manager functions of all the handlers.Basic Game theory is to check the input,update the logic and display. we are implementing same thing using handlers for display,logic and input.
 +
 
 +
[[File:Display Screen 2019 fall.JPG|500px|thumb|center|'''Display module screen state flow''']]
  
=== Software Design ===
+
'''Tasks in Console Module :'''
Show your software design.  For example, if you are designing an MP3 Player, show the tasks that you are using, and what they are doing at a high level.  Do not show the details of the code.  For example, do not show exact code, but you may show psuedocode and fragments of code.  Keep in mind that you are showing DESIGN of your software, not the inner workings of it.
 
  
=== Implementation ===
+
'''Transmitter Task:''' This task periodically transmits the orientation values and button press status to  the display module.
This section includes implementation, but again, not the details, just the high level. For example, you can list the steps it takes to communicate over a sensor, or the steps needed to write a page of memory onto SPI Flash.  You can include sub-sections for each of your component implementation.
+
Task Priority :1 (could be anything as it the only task running in the console).
  
 
== Testing & Technical Challenges ==
 
== Testing & Technical Challenges ==

Revision as of 04:42, 16 December 2019

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

Smacman

Abstract

Our team 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 ,also 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 the objective are as below:

  • Visually display the movement of the monster 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 two modules:

1. Input Module: The input module connects SJ-two board() to XBee Modules(distant nodes for players) and MP3 Decoders which is used to control the Paddle movement which will eventually control the game. The XBee Module transmits control packets to the output module.

2. Output Module: The output module connects another SJ-two board to LED Matrix for visual display. It recursively polls to receive control packets from the input module and updates the paddle movement as per user's input.

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.
  • 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.
  • 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 along the edges. 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 along the edges. 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 he 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

Delivery Schedule

Project Repository Link: Github Project

Week# Date Task Status Actual Completion Date
1 10/1/2019
  • Submission of Project Proposal.
  • Complete
  • 10/1/2019
2 10/15/2019
  • Create GitLab Repository.
  • Go through the projects and research about components.
  • Distributing the roles among team members.
  • Research Required Components.
  • Submit Schedule and Components List.
  • Complete
  • 10/14/2019
3 10/22/2019
  • Familiarize with 64x64 LED Matrix Datasheet.
  • Familiarize with xbee & accelerometer datasheet.
  • Familiarize with Mp3 Decoder VS-1053 datasheet.
  • Complete
  • 11/8/2019
4 10/29/2019
  • Make Gitlab Repository for individual tasks for all modules
  • Introduce Naming Convention
  • Develop Graphics Drivers and Implementation of displaying basic monster on LED Matrix
  • Calibrating Accelerometer values for 2 Players
  • Complete
  • 11/8/2019
5 11/5/2019
  • Develop code to send Accelerometer values to move the paddle for both the players
  • Basic LED Display testing for boundary conditions.
  • Develop game specific APIs to draw objects like monster, paddle, ball of led driver
  • Project report update on the wiki.
  • Complete
  • 11/12/2019
6 11/12/2019
  • Develop Algorithm Design for Game Logic for all 3 levels of game
  • Transmission of Accelerometer values for 2 players from their respective controllers to the master
  • Code for the splash screen(Intro screen)
  • Complete
  • 11/19/2019
7 11/19/2019
  • Code for MP3 Decoder for the background music
  • 7 segment display for players score from controller
  • Code to display the score on matrix
  • Code Integration for the moving of paddle on basis of accelerometer values from controllers for both the players
  • Complete
  • 11/26/2019
8 11/26/2019
  • Develop Play/Pause/Stop functionality
  • Debug and Test the Play/Pause/Stop functionality
  • Complete
  • 11/30/2019
9 12/3/2019
  • Design PCB for Controller & master and generate Gerber files, finalize PCB manufacture
  • Integrating calibrated accelerometer, push-button functionalities and wireless transfer from controller boards
  • Complete
  • 12/10/2019
10 12/10/2019
  • Integration of subsystems
  • 3-D Printing of enclosures for matrix and the player's controller
  • Fixing the bugs during testing
  • Complete
  • 12/15/2019
11 12/17/2019
  • Final bug fixes and troubleshooting.
  • Complete wiki report and final demo.
  • In-Progress
  • 12/17/2019

Parts List & Cost

Item# Part Desciption Vendor Qty Cost
1 SJTwo Boards From Preet 4 $200.00
2 64x64 RGB LED Matrix Adafruit 1 $92.00
3 Wiring Components and Cable Amazon 1 $20.00
4 3D printer filament spool(s) For 3D printed enclosures [1] 2 $40.00
5 XBEE Modules From Preet and Adafruit 3 $27.00
6 Batteries Local 2 $4.00
7 I2C 7-seg screens Amazon 2 $18.00
8 XBee Programmer Boards Amazon 3 $35.00

Design & Implementation

Hardware and PCB Design

PCB Design

PCB is an important part of the embedded system, it is certainly true for this project as it reduced wire complexity and gave independent power to our circuit. There are many softwares available for PCB design, among them Eagle and KiCAD are more popular and both software are free for students. We chose KiCAD (v5.10.0) for PCB design over Eagle because, it is opensource so we din't have to worry about the license. The second reason was that, all of our team members was new to PCB design so the learning curve was same for both software but we found a good tutorial series for KiCAD on youtube ( KiCAD tutorials ). KiCAD has its own issues which 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.

Display PCB schematic:
Game Display PCB Schematic


Display PCB has two independent circuits. One circuit is to connect SJOne board to LED panel connector and with two piezo buzzers. While another circuit is to connect one unused power cable of LED panel to SJOne board so that we don't have to power SJOne board from PC while we are playing the game. Our preliminary idea was to make this PCB, a Arduino kind of shield but for SJOne board.

Console PCB schematic:
Game Console PCB Schematic


In this game, console is used to move the basket to catch fast falling eggs and if there were any wires attached to console then it is very inconvenient for the user to play. so, we decided to make PCB which can charge battery and power the console while the user is playing. As shown in figure, the heart of the circuit is microchip's MCP73831 LiPo battery charging management IC. One LED is connected to it's Status Pin which glows when the battery is charging. A mini USB B port is used to connect to power resource (PC or any 5V mobile charger)via USB cable to charge the battery. while playing the game, the user must connect USB A port to SJOne Board's mini USB B port. To use the console on battery power user must turn on/off switch.

PCB Layout:

After schematic design, the most important step is to connect the PCB layout. In KiCAD 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.

Display PCB layout:
Dispay PCB layout without Copper layer
Display PCB layout with Copper layer
Display PCB front 3D view


Console PCB layout:
Console PCB layout without Copper layer
Console PCB layout with Copper layer
Console PCB front 3D view

PCB manufacturing and soldering:

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 $17 for shipment. We received manufactured PCB in just 5 days. We order components from Moser the total BOM cost of both PCB is approx $25 including shipment. Followings are actual photos of manufactured & assembled PCBs.

Actual Console PCB
Actual Display PCB

Hardware Interface

Hardware Design Diagram


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.

Software Design and Implementation

Display Module

RGB LED Matrix:

RGB LED matrix display
RGB Display'

The Human Machine Interface is a display which is composed of 6mm pitch 1024 RGB LEDs arranged in a 32x32 matrix. 32 rows of the matrix is divided into 16 interleaved sections. Here the first section is the 1st and 16th 'row' (32 x 2 = 64 RGB LEDs), the second section is 2nd and 17th 'row' and so on. On the PCB is 12 LED driver chips. These are like 74HC595s but they have 16 outputs and they are constant current. 16 outputs * 12 chips = 192 LEDs that can be controlled at once, and 64 * 3 (R G and B) = 192. So now the design comes together. We can have 192 outputs that can control one line at a time, with each of 192 R, G and B LEDs either on or off. The LPC1758 controller selects which section to currently draw (using A, B, C and D address pins - 4 bits can have 16 values). Once the address is set, the controller clocks out 192 bits of data (24 bytes) and latches it. Then it increments the address and clocks out another 192 bits, etc until it gets to address #15, then it sets the address back to #0. To light up an individual pixel, appropriate row value is loaded on to the address pins A,B,C & D, Clock is set out to traverse the row and when required pixel is reached, the latch is set high to turn ON the LED. The hardware interface to the LED Matrix uses GPIO for all data and control lines. A GPIO clock is toggled to shift in data sitting at the Matrix's 6 data ports.

SJ One Board Pin Name Description
P0.0 addrA Address Input A
P0.1 addrB Address Input B
P2.6 addrC Address Input C
P2.7 addrD Address Input D
P1.29 Latch Shift in row data/Active High
P1.28 Output Enable Turn on selected rows/Active Low
P1.19 Clock Shift clock
P1.22 R1 Top half red data
P0.26 G1 Top half green data
P1.23 B1 Top half blue data
P1.30 R2 Bottom half red data
P1.31 G2 Bottom half green data
P2.5 B2 Bottom half blue data

Piezo Buzzer:

Piezo Schematic Diagram
Piezo Physical Diagram

Piezo electric buzzer are high performance buzzer that employ piezoelectric elements and are designed for easy incorporation into various circuits. These buzzers are designed for external excitation, the same part can serve as both a musical tone oscillator and a buzzer. In our project we are using this device to create musical tones by varying the operating frequency.The different range of operating frequency are generated from PWM peripheral. Different range of frequencies are maintained as constants ,these constants are fed to PWM,which generates square wave. The output of the PWM is driving the Piezo buzzer.

Code snippet for creating musical tones by varying frequency:

int fire[]=
{
		550,/*twice the freq of this and use always tempo as 40 */
		404,
		315,
		494,
		182,
		260,
		455,
		387,
		340
};

void fire_sound_level(void){
	 for(int i = 0;i < 8;i++)
		 {
		 	 uint8_t tempo = 40;
		 	 	 while(tempo)
		 	 	 {
					pwm.SetFrequency(fire[i]*2);
					pwm.SetDutyCycle(pwm.k2_1,50);
					pwm.PwmEnableMode(true);
					tempo--;
		 	 	 }
		 }
		 pwm.PwmEnableMode(false);
	}

Control Module

Accelerometer:

Accelerometer Detection
The MMA8452Q which is a smart low-power, three-axis, capacitive micromachined accelerometer with 12 bits of resolution is used in our project. Accelerometers are electromechanical devices that are used to sense acceleration that can be of various forms, for instance gravity.
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 Basket int the game to catch the eggs on the screen. 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:

if (((x_coordiante > px_coordiante + CONSOLE_SENSITIVITY) && (x_coordiante <= CONSOLE_TILT_RANGE) ))
{
        boardOrientation=left;
        bskObj.speed=BASKET_SPEED;
        px_coordiante=x_coordiante;
}
    //left
    else if((x_coordiante<px_coordiante-CONSOLE_SENSITIVITY && x_coordiante>=-CONSOLE_TILT_RANGE))
{
        boardOrientation=right;
        bskObj.speed=BASKET_SPEED;
        px_coordiante=x_coordiante;
}
else if(x_coordiante>CONSOLE_TILT_RANGE ){
        boardOrientation=left;
        bskObj.speed=BASKET_SPEED;
}
else if(x_coordiante<-CONSOLE_TILT_RANGE ){
        boardOrientation=right;
        bskObj.speed=BASKET_SPEED;
    }
else
{
        boardOrientation=invalid;
        py_coordiante=y_coordiante;
}

Wireless Module:

Nordic Wireless Block Diagram
The nRF24L01+ is a single chip 2.4GHz transceiver with an embedded baseband protocol engine, suitable for ultra low power wireless applications. The nRF24L01+ is designed for operation in the world wide ISM frequency band at 2.400 - 2.4835GHz.The nRF24L01+ supports an air data rate of 250 kbps, 1 Mbps and 2Mbps. The high air data rate combined with two power saving modes make the nRF24L01+ very suitable for ultra low power designs. The register map, which is accessible through the SPI, contains all configuration registers in the nRF24L01+ and is accessible in all operation modes of the chip. The embedded baseband protocol is based on packet communication and supports various modes from manual operation to advanced autonomous protocol operation. Internal FIFOs ensure a smooth data flow between the radio front end and the system’s MCU. Enhanced ShockBurst reduces system cost by handling all the high speed link layer operations. Whenever a data is to be transferred over the Nordic Wireless transceiver,a packet containing the required data is made and then transmitted using wireless_send() function to the address of the receiver node. On the other hand, the receiver node waits for the package to be received and once it receives the packet, the data in the the form of X,Y and Z co-ordinates is extracted from the packet and then used to vary the basket position on the display module side. The code snippet below show basic implementation of the Wireless Transmitter and the Wireless Receiver tasks using the Nordic wireless transceiver.
Code snippet for Wireless Transmitter:
 

struct pckt
{
    int16_t x;
    int16_t y;
    int16_t z;
    int16_t buttonPressed=0;
};
void WirelessTx(void *p)
{
       while(1)
       {
           pckt var;
           var.x = AS.getX();/values from accelerometer*/
           var.y = AS.getY();
           var.z = AS.getZ();
           pckt var;
             while(1)
             {
                 if(SW.getSwitch(1))
                 {
                     var.buttonPressed=1;
                     vTaskDelay(300);
                 }
                 else if(SW.getSwitch(2))
                 {
                     var.buttonPressed=2;
                     vTaskDelay(300);
                 }
           wireless_send(REM, mesh_pkt_nack,(pckt*)&var, 8, 0);
           vTaskDelay(50);
             }
       }
}

Code snippet for Wireless Receiver:

void wirelessRx(void* p)
{
    while(1)
    {
        mesh_packet_t rcvPkt;
        int timeout_ms = 50;

        if(wireless_get_rx_pkt(&rcvPkt, timeout_ms)){

            iphObj.x_coordiante = (int16_t)(*((uint16_t*)(rcvPkt.data+0)));
            iphObj.y_coordiante = (int16_t)(*((uint16_t*)(rcvPkt.data+2)));
            iphObj.z_coordiante = (int16_t)(*((uint16_t*)(rcvPkt.data+4)));
            iphObj.buttonPressed= (int16_t)(*((uint16_t*)(rcvPkt.data+6)));
            if(iphObj.buttonPressed==1 )
            {
                xSemaphoreGive(playPauseHandler);
            }
            else if(iphObj.buttonPressed==2 )
            {
               xSemaphoreGive(resetGameHandler);
            }
        }
        vTaskDelay(50);
    }
}


Tasks and Flow Control

List of Free RTOS Tasks
Input Handler Class


Display Handler Class
Game Logic Handler Class


Software Design in Display module:

'Input_handler:' This is class, which contains all the functions which controls the position of the basket. Which is in turn depends on the console unit orientation value received from wireless task. This task also receives status of button press from the console unit. The values are received as a structure. Wireless task checks for button press and accordingly changes the state of game.i.e for button 1 press it pauses the game and for button 2 press it restarts the game. The accelerometer values are used to calibrate the basket horizontal movement.Depending upon the x-axis values of console the basket slides horizontally.

Display_handler: We have implemented the various functions to display the components used in our Game. It uses GFX matrix library to draw the shapes and pixel. Objects used in our game includes Baskets,Eggs,Cannon and Water. Apart form Object display Handler also has functions to implement the screens used in our Game like-Play/Pause screen,Game Over Screen,Win Screen.

Game_Begin: This is a task which divided into Logic Handler, Input Handler and Display Handler. Input Handler read the input,Logic Handler implements various algorithms to generate eggs with random behavior,checks for game Over condition,sliding the basket depending upon the direction received from Input handler,speed of sliding ,Logic to determine the catch or miss of Egg and increment the water level on every miss.Display Handler deals with displaying objects on screen. Each handler class have its manager functions which calls all the private functions of respective handler. From the game Task we call these manager functions of all the handlers.Basic Game theory is to check the input,update the logic and display. we are implementing same thing using handlers for display,logic and input.

Display module screen state flow

Tasks in Console Module :

Transmitter Task: This task periodically transmits the orientation values and button press status to the display module. Task Priority :1 (could be anything as it the only task running in the console).

Testing & Technical Challenges

Describe the challenges of your project. What advise would you give yourself or someone else if your project can be started from scratch again? Make a smooth transition to testing section and described what it took to test your project.

Include sub-sections that list out a problem and solution, such as:

<Bug/issue name>

Discuss the issue and resolution.

Conclusion

Conclude your project here. You can recap your testing and problems. You should address the "so what" part here to indicate what you ultimately learnt from this project. How has this project increased your knowledge?

Project Video

Upload a video of your project and post the link here.

Project Source Code

References

Acknowledgement

Any acknowledgement that you may wish to provide can be included here.

References Used

List any references used in project.

Appendix

You can list the references you used.