OLED

The top boards on microcontroller6.0 have an OLED screen. Everything displayed on the OLED is defined by a page that follows a certain structure. The pages are connected to each other like a tree structure. This page provides an overview of the driver and instructions on how to create new pages.

There are 3 major sections

Driver

The driver contains the code that keeps track of what page should be displayed and what should happen after a button press. Besides that it contains the definition of the warning/error pages.

Buttons

The pages on the OLED screen can be navigated by using the buttons on the top board. They can be used as follows:

struct page_struct

Each page has to follow a structure, which is as follows:

Name type max size explanation
id int Used for routing to the correct function that runs a self-test or updates variables. Needs be unique
page_name char array 15 Name of page, used for menu's and display
parent page_struct pointer Parent of the current page
children array of page_struct pointers 9 Amount of children each page is allowed to have.
n_of_children int Keeps track of how many children the page actually has to prevent overflows
is_menu bool Indicates if page is a menu
is_test enum test_type Indicates if page is a test and what kind of test it is
has_variables bool Indicates if page has variables that needs to be updated while displaying the page
line0 char array 23 text that is displayed on line 0
line1 char array 23 text that is displayed on line 1
line2 char array 23 text that is displayed on line 2
line3 char array 23 text that is displayed on line 3

Enum test_type

Every page has a test_type, which can be either NOT_A_TEST, BLOCKING_TEST, NON_BLOCKING_TEST. The default is that a page is NOT_A_TEST. When the page is meant to run a page, one of the other options should be selected. If the test does not make use of the “control loop” (part of HAL_TIM_PeriodElapsedCallback) or any other functions called in the main loop, BLOCKING_TEST should be selected. If it does make use of these loops that are not directly called by the OLED, NON_BLOCKING_TEST should be selected.

Base pages

There are a few pages defined in the driver that display warnings, errors, and are used on bootup

Update

The update function is called by the main loop of the top board, and takes the following steps

  1. If a menu has too many children, display hasTooManyChildrenException
  2. If no button is pressed, run the test or update the variables on the page if applicable. Return anyway
  3. If a button is pressed, follow up on the actions as discussed before
  4. Check if page is a test and if test mode is disabled, if both are true display the warning NotInTestMode
  5. Either display the menuHasNoChildrenException if applicable or display the new page

Start/End of test

At the start of a test, calling start_of_test is recommended to display that the test has started. At the end of a test it is strongly to call end_of_test, as it brakes the wheels and for non-blocking tests it also should stop the robot from kicking and dribbling.

Limitations

Pages

Pages can typically be categorized in one of four ways.

pages have default values, which can be set by pages_set_deafault_values(&page, parent). This sets the parent, and sets fields like is_menu to false. To make sure the edge between parent and child is set in both ways add_child_to_parent(&child) should be used.

In the menus folder you can some of the menu's present. For example the main_menu.c file. In this file the children of main menu (that are also a menu) are initialized, not the page itself. This is done to minimize the amount of pages needed. Some menus, especially those where a setting for a self test is selected, are initialized in the file of the self test.

Self test

Self tests have at least 2 functions.

  1. init() or similair where the pages are initialized
  2. run() where the test is executed, which is called from the selftest_selector

Reminder to use start_of_test() and end_of_test()

Variable page

Variable pages have at least 2 functions.

  1. init() or similair where the pages are initialized
  2. update() where the the values are updated, which is called from the variable_page_selector

Selector

To call the correct run() or update(), there is a selftest_selector and variable_page_selector respectively. They check the id of the current page and check which function should be called.