Difference between revisions of "F20: Maddening Marbles"

From Embedded Systems Learning Academy
Jump to: navigation, search
(Hardware Interface)
(Conclusion)
 
(24 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
== Maddening Marbles ==
 
== Maddening Marbles ==
 
+
[[File:CMPE244 MM main screen.jpg]]
== Abstract ==
 
The player must maneuver a “marble” through a maze within a time limit. There will be multiple
 
stages. Tilting the game board will move the marble through the maze. Colliding with walls will
 
stop the marble, and touching certain objects will make the marble respawn at the beginning of
 
the stage. There will be items the player can pick up to increase the time limit. Play ends when
 
the timer runs out.
 
  
 
== Objectives & Introduction ==
 
== Objectives & Introduction ==
Show list of your objectives. This section includes the high level details of your projectYou can write about the various sensors or peripherals you used to get your project completed.
+
=== Objectives ===
 +
* Create smooth and natural feeling motion controls using the SJTwo's onboard accelerometer.
 +
* Implement a collision detection system that can detect stage goals and will allow the marble to roll along walls.  
  
 
=== Team Members & Responsibilities ===
 
=== Team Members & Responsibilities ===
Line 106: Line 102:
 
|  
 
|  
 
* 12/08/2020
 
* 12/08/2020
* 12/08/2020
+
* 12/14/2020
 
* 12/12/2020
 
* 12/12/2020
 
|
 
|
Line 114: Line 110:
 
|
 
|
 
* <span style="color:green">Completed</span>
 
* <span style="color:green">Completed</span>
* <span style="color:orange">In progress</span>
+
* <span style="color:green">Completed</span>
 
* <span style="color:green">Completed</span>
 
* <span style="color:green">Completed</span>
 
|-
 
|-
Line 129: Line 125:
 
* Push final code to GitLab repo
 
* Push final code to GitLab repo
 
|
 
|
* <span style="color:red">Not started</span>
+
* <span style="color:green">Completed</span>
* <span style="color:red">Not started</span>
+
* <span style="color:orange">In progress</span>
* <span style="color:red">Not started</span>
+
* <span style="color:orange">In Progress</span>
* <span style="color:red">Not started</span>
+
* <span style="color:green">Completed</span>
 
|-
 
|-
 
|}
 
|}
Line 159: Line 155:
  
 
=== Hardware Interface ===
 
=== Hardware Interface ===
The LED Matrix requires 13 pins to function, which are connected to 13 pins on the SJ2 board configured as GPIO output pins. All pins are active high, except for the OE pin.  These pins are initialized in the led_matrix__init() function.
+
The LED Matrix requires 13 pins to function, which are connected to 13 pins on the SJ2 board configured as GPIO output pins. All pins are active high, except for the OE pin.  These pins are initialized in the led_matrix__init() function.
  
 
The display is enabled by the active low OE pin. When the display needs to be updated, it needs to be disabled and the data unlatched by resetting the LAT pin. Then, two rows of LEDs are selected by setting pins A, B, C, and D, which act as a 4-to-16 decoder. The R1, G1, and B1 pins control the LED in the upper selected row, and the R2, G2, and B2 control the LED the lower row (16 rows down). Then, the CLK and LAT pins are toggled on/off in order to load the data into the LED matrix and select the next column of LEDs. After all LEDs for a row are updated, LAT is set, OE is reset, and a delay is added to prepare for the next row. When all rows are finished being updated, the OE pin is set again to display the LEDs.
 
The display is enabled by the active low OE pin. When the display needs to be updated, it needs to be disabled and the data unlatched by resetting the LAT pin. Then, two rows of LEDs are selected by setting pins A, B, C, and D, which act as a 4-to-16 decoder. The R1, G1, and B1 pins control the LED in the upper selected row, and the R2, G2, and B2 control the LED the lower row (16 rows down). Then, the CLK and LAT pins are toggled on/off in order to load the data into the LED matrix and select the next column of LEDs. After all LEDs for a row are updated, LAT is set, OE is reset, and a delay is added to prepare for the next row. When all rows are finished being updated, the OE pin is set again to display the LEDs.
 +
 +
{| class="wikitable"
 +
|+
 +
|-
 +
! LED Matrix Pins !! SJTwo Pins !! Function
 +
|-
 +
| R1 || P0.18 || Controls red color for rows 0-15 of the LED matrix
 +
|-
 +
| R2 || P0.17 || Controls red color for rows 16-31 of the LED matrix
 +
|-
 +
| G1 || P0.22 || Controls green color for rows 0-15 of the LED matrix
 +
|-
 +
| G2 || P2.9 || Controls green color for rows 16-31 of the LED matrix
 +
|-
 +
| B1 || P0.15 || Controls blue color for rows 0-15 of the LED matrix
 +
|-
 +
| B2 || P0.16 || Controls blue color for rows 16-31 of the LED matrix
 +
|-
 +
| A || P2.7 || One of four decoder inputs used to select the rows of the matrix
 +
|-
 +
| B || P2.8 || One of four decoder inputs used to select the rows of the matrix
 +
|-
 +
| C || P2.5 || One of four decoder inputs used to select the rows of the matrix
 +
|-
 +
| D || P2.6 || One of four decoder inputs used to select the rows of the matrix
 +
|-
 +
| CLK || P2.2 || Clock input used to shift bits into the display registers
 +
|-
 +
| LAT || P2.4 || Latch input used to save the state of the pins
 +
|-
 +
| OE || P2.0 || Output Enable, used to enable the display to power LEDs according to the current configuration of the display registers
 +
|-
 +
| GND(x3) || GND || Three ground pins of the display connect to a common ground on the SJTwo
 +
|}
 +
 +
The enclosure is a wooden box designed by the team. 
 +
 +
[[File:CMPE244 MM inside enclosure.jpg]]
  
 
=== Software Design ===
 
=== Software Design ===
Line 168: Line 202:
 
The game logic is contained in the marble.c file. The marble__init() function initializes the accelerometer, "zeroes" the marble so that the position you hold the LED board at is considered "flat," and sets the next stage to load to the title screen. The marble__handle_movement() method reads the accelerator reading, scales it to prevent choppy movement, calculates what the change in movement should be, and calls the marble__update_marble_position() function. This function checks the 12 spaces around for any obstacles that will limit its movement. If the ball will roll to the maze's goal, the next maze is loaded by a call to marble__draw_next_stage() and the marble repositioned to the starting position for that maze, which is determined by a call to marble__get_starting_coordinates(). The game timer is in the led_matrix.c file. The timer is displayed on the bottom of the board as a line of LEDs that slowly turn off. The LEDs start green, but when half of the time is remaining they turn yellow, and when a quarter of the time remains they turn red. When the timer runs out, the game over screen is displayed and the game resets back to the title screen.
 
The game logic is contained in the marble.c file. The marble__init() function initializes the accelerometer, "zeroes" the marble so that the position you hold the LED board at is considered "flat," and sets the next stage to load to the title screen. The marble__handle_movement() method reads the accelerator reading, scales it to prevent choppy movement, calculates what the change in movement should be, and calls the marble__update_marble_position() function. This function checks the 12 spaces around for any obstacles that will limit its movement. If the ball will roll to the maze's goal, the next maze is loaded by a call to marble__draw_next_stage() and the marble repositioned to the starting position for that maze, which is determined by a call to marble__get_starting_coordinates(). The game timer is in the led_matrix.c file. The timer is displayed on the bottom of the board as a line of LEDs that slowly turn off. The LEDs start green, but when half of the time is remaining they turn yellow, and when a quarter of the time remains they turn red. When the timer runs out, the game over screen is displayed and the game resets back to the title screen.
  
=== Implementation ===
+
FreeRTOS is used as the real-time operating system (RTOS) to manage the timing and call the various interfaces mentioned aboveTwo tasks are used.  The highest priority task is the screen refresh task runs every 10 milliseconds to update the display based on the current state of the LED matrix bufferThe next task is called every 100 milliseconds and updates the position of the marble in the maze based on accelerometer readings and processes any interactions with the maze environment caused by the change in position.
This section includes implementation, but again, not the details, just the high levelFor 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 FlashYou can include sub-sections for each of your component implementation.
 
  
== Testing & Technical Challenges ==
+
[[File:CMPE244_MM_software_flow.jpg]]
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:
+
[[File:CMPE_244_MM_Collision.png]]
  
=== <Bug/issue name> ===
+
== Technical Challenges ==
Discuss the issue and resolution.
+
 
 +
=== LED Matrix Driver ===
 +
The LED matrix used in this project suffered from a lack of documentation. Adafruit has a tutorial on their website that uses a Python library they developed for use with Arduino boards. With no datasheet to reference, this project had to reference previous years' projects that used the same hardware. Specifically, it wasn't initially clear how the row select worked with the A, B, C, and D bits, as well as when the LAT pin should be driven high/low to latch/unlatch the data to update the display. After some trial and error, we figured out how to properly use the LAT pin.
 +
 
 +
=== Motion Controls ===
 +
Creating smooth feeling motion controls required some finessing. Because we planned to mount the SJTWO-C board to the back of the LED matrix but were testing the game by holding the board directly, we couldn't be sure that the controls we developed would feel smooth in the final build.
 +
 
 +
=== Collision Detection ===  
 +
Issues arose with collision detection in mazes with tricky geometry. The marble would not move in certain directions despite having clearance. Some extra logic had to be added to the cases where a marble moved towards an LED lit in one of the four adjacent corners to eliminate the movement in a direction where there was not room enough for the marble to roll to or the direction in which the magnitude of movement was the smallest.
  
 
== Conclusion ==
 
== Conclusion ==
Conclude your project hereYou can recap your testing and problemsYou should address the "so what" part here to indicate what you ultimately learnt from this projectHow has this project increased your knowledge?
+
This project allowed us to take the concepts learned during the embedded systems course and put them into a practical application.  We had to be creative about how we designed our game logic and mindful of how we were implementing the hardware interfaceIt was definitely a learning experience to see all of the work and consideration that goes into creating every aspect of a product.
 +
 
 +
Our game does have a limited set of features but can be expanded upon in the future.  At some point, we would like to integrate score elements, a leaderboard, and audio.  We were concerned that if we tried to implement too expansive of a feature set that we may have a lot of half baked features and an unplayable gameWe prioritized accomplishing the parts necessary to have a complete game from start to finish and reached our goalUltimately, this project was a challenging learning experience and a lot of fun.
 +
 
 +
 
 +
[[File:IMG 20201217 182114.jpg]]
  
 
=== Project Video ===
 
=== Project Video ===
Upload a video of your project and post the link here.
+
*  [https://youtu.be/TVMcgRM9wH8 Maddening Marbles Video Link]
  
 
=== Project Source Code ===
 
=== Project Source Code ===
Line 190: Line 234:
  
 
== References ==
 
== References ==
=== Acknowledgement ===
+
* [https://github.com/adafruit/RGB-matrix-Panel Adafruit LED Matrix Library]
Any acknowledgement that you may wish to provide can be included here.
+
* [https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/ Adafruit LED Matrix Tutorial]
 
+
* [https://www.riyas.org/2013/12/online-led-matrix-font-generator-with.html LED Matrix Graphics Tool]
=== References Used ===
 
List any references used in project.
 
 
 
=== Appendix ===
 
You can list the references you used.
 

Latest revision as of 07:41, 18 December 2020

Maddening Marbles

CMPE244 MM main screen.jpg

Objectives & Introduction

Objectives

  • Create smooth and natural feeling motion controls using the SJTwo's onboard accelerometer.
  • Implement a collision detection system that can detect stage goals and will allow the marble to roll along walls.

Team Members & Responsibilities

  • Scott LoCascio
    • Game timer
    • LED Matrix driver implementation
    • Game graphics
    • Case/housing for project
    • Wiki editing
  • Francesco Vescio
    • Gameplay and concept
    • Collision logic
    • LED Matrix driver design
    • Motion controls
    • Wiki editing

Schedule

Week# Start Date End Date Task Status
1
  • 11/16/2020
  • 11/16/2020
  • 11/21/2020
  • 11/21/2020
  • 11/16/2020
  • 11/18/2020
  • 11/22/2020
  • 11/22/2020
  • Read previous projects, gather information and discuss among the group members
  • Order necessary parts
  • Create GitLab repository for project
  • Read and familiarize ourselves with LED Matrix Datasheet
  • Design project header files
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
2
  • 11/23/2020
  • 11/24/2020
  • 12/08/2020
  • 12/02/2020
  • Finalize wiki schedule
  • Develop graphics driver for LED matrix and implement initial game objects
  • Completed
  • Completed
3
  • 12/04/2020
  • 12/04/2020
  • 12/05/2020
  • 12/05/2020
  • 12/05/2020
  • 12/04/2020
  • 12/04/2020
  • 12/08/2020
  • 12/08/2020
  • 12/08/2020
  • Game object movement logic designed and implemented
  • Game object collision designed
  • Game object collision implemented
  • Motion controls designed and implemented
  • Testing and debugging controls and collision
  • Completed
  • Completed
  • Completed
  • Completed
  • Completed
4
  • 12/07/2020
  • 12/07/2020
  • 12/07/2020
  • 12/08/2020
  • 12/14/2020
  • 12/12/2020
  • Design and implement game timer
  • Design mazes and goals
  • Update game logic to switch stages and handle game loss
  • Completed
  • Completed
  • Completed
5
  • 12/14/2020
  • 12/17/2020
  • Final Demo
  • Upload gameplay video
  • Finalize wiki page
  • Push final code to GitLab repo
  • Completed
  • In progress
  • In Progress
  • Completed


Parts List & Cost

Quantity Item cost
1 5-Volt 20-Amp Power Supply $20
1 64x32 RGB LED Matrix $74
1 SJTwo Microcontroller $50

Design & Implementation

Hardware Design

The hardware for this project consists of an SJTwo microcontroller, an LED matrix and a power supply. The microcontroller handles the game logic, drives the display, and interfaces with its on-board accelerometer to control the game.

Hardware Interface

The LED Matrix requires 13 pins to function, which are connected to 13 pins on the SJ2 board configured as GPIO output pins. All pins are active high, except for the OE pin. These pins are initialized in the led_matrix__init() function.

The display is enabled by the active low OE pin. When the display needs to be updated, it needs to be disabled and the data unlatched by resetting the LAT pin. Then, two rows of LEDs are selected by setting pins A, B, C, and D, which act as a 4-to-16 decoder. The R1, G1, and B1 pins control the LED in the upper selected row, and the R2, G2, and B2 control the LED the lower row (16 rows down). Then, the CLK and LAT pins are toggled on/off in order to load the data into the LED matrix and select the next column of LEDs. After all LEDs for a row are updated, LAT is set, OE is reset, and a delay is added to prepare for the next row. When all rows are finished being updated, the OE pin is set again to display the LEDs.

LED Matrix Pins SJTwo Pins Function
R1 P0.18 Controls red color for rows 0-15 of the LED matrix
R2 P0.17 Controls red color for rows 16-31 of the LED matrix
G1 P0.22 Controls green color for rows 0-15 of the LED matrix
G2 P2.9 Controls green color for rows 16-31 of the LED matrix
B1 P0.15 Controls blue color for rows 0-15 of the LED matrix
B2 P0.16 Controls blue color for rows 16-31 of the LED matrix
A P2.7 One of four decoder inputs used to select the rows of the matrix
B P2.8 One of four decoder inputs used to select the rows of the matrix
C P2.5 One of four decoder inputs used to select the rows of the matrix
D P2.6 One of four decoder inputs used to select the rows of the matrix
CLK P2.2 Clock input used to shift bits into the display registers
LAT P2.4 Latch input used to save the state of the pins
OE P2.0 Output Enable, used to enable the display to power LEDs according to the current configuration of the display registers
GND(x3) GND Three ground pins of the display connect to a common ground on the SJTwo

The enclosure is a wooden box designed by the team.

CMPE244 MM inside enclosure.jpg

Software Design

The LED matrix driver, led_matrix.c, handles pin assignments, setting LEDs on and off, drawing mazes, updating the display, drawing and erasing the marble, and displaying the timer.

The game logic is contained in the marble.c file. The marble__init() function initializes the accelerometer, "zeroes" the marble so that the position you hold the LED board at is considered "flat," and sets the next stage to load to the title screen. The marble__handle_movement() method reads the accelerator reading, scales it to prevent choppy movement, calculates what the change in movement should be, and calls the marble__update_marble_position() function. This function checks the 12 spaces around for any obstacles that will limit its movement. If the ball will roll to the maze's goal, the next maze is loaded by a call to marble__draw_next_stage() and the marble repositioned to the starting position for that maze, which is determined by a call to marble__get_starting_coordinates(). The game timer is in the led_matrix.c file. The timer is displayed on the bottom of the board as a line of LEDs that slowly turn off. The LEDs start green, but when half of the time is remaining they turn yellow, and when a quarter of the time remains they turn red. When the timer runs out, the game over screen is displayed and the game resets back to the title screen.

FreeRTOS is used as the real-time operating system (RTOS) to manage the timing and call the various interfaces mentioned above. Two tasks are used. The highest priority task is the screen refresh task runs every 10 milliseconds to update the display based on the current state of the LED matrix buffer. The next task is called every 100 milliseconds and updates the position of the marble in the maze based on accelerometer readings and processes any interactions with the maze environment caused by the change in position.

CMPE244 MM software flow.jpg

CMPE 244 MM Collision.png

Technical Challenges

LED Matrix Driver

The LED matrix used in this project suffered from a lack of documentation. Adafruit has a tutorial on their website that uses a Python library they developed for use with Arduino boards. With no datasheet to reference, this project had to reference previous years' projects that used the same hardware. Specifically, it wasn't initially clear how the row select worked with the A, B, C, and D bits, as well as when the LAT pin should be driven high/low to latch/unlatch the data to update the display. After some trial and error, we figured out how to properly use the LAT pin.

Motion Controls

Creating smooth feeling motion controls required some finessing. Because we planned to mount the SJTWO-C board to the back of the LED matrix but were testing the game by holding the board directly, we couldn't be sure that the controls we developed would feel smooth in the final build.

Collision Detection

Issues arose with collision detection in mazes with tricky geometry. The marble would not move in certain directions despite having clearance. Some extra logic had to be added to the cases where a marble moved towards an LED lit in one of the four adjacent corners to eliminate the movement in a direction where there was not room enough for the marble to roll to or the direction in which the magnitude of movement was the smallest.

Conclusion

This project allowed us to take the concepts learned during the embedded systems course and put them into a practical application. We had to be creative about how we designed our game logic and mindful of how we were implementing the hardware interface. It was definitely a learning experience to see all of the work and consideration that goes into creating every aspect of a product.

Our game does have a limited set of features but can be expanded upon in the future. At some point, we would like to integrate score elements, a leaderboard, and audio. We were concerned that if we tried to implement too expansive of a feature set that we may have a lot of half baked features and an unplayable game. We prioritized accomplishing the parts necessary to have a complete game from start to finish and reached our goal. Ultimately, this project was a challenging learning experience and a lot of fun.


IMG 20201217 182114.jpg

Project Video

Project Source Code

References