Setup Guide

Microesque edited this page Mar 7, 2025 · 4 revisions

Overview


Library Setup

  • Download or clone the repository.
  • Navigate to the lib folder.
  • Copy the ssd1306.c and ssd1306.h into your project directory.
  • Include the ssd1306.h in your source file.
  • Set up your display by following the Display Setup below. See the Example main.c Files as well.
  • Use the provided library functions to test your display. Optionally you can use the demo or test animations.

Display Setup

Step-1: Create an I2C Callback

Define an I2C callback function with the following prototype:

voidi2c_write(uint8_t*data, uint16_tlength);

You'll need to either create an I2C library or adapt an existing one for your platform. Most embedded systems are shipped with hardware abstraction libraries that can be used with minimal tweaking as shown in the examples below.

Note: The first byte of the data passed to this function will always be the 8-bit I2C write address (i2c_address << 1) of the display. Note that this isn't the original 7-bit address but the I2C write command for that address. This is done to enable support for various I2C libraries, some of which don't have a sequential write or address-data separate write functions. If your I2C library sends the address separately:

  • Read the first data byte to get the address. If necessary, shift it to the right by one to get the 7-bit address.
  • Advance the data pointer by one, and decrement the length by one, and send the data with your library write function.

Example - Discrete I2C Functions (Start/Stop/Write):

voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}

Example - STM32 HAL Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}

Example - PIC16/18 MCC Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}

Step-2: Create a Display Object

Define an ssd1306_display structure for your display. This object will represent your display, and all library functions will require it as their first argument:

staticstructssd1306_displaydisplay;

Step-3: Create a Buffer Array

Define a uint8_t array for your display. This array will serve as the internal buffer for your display. Use the macros in the header file to declare an array with the appropriate size according to your display type:

/* For 128x64 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
/* For 128x32 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_32];

Step-4: Initialize the Display

Initialize the ssd1306_display structure with the ssd1306_init() function. This will initialize both the structure and the physical display:

The arguments are:

  • Arg1: The address of your ssd1306_display structure.
  • Arg2: The 7-bit I2C address of your display.
  • Arg3: The Type of your display. Use the ssd1306_display_type enum from the header file:
    • SSD1306_DISPLAY_TYPE_32 for 128x32 displays.
    • SSD1306_DISPLAY_TYPE_64 for 128x64 displays.
  • Arg4: The address of your display_array.
  • Arg5: The address of your i2c_write function
/* 128x64 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* 128x32 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_32,
display_array,
i2c_write);

Example main.c Files

Below are example main.c files demonstrating the minimum code required to display a circle in the center of a 128x64 display with the I2C address 0x3C:

Note: For 128x32 displays, simply adjust the display initialization and the circle shape accordingly.

Example - Discrete I2C Functions (Start/Stop/Write):

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - STM32 HAL Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - PIC16/18 MCC Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}
voidmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}
img

Demo and Test Files

The library also includes demo and test animations:

  • Demo files include various cool animations that can be performed with the library.
  • Test files include lazily written test animations for each library function. These aren't unit tests, but simple animations.

Note: Instead of a manual setup like shown below, you have the option to put the entire repository into your project instead.

Demo Files Setup

  • Follow the Library Setup.
  • Navigate to the demo folder and copy the ssd1306_demo.c and ssd1306_demo.h into your project the same way.
  • Open the ssd1306_demo.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_demo.h in your source file and call one of the demo functions listed in the header file (all demo functions are infinite loops):

Note: Demo functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_demo.h"/* In your main.c after display initializations */ssd1306_demo_1(&display, 0);

Test Files Setup

  • Follow the Library Setup.
  • Navigate to the test folder and copy the ssd1306_test.c and ssd1306_test.h into your project the same way.
  • Open the ssd1306_test.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_test.h in your source file and call one of the test functions listed in the header file (all test functions are infinite loops):

Note: Test functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_test.h"/* In your main.c after display initializations */ssd1306_test_draw_shifts(&display, 0);
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Setup Guide

Microesque edited this page Mar 7, 2025 · 4 revisions

Overview


Library Setup

  • Download or clone the repository.
  • Navigate to the lib folder.
  • Copy the ssd1306.c and ssd1306.h into your project directory.
  • Include the ssd1306.h in your source file.
  • Set up your display by following the Display Setup below. See the Example main.c Files as well.
  • Use the provided library functions to test your display. Optionally you can use the demo or test animations.

Display Setup

Step-1: Create an I2C Callback

Define an I2C callback function with the following prototype:

voidi2c_write(uint8_t*data, uint16_tlength);

You'll need to either create an I2C library or adapt an existing one for your platform. Most embedded systems are shipped with hardware abstraction libraries that can be used with minimal tweaking as shown in the examples below.

Note: The first byte of the data passed to this function will always be the 8-bit I2C write address (i2c_address << 1) of the display. Note that this isn't the original 7-bit address but the I2C write command for that address. This is done to enable support for various I2C libraries, some of which don't have a sequential write or address-data separate write functions. If your I2C library sends the address separately:

  • Read the first data byte to get the address. If necessary, shift it to the right by one to get the 7-bit address.
  • Advance the data pointer by one, and decrement the length by one, and send the data with your library write function.

Example - Discrete I2C Functions (Start/Stop/Write):

voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}

Example - STM32 HAL Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}

Example - PIC16/18 MCC Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}

Step-2: Create a Display Object

Define an ssd1306_display structure for your display. This object will represent your display, and all library functions will require it as their first argument:

staticstructssd1306_displaydisplay;

Step-3: Create a Buffer Array

Define a uint8_t array for your display. This array will serve as the internal buffer for your display. Use the macros in the header file to declare an array with the appropriate size according to your display type:

/* For 128x64 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
/* For 128x32 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_32];

Step-4: Initialize the Display

Initialize the ssd1306_display structure with the ssd1306_init() function. This will initialize both the structure and the physical display:

The arguments are:

  • Arg1: The address of your ssd1306_display structure.
  • Arg2: The 7-bit I2C address of your display.
  • Arg3: The Type of your display. Use the ssd1306_display_type enum from the header file:
    • SSD1306_DISPLAY_TYPE_32 for 128x32 displays.
    • SSD1306_DISPLAY_TYPE_64 for 128x64 displays.
  • Arg4: The address of your display_array.
  • Arg5: The address of your i2c_write function
/* 128x64 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* 128x32 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_32,
display_array,
i2c_write);

Example main.c Files

Below are example main.c files demonstrating the minimum code required to display a circle in the center of a 128x64 display with the I2C address 0x3C:

Note: For 128x32 displays, simply adjust the display initialization and the circle shape accordingly.

Example - Discrete I2C Functions (Start/Stop/Write):

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - STM32 HAL Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - PIC16/18 MCC Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}
voidmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}
img

Demo and Test Files

The library also includes demo and test animations:

  • Demo files include various cool animations that can be performed with the library.
  • Test files include lazily written test animations for each library function. These aren't unit tests, but simple animations.

Note: Instead of a manual setup like shown below, you have the option to put the entire repository into your project instead.

Demo Files Setup

  • Follow the Library Setup.
  • Navigate to the demo folder and copy the ssd1306_demo.c and ssd1306_demo.h into your project the same way.
  • Open the ssd1306_demo.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_demo.h in your source file and call one of the demo functions listed in the header file (all demo functions are infinite loops):

Note: Demo functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_demo.h"/* In your main.c after display initializations */ssd1306_demo_1(&display, 0);

Test Files Setup

  • Follow the Library Setup.
  • Navigate to the test folder and copy the ssd1306_test.c and ssd1306_test.h into your project the same way.
  • Open the ssd1306_test.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_test.h in your source file and call one of the test functions listed in the header file (all test functions are infinite loops):

Note: Test functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_test.h"/* In your main.c after display initializations */ssd1306_test_draw_shifts(&display, 0);
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Setup Guide

Microesque edited this page Mar 7, 2025 · 4 revisions

Overview


Library Setup

  • Download or clone the repository.
  • Navigate to the lib folder.
  • Copy the ssd1306.c and ssd1306.h into your project directory.
  • Include the ssd1306.h in your source file.
  • Set up your display by following the Display Setup below. See the Example main.c Files as well.
  • Use the provided library functions to test your display. Optionally you can use the demo or test animations.

Display Setup

Step-1: Create an I2C Callback

Define an I2C callback function with the following prototype:

voidi2c_write(uint8_t*data, uint16_tlength);

You'll need to either create an I2C library or adapt an existing one for your platform. Most embedded systems are shipped with hardware abstraction libraries that can be used with minimal tweaking as shown in the examples below.

Note: The first byte of the data passed to this function will always be the 8-bit I2C write address (i2c_address << 1) of the display. Note that this isn't the original 7-bit address but the I2C write command for that address. This is done to enable support for various I2C libraries, some of which don't have a sequential write or address-data separate write functions. If your I2C library sends the address separately:

  • Read the first data byte to get the address. If necessary, shift it to the right by one to get the 7-bit address.
  • Advance the data pointer by one, and decrement the length by one, and send the data with your library write function.

Example - Discrete I2C Functions (Start/Stop/Write):

voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}

Example - STM32 HAL Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}

Example - PIC16/18 MCC Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}

Step-2: Create a Display Object

Define an ssd1306_display structure for your display. This object will represent your display, and all library functions will require it as their first argument:

staticstructssd1306_displaydisplay;

Step-3: Create a Buffer Array

Define a uint8_t array for your display. This array will serve as the internal buffer for your display. Use the macros in the header file to declare an array with the appropriate size according to your display type:

/* For 128x64 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
/* For 128x32 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_32];

Step-4: Initialize the Display

Initialize the ssd1306_display structure with the ssd1306_init() function. This will initialize both the structure and the physical display:

The arguments are:

  • Arg1: The address of your ssd1306_display structure.
  • Arg2: The 7-bit I2C address of your display.
  • Arg3: The Type of your display. Use the ssd1306_display_type enum from the header file:
    • SSD1306_DISPLAY_TYPE_32 for 128x32 displays.
    • SSD1306_DISPLAY_TYPE_64 for 128x64 displays.
  • Arg4: The address of your display_array.
  • Arg5: The address of your i2c_write function
/* 128x64 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* 128x32 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_32,
display_array,
i2c_write);

Example main.c Files

Below are example main.c files demonstrating the minimum code required to display a circle in the center of a 128x64 display with the I2C address 0x3C:

Note: For 128x32 displays, simply adjust the display initialization and the circle shape accordingly.

Example - Discrete I2C Functions (Start/Stop/Write):

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - STM32 HAL Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - PIC16/18 MCC Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}
voidmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}
img

Demo and Test Files

The library also includes demo and test animations:

  • Demo files include various cool animations that can be performed with the library.
  • Test files include lazily written test animations for each library function. These aren't unit tests, but simple animations.

Note: Instead of a manual setup like shown below, you have the option to put the entire repository into your project instead.

Demo Files Setup

  • Follow the Library Setup.
  • Navigate to the demo folder and copy the ssd1306_demo.c and ssd1306_demo.h into your project the same way.
  • Open the ssd1306_demo.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_demo.h in your source file and call one of the demo functions listed in the header file (all demo functions are infinite loops):

Note: Demo functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_demo.h"/* In your main.c after display initializations */ssd1306_demo_1(&display, 0);

Test Files Setup

  • Follow the Library Setup.
  • Navigate to the test folder and copy the ssd1306_test.c and ssd1306_test.h into your project the same way.
  • Open the ssd1306_test.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_test.h in your source file and call one of the test functions listed in the header file (all test functions are infinite loops):

Note: Test functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_test.h"/* In your main.c after display initializations */ssd1306_test_draw_shifts(&display, 0);
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Setup Guide

Microesque edited this page Mar 7, 2025 · 4 revisions

Overview


Library Setup

  • Download or clone the repository.
  • Navigate to the lib folder.
  • Copy the ssd1306.c and ssd1306.h into your project directory.
  • Include the ssd1306.h in your source file.
  • Set up your display by following the Display Setup below. See the Example main.c Files as well.
  • Use the provided library functions to test your display. Optionally you can use the demo or test animations.

Display Setup

Step-1: Create an I2C Callback

Define an I2C callback function with the following prototype:

voidi2c_write(uint8_t*data, uint16_tlength);

You'll need to either create an I2C library or adapt an existing one for your platform. Most embedded systems are shipped with hardware abstraction libraries that can be used with minimal tweaking as shown in the examples below.

Note: The first byte of the data passed to this function will always be the 8-bit I2C write address (i2c_address << 1) of the display. Note that this isn't the original 7-bit address but the I2C write command for that address. This is done to enable support for various I2C libraries, some of which don't have a sequential write or address-data separate write functions. If your I2C library sends the address separately:

  • Read the first data byte to get the address. If necessary, shift it to the right by one to get the 7-bit address.
  • Advance the data pointer by one, and decrement the length by one, and send the data with your library write function.

Example - Discrete I2C Functions (Start/Stop/Write):

voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}

Example - STM32 HAL Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}

Example - PIC16/18 MCC Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}

Step-2: Create a Display Object

Define an ssd1306_display structure for your display. This object will represent your display, and all library functions will require it as their first argument:

staticstructssd1306_displaydisplay;

Step-3: Create a Buffer Array

Define a uint8_t array for your display. This array will serve as the internal buffer for your display. Use the macros in the header file to declare an array with the appropriate size according to your display type:

/* For 128x64 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
/* For 128x32 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_32];

Step-4: Initialize the Display

Initialize the ssd1306_display structure with the ssd1306_init() function. This will initialize both the structure and the physical display:

The arguments are:

  • Arg1: The address of your ssd1306_display structure.
  • Arg2: The 7-bit I2C address of your display.
  • Arg3: The Type of your display. Use the ssd1306_display_type enum from the header file:
    • SSD1306_DISPLAY_TYPE_32 for 128x32 displays.
    • SSD1306_DISPLAY_TYPE_64 for 128x64 displays.
  • Arg4: The address of your display_array.
  • Arg5: The address of your i2c_write function
/* 128x64 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* 128x32 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_32,
display_array,
i2c_write);

Example main.c Files

Below are example main.c files demonstrating the minimum code required to display a circle in the center of a 128x64 display with the I2C address 0x3C:

Note: For 128x32 displays, simply adjust the display initialization and the circle shape accordingly.

Example - Discrete I2C Functions (Start/Stop/Write):

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - STM32 HAL Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - PIC16/18 MCC Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}
voidmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}
img

Demo and Test Files

The library also includes demo and test animations:

  • Demo files include various cool animations that can be performed with the library.
  • Test files include lazily written test animations for each library function. These aren't unit tests, but simple animations.

Note: Instead of a manual setup like shown below, you have the option to put the entire repository into your project instead.

Demo Files Setup

  • Follow the Library Setup.
  • Navigate to the demo folder and copy the ssd1306_demo.c and ssd1306_demo.h into your project the same way.
  • Open the ssd1306_demo.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_demo.h in your source file and call one of the demo functions listed in the header file (all demo functions are infinite loops):

Note: Demo functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_demo.h"/* In your main.c after display initializations */ssd1306_demo_1(&display, 0);

Test Files Setup

  • Follow the Library Setup.
  • Navigate to the test folder and copy the ssd1306_test.c and ssd1306_test.h into your project the same way.
  • Open the ssd1306_test.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_test.h in your source file and call one of the test functions listed in the header file (all test functions are infinite loops):

Note: Test functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_test.h"/* In your main.c after display initializations */ssd1306_test_draw_shifts(&display, 0);
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Setup Guide

Microesque edited this page Mar 7, 2025 · 4 revisions

Overview


Library Setup

  • Download or clone the repository.
  • Navigate to the lib folder.
  • Copy the ssd1306.c and ssd1306.h into your project directory.
  • Include the ssd1306.h in your source file.
  • Set up your display by following the Display Setup below. See the Example main.c Files as well.
  • Use the provided library functions to test your display. Optionally you can use the demo or test animations.

Display Setup

Step-1: Create an I2C Callback

Define an I2C callback function with the following prototype:

voidi2c_write(uint8_t*data, uint16_tlength);

You'll need to either create an I2C library or adapt an existing one for your platform. Most embedded systems are shipped with hardware abstraction libraries that can be used with minimal tweaking as shown in the examples below.

Note: The first byte of the data passed to this function will always be the 8-bit I2C write address (i2c_address << 1) of the display. Note that this isn't the original 7-bit address but the I2C write command for that address. This is done to enable support for various I2C libraries, some of which don't have a sequential write or address-data separate write functions. If your I2C library sends the address separately:

  • Read the first data byte to get the address. If necessary, shift it to the right by one to get the 7-bit address.
  • Advance the data pointer by one, and decrement the length by one, and send the data with your library write function.

Example - Discrete I2C Functions (Start/Stop/Write):

voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}

Example - STM32 HAL Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}

Example - PIC16/18 MCC Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}

Step-2: Create a Display Object

Define an ssd1306_display structure for your display. This object will represent your display, and all library functions will require it as their first argument:

staticstructssd1306_displaydisplay;

Step-3: Create a Buffer Array

Define a uint8_t array for your display. This array will serve as the internal buffer for your display. Use the macros in the header file to declare an array with the appropriate size according to your display type:

/* For 128x64 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
/* For 128x32 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_32];

Step-4: Initialize the Display

Initialize the ssd1306_display structure with the ssd1306_init() function. This will initialize both the structure and the physical display:

The arguments are:

  • Arg1: The address of your ssd1306_display structure.
  • Arg2: The 7-bit I2C address of your display.
  • Arg3: The Type of your display. Use the ssd1306_display_type enum from the header file:
    • SSD1306_DISPLAY_TYPE_32 for 128x32 displays.
    • SSD1306_DISPLAY_TYPE_64 for 128x64 displays.
  • Arg4: The address of your display_array.
  • Arg5: The address of your i2c_write function
/* 128x64 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* 128x32 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_32,
display_array,
i2c_write);

Example main.c Files

Below are example main.c files demonstrating the minimum code required to display a circle in the center of a 128x64 display with the I2C address 0x3C:

Note: For 128x32 displays, simply adjust the display initialization and the circle shape accordingly.

Example - Discrete I2C Functions (Start/Stop/Write):

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - STM32 HAL Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - PIC16/18 MCC Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}
voidmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}
img

Demo and Test Files

The library also includes demo and test animations:

  • Demo files include various cool animations that can be performed with the library.
  • Test files include lazily written test animations for each library function. These aren't unit tests, but simple animations.

Note: Instead of a manual setup like shown below, you have the option to put the entire repository into your project instead.

Demo Files Setup

  • Follow the Library Setup.
  • Navigate to the demo folder and copy the ssd1306_demo.c and ssd1306_demo.h into your project the same way.
  • Open the ssd1306_demo.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_demo.h in your source file and call one of the demo functions listed in the header file (all demo functions are infinite loops):

Note: Demo functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_demo.h"/* In your main.c after display initializations */ssd1306_demo_1(&display, 0);

Test Files Setup

  • Follow the Library Setup.
  • Navigate to the test folder and copy the ssd1306_test.c and ssd1306_test.h into your project the same way.
  • Open the ssd1306_test.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_test.h in your source file and call one of the test functions listed in the header file (all test functions are infinite loops):

Note: Test functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_test.h"/* In your main.c after display initializations */ssd1306_test_draw_shifts(&display, 0);
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Setup Guide

Microesque edited this page Mar 7, 2025 · 4 revisions

Overview


Library Setup

  • Download or clone the repository.
  • Navigate to the lib folder.
  • Copy the ssd1306.c and ssd1306.h into your project directory.
  • Include the ssd1306.h in your source file.
  • Set up your display by following the Display Setup below. See the Example main.c Files as well.
  • Use the provided library functions to test your display. Optionally you can use the demo or test animations.

Display Setup

Step-1: Create an I2C Callback

Define an I2C callback function with the following prototype:

voidi2c_write(uint8_t*data, uint16_tlength);

You'll need to either create an I2C library or adapt an existing one for your platform. Most embedded systems are shipped with hardware abstraction libraries that can be used with minimal tweaking as shown in the examples below.

Note: The first byte of the data passed to this function will always be the 8-bit I2C write address (i2c_address << 1) of the display. Note that this isn't the original 7-bit address but the I2C write command for that address. This is done to enable support for various I2C libraries, some of which don't have a sequential write or address-data separate write functions. If your I2C library sends the address separately:

  • Read the first data byte to get the address. If necessary, shift it to the right by one to get the 7-bit address.
  • Advance the data pointer by one, and decrement the length by one, and send the data with your library write function.

Example - Discrete I2C Functions (Start/Stop/Write):

voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}

Example - STM32 HAL Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}

Example - PIC16/18 MCC Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}

Step-2: Create a Display Object

Define an ssd1306_display structure for your display. This object will represent your display, and all library functions will require it as their first argument:

staticstructssd1306_displaydisplay;

Step-3: Create a Buffer Array

Define a uint8_t array for your display. This array will serve as the internal buffer for your display. Use the macros in the header file to declare an array with the appropriate size according to your display type:

/* For 128x64 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
/* For 128x32 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_32];

Step-4: Initialize the Display

Initialize the ssd1306_display structure with the ssd1306_init() function. This will initialize both the structure and the physical display:

The arguments are:

  • Arg1: The address of your ssd1306_display structure.
  • Arg2: The 7-bit I2C address of your display.
  • Arg3: The Type of your display. Use the ssd1306_display_type enum from the header file:
    • SSD1306_DISPLAY_TYPE_32 for 128x32 displays.
    • SSD1306_DISPLAY_TYPE_64 for 128x64 displays.
  • Arg4: The address of your display_array.
  • Arg5: The address of your i2c_write function
/* 128x64 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* 128x32 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_32,
display_array,
i2c_write);

Example main.c Files

Below are example main.c files demonstrating the minimum code required to display a circle in the center of a 128x64 display with the I2C address 0x3C:

Note: For 128x32 displays, simply adjust the display initialization and the circle shape accordingly.

Example - Discrete I2C Functions (Start/Stop/Write):

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - STM32 HAL Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - PIC16/18 MCC Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}
voidmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}
img

Demo and Test Files

The library also includes demo and test animations:

  • Demo files include various cool animations that can be performed with the library.
  • Test files include lazily written test animations for each library function. These aren't unit tests, but simple animations.

Note: Instead of a manual setup like shown below, you have the option to put the entire repository into your project instead.

Demo Files Setup

  • Follow the Library Setup.
  • Navigate to the demo folder and copy the ssd1306_demo.c and ssd1306_demo.h into your project the same way.
  • Open the ssd1306_demo.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_demo.h in your source file and call one of the demo functions listed in the header file (all demo functions are infinite loops):

Note: Demo functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_demo.h"/* In your main.c after display initializations */ssd1306_demo_1(&display, 0);

Test Files Setup

  • Follow the Library Setup.
  • Navigate to the test folder and copy the ssd1306_test.c and ssd1306_test.h into your project the same way.
  • Open the ssd1306_test.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_test.h in your source file and call one of the test functions listed in the header file (all test functions are infinite loops):

Note: Test functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_test.h"/* In your main.c after display initializations */ssd1306_test_draw_shifts(&display, 0);
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Setup Guide

Microesque edited this page Mar 7, 2025 · 4 revisions

Overview


Library Setup

  • Download or clone the repository.
  • Navigate to the lib folder.
  • Copy the ssd1306.c and ssd1306.h into your project directory.
  • Include the ssd1306.h in your source file.
  • Set up your display by following the Display Setup below. See the Example main.c Files as well.
  • Use the provided library functions to test your display. Optionally you can use the demo or test animations.

Display Setup

Step-1: Create an I2C Callback

Define an I2C callback function with the following prototype:

voidi2c_write(uint8_t*data, uint16_tlength);

You'll need to either create an I2C library or adapt an existing one for your platform. Most embedded systems are shipped with hardware abstraction libraries that can be used with minimal tweaking as shown in the examples below.

Note: The first byte of the data passed to this function will always be the 8-bit I2C write address (i2c_address << 1) of the display. Note that this isn't the original 7-bit address but the I2C write command for that address. This is done to enable support for various I2C libraries, some of which don't have a sequential write or address-data separate write functions. If your I2C library sends the address separately:

  • Read the first data byte to get the address. If necessary, shift it to the right by one to get the 7-bit address.
  • Advance the data pointer by one, and decrement the length by one, and send the data with your library write function.

Example - Discrete I2C Functions (Start/Stop/Write):

voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}

Example - STM32 HAL Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}

Example - PIC16/18 MCC Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}

Step-2: Create a Display Object

Define an ssd1306_display structure for your display. This object will represent your display, and all library functions will require it as their first argument:

staticstructssd1306_displaydisplay;

Step-3: Create a Buffer Array

Define a uint8_t array for your display. This array will serve as the internal buffer for your display. Use the macros in the header file to declare an array with the appropriate size according to your display type:

/* For 128x64 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
/* For 128x32 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_32];

Step-4: Initialize the Display

Initialize the ssd1306_display structure with the ssd1306_init() function. This will initialize both the structure and the physical display:

The arguments are:

  • Arg1: The address of your ssd1306_display structure.
  • Arg2: The 7-bit I2C address of your display.
  • Arg3: The Type of your display. Use the ssd1306_display_type enum from the header file:
    • SSD1306_DISPLAY_TYPE_32 for 128x32 displays.
    • SSD1306_DISPLAY_TYPE_64 for 128x64 displays.
  • Arg4: The address of your display_array.
  • Arg5: The address of your i2c_write function
/* 128x64 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* 128x32 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_32,
display_array,
i2c_write);

Example main.c Files

Below are example main.c files demonstrating the minimum code required to display a circle in the center of a 128x64 display with the I2C address 0x3C:

Note: For 128x32 displays, simply adjust the display initialization and the circle shape accordingly.

Example - Discrete I2C Functions (Start/Stop/Write):

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - STM32 HAL Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - PIC16/18 MCC Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}
voidmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}
img

Demo and Test Files

The library also includes demo and test animations:

  • Demo files include various cool animations that can be performed with the library.
  • Test files include lazily written test animations for each library function. These aren't unit tests, but simple animations.

Note: Instead of a manual setup like shown below, you have the option to put the entire repository into your project instead.

Demo Files Setup

  • Follow the Library Setup.
  • Navigate to the demo folder and copy the ssd1306_demo.c and ssd1306_demo.h into your project the same way.
  • Open the ssd1306_demo.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_demo.h in your source file and call one of the demo functions listed in the header file (all demo functions are infinite loops):

Note: Demo functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_demo.h"/* In your main.c after display initializations */ssd1306_demo_1(&display, 0);

Test Files Setup

  • Follow the Library Setup.
  • Navigate to the test folder and copy the ssd1306_test.c and ssd1306_test.h into your project the same way.
  • Open the ssd1306_test.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_test.h in your source file and call one of the test functions listed in the header file (all test functions are infinite loops):

Note: Test functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_test.h"/* In your main.c after display initializations */ssd1306_test_draw_shifts(&display, 0);
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Setup Guide

Microesque edited this page Mar 7, 2025 · 4 revisions

Overview


Library Setup

  • Download or clone the repository.
  • Navigate to the lib folder.
  • Copy the ssd1306.c and ssd1306.h into your project directory.
  • Include the ssd1306.h in your source file.
  • Set up your display by following the Display Setup below. See the Example main.c Files as well.
  • Use the provided library functions to test your display. Optionally you can use the demo or test animations.

Display Setup

Step-1: Create an I2C Callback

Define an I2C callback function with the following prototype:

voidi2c_write(uint8_t*data, uint16_tlength);

You'll need to either create an I2C library or adapt an existing one for your platform. Most embedded systems are shipped with hardware abstraction libraries that can be used with minimal tweaking as shown in the examples below.

Note: The first byte of the data passed to this function will always be the 8-bit I2C write address (i2c_address << 1) of the display. Note that this isn't the original 7-bit address but the I2C write command for that address. This is done to enable support for various I2C libraries, some of which don't have a sequential write or address-data separate write functions. If your I2C library sends the address separately:

  • Read the first data byte to get the address. If necessary, shift it to the right by one to get the 7-bit address.
  • Advance the data pointer by one, and decrement the length by one, and send the data with your library write function.

Example - Discrete I2C Functions (Start/Stop/Write):

voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}

Example - STM32 HAL Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}

Example - PIC16/18 MCC Library:(Source)

voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}

Step-2: Create a Display Object

Define an ssd1306_display structure for your display. This object will represent your display, and all library functions will require it as their first argument:

staticstructssd1306_displaydisplay;

Step-3: Create a Buffer Array

Define a uint8_t array for your display. This array will serve as the internal buffer for your display. Use the macros in the header file to declare an array with the appropriate size according to your display type:

/* For 128x64 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
/* For 128x32 displays */staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_32];

Step-4: Initialize the Display

Initialize the ssd1306_display structure with the ssd1306_init() function. This will initialize both the structure and the physical display:

The arguments are:

  • Arg1: The address of your ssd1306_display structure.
  • Arg2: The 7-bit I2C address of your display.
  • Arg3: The Type of your display. Use the ssd1306_display_type enum from the header file:
    • SSD1306_DISPLAY_TYPE_32 for 128x32 displays.
    • SSD1306_DISPLAY_TYPE_64 for 128x64 displays.
  • Arg4: The address of your display_array.
  • Arg5: The address of your i2c_write function
/* 128x64 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* 128x32 display with the address 0x3C */ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_32,
display_array,
i2c_write);

Example main.c Files

Below are example main.c files demonstrating the minimum code required to display a circle in the center of a 128x64 display with the I2C address 0x3C:

Note: For 128x32 displays, simply adjust the display initialization and the circle shape accordingly.

Example - Discrete I2C Functions (Start/Stop/Write):

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
I2C1_Start();
for (uint16_ti=0; i<length; i++) {
I2C1_Write(data[i]);
}
I2C1_Stop();
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - STM32 HAL Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data;
HAL_I2C_Master_Transmit(&hi2c1, address, ++data, --length, 1000);
}
intmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}

Example - PIC16/18 MCC Library:

/* Other includes... */#include"ssd1306.h"/* I2C callback definition */voidi2c_write(uint8_t*data, uint16_tlength) {
/* Send display commands (first byte is 8-bit write address) */uint8_taddress=*data >> 1;
if (I2C1_Host.Write(address, ++data, --length)) {
uint8_twait_counter=100;
while (I2C1_Host.IsBusy()) {
I2C1_Host.Tasks();
wait_counter--;
}
}
}
voidmain(void) {
/* System setup... *//* Display initialization */staticstructssd1306_displaydisplay;
staticuint8_tdisplay_array[SSD1306_ARRAY_SIZE_64];
ssd1306_init(&display,
0x3C,
SSD1306_DISPLAY_TYPE_64,
display_array,
i2c_write);
/* Draw a circle at (64, 32) with a radius of 30 */ssd1306_draw_circle(&display, 64, 32, 30);
ssd1306_display_update(&display);
while (1);
}
img

Demo and Test Files

The library also includes demo and test animations:

  • Demo files include various cool animations that can be performed with the library.
  • Test files include lazily written test animations for each library function. These aren't unit tests, but simple animations.

Note: Instead of a manual setup like shown below, you have the option to put the entire repository into your project instead.

Demo Files Setup

  • Follow the Library Setup.
  • Navigate to the demo folder and copy the ssd1306_demo.c and ssd1306_demo.h into your project the same way.
  • Open the ssd1306_demo.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_demo.h in your source file and call one of the demo functions listed in the header file (all demo functions are infinite loops):

Note: Demo functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_demo.h"/* In your main.c after display initializations */ssd1306_demo_1(&display, 0);

Test Files Setup

  • Follow the Library Setup.
  • Navigate to the test folder and copy the ssd1306_test.c and ssd1306_test.h into your project the same way.
  • Open the ssd1306_test.h and update the include path for the ssd1306.h:
/* Original */#include"../ssd1306.h"/* Change to */#include"ssd1306.h"
  • Include the ssd1306_test.h in your source file and call one of the test functions listed in the header file (all test functions are infinite loops):

Note: Test functions take a display object and an arbitrary delay number. Read the function descriptions.

#include"ssd1306_test.h"/* In your main.c after display initializations */ssd1306_test_draw_shifts(&display, 0);