Skip to content

Getting Started

Microesque edited this page Mar 7, 2025 · 5 revisions

Overview


Internal Buffer

The library only supports communication via I2C, which comes with certain limitations. Unfortunately, the SSD1306 driver is read-only in serial mode and does not provide a method to write to a single pixel. As a result, the library has to use an internal buffer to store the contents of the display. The internal buffer contents can be pushed onto the display with an ssd1306_display_update() function call:

/* Update the display with the internal buffer */
ssd1306_display_update(&display);

This approach is generally preferred for displays anyways, as updating individual pixels can cause visual artifacts and tearing. Unfortunately, for simpler projects with limited memory, a no-buffer version of the library is not available.

A 128x64 display requires an additional 1026 bytes of memory for the buffer.

A 128x32 display requires an additional 514 bytes of memory for the buffer.


Function Types

The library follows an object-oriented design, where displays are represented as objects, and all operations are performed through function calls.

All library functions require the address of an ssd1306_display structure as their first argument. This structure represents the displays, and the operations performed will only affect the display passed to any given function.

Before calling any other library function, the ssd1306_display structure must be initialized with the ssd1306_init() function using the appropriate arguments (refer to Setup Guide).

There are four categories of functions (refer to Functions Manual). These are:

  • Initialization Functions
  • Display Functions
  • Draw Functions
  • Getter/Setter Functions
  • Initialization Functions are used to initialize the ssd1306_display structures as well as their physical display.
  • Display Functions are used to send hardware commands to the display. Since these are hardware commands, they don't affect the buffer in any way and will take effect immediately without the need to update the display.
  • Draw Functions are used to manipulate the internal buffer. These operations won't be visible until the physical display is updated with the internal buffer contents by calling the ssd1306_display_update() function.
  • Getter/Setter Functions are used to read and configure various display properties. Directly manipulating the ssd1306_display structures is not recommended.

All functions are named for convenience when using IntelliSense:

  • Display Functions begin with ssd1306_display_...
  • Draw Functions begin with ssd1306_draw_...
  • Getter Functions begin with ssd1306_get_...
  • Setter Functions begin with ssd1306_set_...

Buffer Mode

Clearing the display is just as important as drawing on it. Instead of providing separate functions for each operation, such as draw_circle() and clear_circle(), the library introduces a buffer mode property for displays.

The buffer mode can be set to either draw or clear with the ssd1306_set_buffer_mode() function:

Note: Use the ssd1306_buffer_mode enum provided in the header file.

/* Set buffer to 'draw' mode */
ssd1306_set_buffer_mode(&display, SSD1306_BUFFER_MODE_DRAW);

/* Set buffer to 'clear' mode */
ssd1306_set_buffer_mode(&display, SSD1306_BUFFER_MODE_CLEAR);

/* Invert the buffer mode (draw->clear or clear->draw) */
ssd1306_set_buffer_mode_inverse(&display);

In draw mode, all Draw Functions turn the pixels on as expected. In clear mode, these same functions clear the pixels instead.

The clear mode enables operations such as removing a circle from a filled area, erasing text from a filled box, or drawing the inverse of an image. For example, you can create a thick circle by first drawing a filled circle and then clearing a smaller circle at the same coordinates:

/* Draw a filled circle at (64, 32) with a radius of 30 */
ssd1306_set_buffer_mode(&display, SSD1306_BUFFER_MODE_DRAW);
ssd1306_draw_circle_fill(&display, 64, 32, 30);

/* Clear a filled circle at (64, 32) with a radius of 20 */
ssd1306_set_buffer_mode(&display, SSD1306_BUFFER_MODE_CLEAR);
ssd1306_draw_circle_fill(&display, 64, 32, 20);

/* Update the display */
ssd1306_display_update(&display);
img

Display Border

The library defines the top-left corner of the screen as the origin (0, 0), with coordinates increasing to the right and downward:

img

All Draw Functions support drawing to any coordinates, including negative or out-of-bounds. Pixels outside the display area are automatically clipped, eliminating the need for user-implemented safety checks. This also means that objects can be drawn half in frame without any issues:

/* Draw a filled circle at (-30, -10) with a radius of 80 */
ssd1306_draw_circle_fill(&display, -30, -10, 80);

/* Update the display */
ssd1306_display_update(&display);
img

The ability to modify the display borders is also implemented. The library introduces a draw border property for displays. This border represents a rectangle where any attempts to draw pixels outside of its area will be ignored.

The draw border can be set with the ssd1306_set_draw_border() function:

Notes:

  • The border area can't extend beyond the display edges. If any coordinates exceed the display boundaries, they will be automatically constrained.
  • The actual arguments given to the ssd1306_set_draw_border() function are the minimum and maximum xy-coordinates (refer to Functions Manual). The rectangle mentioned is just a simple visualization. For example, if the second set of coordinates (maximum values) are set to zero, nothing will ever be drawn regardless of the first set of coordinates (minimum values).
/* Set the rectangle border from (0, 15) to (127, 50) */
ssd1306_set_draw_border(&display, 0, 15, 127, 50);

/* Draw a filled circle at (-30, -10) with a radius of 80 */
ssd1306_draw_circle_fill(&display, -30, -10, 80);

/* Update the display */
ssd1306_display_update(&display);
img

Note that, after setting the border, the contents of the display that remain beyond the rectangle won't be cleared. The border only affects the subsequent draws after it is set.

The border can be easily reset back to the display edges with the ssd1306_set_draw_border_reset() function:

/* Reset the border back to display edges */
ssd1306_set_draw_border_reset(&display);

Default Configurations

All display settings and configurations can be adjusted individually through functions, but if you only plan to configure them once, you can directly change the default configurations instead.

The default configurations applied by the Initialization Functions are defined as macros in the ssd1306.h file under the Library Setup section. Be sure to follow the provided descriptions and adhere to the valid range of values when making adjustments.

Any changes made to these macros will be global, and affect all display instances. If separate configurations are required, use the library functions instead.

If you're unsure about any of the configurations, you can leave them as is. The default configurations represent the normal behavior you'd expect from the display.