Difference between revisions of "F20: Maddening Marbles"
Proj user10 (talk | contribs) (→Abstract) |
Proj user11 (talk | contribs) (→Conclusion) |
||
(40 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | == | + | == Maddening Marbles == |
− | + | [[File:CMPE244 MM main screen.jpg]] | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | Maddening Marbles | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Objectives & Introduction == | == 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 === | === Team Members & Responsibilities === | ||
* Scott LoCascio | * 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 == | == Schedule == | ||
Line 45: | Line 33: | ||
! scope="row"| 1 | ! scope="row"| 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 | + | * Read previous projects, gather information and discuss among the group members |
+ | * Order necessary parts | ||
* Create GitLab repository for project | * Create GitLab repository for project | ||
+ | * Read and familiarize ourselves with LED Matrix Datasheet | ||
+ | * Design project header files | ||
| | | | ||
+ | * <span style="color:green">Completed</span> | ||
+ | * <span style="color:green">Completed</span> | ||
+ | * <span style="color:green">Completed</span> | ||
* <span style="color:green">Completed</span> | * <span style="color:green">Completed</span> | ||
* <span style="color:green">Completed</span> | * <span style="color:green">Completed</span> | ||
|- | |- | ||
! scope="row"| 2 | ! scope="row"| 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 | * Develop graphics driver for LED matrix and implement initial game objects | ||
| | | | ||
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
+ | * <span style="color:green">Completed</span> | ||
|- | |- | ||
− | ! scope="row"| | + | ! scope="row"| 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 |
| | | | ||
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
|- | |- | ||
− | ! scope="row"| | + | ! scope="row"| 4 |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
| | | | ||
+ | * 12/07/2020 | ||
+ | * 12/07/2020 | ||
* 12/07/2020 | * 12/07/2020 | ||
| | | | ||
− | * 12/ | + | * 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 | ||
| | | | ||
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
|- | |- | ||
− | ! scope="row"| | + | ! scope="row"| 5 |
| | | | ||
− | + | * 12/14/2020 | |
− | |||
− | |||
− | *12/14/2020 | ||
| | | | ||
− | *12/ | + | * 12/17/2020 |
− | |||
− | |||
− | |||
| | | | ||
− | *Final Demo | + | * Final Demo |
− | * | + | * Upload gameplay video |
− | + | * Finalize wiki page | |
− | * | + | * Push final code to GitLab repo |
| | | | ||
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
− | * <span style="color: | + | * <span style="color:orange">In progress</span> |
− | * <span style="color: | + | * <span style="color:orange">In Progress</span> |
− | * <span style="color: | + | * <span style="color:green">Completed</span> |
|- | |- | ||
|} | |} | ||
Line 198: | Line 136: | ||
== Parts List & Cost == | == Parts List & Cost == | ||
− | |||
− | + | {| class="wikitable" | |
− | + | |+ | |
− | + | |- | |
+ | ! Quantity !! Item !! cost | ||
+ | |- | ||
+ | | 1 || 5-Volt 20-Amp Power Supply || $20 | ||
+ | |- | ||
+ | | 1 || 64x32 RGB LED Matrix || $74 | ||
+ | |- | ||
+ | | 1 || SJTwo Microcontroller || $50 | ||
+ | |} | ||
== Design & Implementation == | == Design & Implementation == | ||
− | |||
=== Hardware Design === | === 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 === | === 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. | ||
+ | |||
+ | {| 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 === | ||
− | + | 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. | ||
+ | |||
+ | [[File:CMPE244_MM_software_flow.jpg]] | ||
+ | |||
+ | [[File: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 == | == 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. | ||
+ | |||
+ | |||
+ | [[File:IMG 20201217 182114.jpg]] | ||
=== Project Video === | === Project Video === | ||
− | + | * [https://youtu.be/TVMcgRM9wH8 Maddening Marbles Video Link] | |
=== Project Source Code === | === Project Source Code === | ||
− | * [https:// | + | * [https://gitlab.com/parkingfrenzy/sjtwo-c GitLab Source Code Link] |
== References == | == References == | ||
− | + | * [https://github.com/adafruit/RGB-matrix-Panel Adafruit LED Matrix Library] | |
− | + | * [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] | |
− | |||
− | |||
− | |||
− | |||
− |
Latest revision as of 07:41, 18 December 2020
Contents
Maddening Marbles
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 |
|
|
|
|
2 |
|
|
|
|
3 |
|
|
|
|
4 |
|
|
|
|
5 |
|
|
|
|
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.
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.
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.