This project is an interactive digital quiz game developed for an HMI (Human-Machine Interface) board and powered by the RT-Thread real-time operating system. Drawing inspiration from traditional quizbowl formats, it presents five carefully selected multiple-choice questions, shown one per screen to challenge and entertain users. The game features a real-time timer alongside scoring, allowing players to track their speed and accuracy. Using SquareLine Studio for design, the project achieves an intuitive, visually appealing interface and a smooth quiz experience on embedded hardware. BrainBoard demonstrates how real-time OS capabilities and user-focused HMI design can combine to deliver responsive, engaging applications for embedded systems.
Step 1: HMI Board Setup with RT-ThreadHow We Got Started with Hardware & RT-Thread
1. Unboxing and First Checks
- Together, we unboxed our HMI Board RA6M3 and made sure all the parts were included: the board itself, LCD, touch panel, and USB cable. We inspected the board and verified there was no visible damage or missing components before powering up.
2. Connecting to Our Computer
- We plugged the HMI Board into our laptop using the USB Type-C cable. As a team, we confirmed the device powered on and was recognized by our computer. Sometimes one of us would troubleshoot if a driver was not automatically detected.
3. Setting Up RT-Thread Studio IDE
- We downloaded RT-Thread Studio IDE from RT-Thread official website. After running the installer, we took turns going through the setup screens and familiarizing ourselves with the interface.
4. Installing the RA6M3 Board Support Package (BSP)
- In RT-Thread Studio, we used the SDK Manager to find and install the RA6M3 BSP, supporting our specific hardware. We double-checked that the installation completed successfully.
5. Starting a New Project
- We created a new project in RT-Thread Studio, using “RT-Thread BSP Project” and selecting RA6M3 as our target board. We discussed naming conventions and chose “BrainBoard_QuizGame” for clarity and teamwork.
6. Verifying Drivers and Connections
- Together, we made sure all necessary drivers (USB, touch) were installed for the RA6M3 board. We used the device browser in RT-Thread Studio to verify our board showed up properly.
7. Testing with Sample Code
- Before diving into our full application, we ran a basic sample (like a “Hello World” program or touch test) to confirm the board and IDE setup. Once the sample ran, such as an LED blink or a display output, we knew our hardware foundations were solid.
1. Opening SquareLine Studio
- We launched SquareLine Studio on our laptop and created a new UI project for BrainBoard. We set the resolution to 480 x 272 pixels to match the exact size of the RA6M3 HMI board display.
2. Planning the Screens
- Our team discussed which screens were needed for the game, including a start screen, multiple quiz screens for each question, and a results screen showing score and time.
3. Designing the Start Screen
- We placed a Panel widget as the container, added Label widgets for the title and description, and positioned the Play button in the center of the layout. We tested different fonts and colors until everything looked visually clear and readable.
4. Creating the Quiz Question Screens
- For each quiz screen, we used a Label for the question text and several Buttons for the possible answers, arranging them for easy selection and clear visibility. Labels for progress or feedback were included.
5. Building the Scoring and Time Results Screen
- We created a results page to display the player’s score and the time taken to complete the game. This screen had labels to show results and used a straightforward layout for user feedback.
6. Customizing Styles and Objects
- Using the Inspector panel, we set widget sizes, colors, and text alignment. We gave each widget clear names for easier code reference in later steps and made sure the visual style was consistent.
7. Capturing Screenshots
- Throughout the process, we took screenshots of the main screens to document our design choices.
8. Exporting UI Files
- When satisfied with the design, we exported our SquareLine project files, ready to integrate with our RT-Thread application.
1. We planned the quiz workflow, setting up the code to show questions in sequence and accept player input for answer choices.
2. We implemented navigation logic so the program moves from one question to the next when an answer is selected.
3. We checked answer selections and advanced through the full list of questions, ensuring the game logic was smooth and intuitive.
Step 4: Building the Scoring System1. We programmed the backend to track the player’s score.
#include "ui.h"
#include <rtthread.h>
#include <stdio.h> // Required for snprintf if not using standard set_text_fmt
int current_score = 0;
void IncrementScore(lv_event_t * e)
{
current_score++;
rt_kprintf("Correct! Score: %d\n", current_score);
}
void UpdateScoreLabel(lv_event_t * e)
{
rt_kprintf("Updating Screen 7 Label. Final Score: %d\n", current_score);
if (ui_LabelScore != NULL) {
lv_label_set_text_fmt(ui_LabelScore, "%d", current_score);
}
}2. For each question, we checked if the selected answer was correct and updated the score accordingly.
3. After the last question was answered, we displayed the total score on the results screen.
4. We tested the scoring logic with various answer patterns to confirm it updated accurately each time.
Step 5: Adding Timer Functionality1. We added code to start the timer when the player begins the quiz.
#include "ui.h"
#include "lvgl.h"
#include <rtthread.h>
#include <stdio.h>
int current_score = 0;
static int elapsed_seconds = 0;
static lv_timer_t * game_timer = NULL;
static void game_timer_callback(lv_timer_t * timer)
{
(void)timer;
elapsed_seconds++;
int minutes = elapsed_seconds / 60;
int seconds = elapsed_seconds % 60;
if (ui_LabelTimer1 != NULL) {
lv_label_set_text_fmt(ui_LabelTimer1, "%02d:%02d", minutes, seconds);
}
}
void IncrementScore(lv_event_t * e)
{
(void)e;
current_score++;
rt_kprintf("Correct! Score: %d\n", current_score);
}
void UpdateScoreLabel(lv_event_t * e)
{
(void)e;
rt_kprintf("Updating Score Label. Final Score: %d\n", current_score);
if (ui_LabelScore != NULL) {
lv_label_set_text_fmt(ui_LabelScore, "%d", current_score);
}
}
void StartGameTrigger(lv_event_t * e)
{
(void)e;
elapsed_seconds = 0;
current_score = 0;
if (ui_LabelTimer1 != NULL) {
lv_label_set_text(ui_LabelTimer1, "00:00");
}
if (game_timer == NULL) {
game_timer = lv_timer_create(game_timer_callback, 1000, NULL);
} else {
lv_timer_resume(game_timer);
}
rt_kprintf("Game Timer Started.\n");
}
void StopGameTrigger(lv_event_t * e)
{
(void)e;
if (game_timer != NULL) {
lv_timer_pause(game_timer);
}
int minutes = elapsed_seconds / 60;
int seconds = elapsed_seconds % 60;
printf("Game Finished! Total Time: %02d:%02d. Final Score: %d\n",
minutes, seconds, current_score);
}2. The timer runs in parallel, measuring how long it takes for the player to complete all questions.
3. Once the final question is answered, we stopped the timer and showed the elapsed time on the results page.
4. We checked the timer for accuracy and confirmed that it responds instantly at both the start and end of the game.







Comments