Contact Sales & After-Sales Service

Contact & Quotation

  • Inquire: Call 0086-755-23203480, or reach out via the form below/your sales contact to discuss our design, manufacturing, and assembly capabilities.
  • Quote: Email your PCB files to Sales@pcbsync.com (Preferred for large files) or submit online. We will contact you promptly. Please ensure your email is correct.
Drag & Drop Files, Choose Files to Upload You can upload up to 3 files.

Notes:
For PCB fabrication, we require PCB design file in Gerber RS-274X format (most preferred), *.PCB/DDB (Protel, inform your program version) format or *.BRD (Eagle) format. For PCB assembly, we require PCB design file in above mentioned format, drilling file and BOM. Click to download BOM template To avoid file missing, please include all files into one folder and compress it into .zip or .rar format.

Adafruit GFX Library: Graphics on Any Display

What is the Adafruit GFX Library?

The Adafruit GFX Library is a hardware-independent graphics core that provides a common set of graphics primitives—lines, circles, rectangles, text rendering, and bitmap display—that work identically across dozens of different display types. Think of it as an abstraction layer that sits between your application code and the hardware-specific display drivers.

The beauty of this architecture becomes apparent when you need to switch from an SSD1306 OLED to an ST7789 TFT display. Instead of rewriting all your graphics code, you simply change one include file and the display constructor. Everything else remains identical.

Core Architecture and Design Philosophy

The Adafruit GFX Library uses object-oriented inheritance to separate hardware-specific functions from generic graphics operations. The Adafruit_GFX base class defines all the drawing functions, while hardware-specific classes like Adafruit_SSD1306 or Adafruit_ST7735 inherit from this base and implement the low-level pixel manipulation.

This design means you always work with two libraries:

  1. Adafruit_GFX.h – The graphics core with all drawing functions
  2. Hardware-specific library – The driver for your particular display

Supported Display Types and Compatibility

The Adafruit GFX Library ecosystem supports an extensive range of displays. Here’s what you need to know about compatibility:

Common Display Controllers

Display TypeControllerResolution ExamplesInterfaceColor Depth
Monochrome OLEDSSD1306128×64, 128×32I2C, SPI1-bit (B/W)
Color OLEDSSD133196×64SPI16-bit (65K)
Small TFTST7735128×160, 160×128SPI16-bit (65K)
Medium TFTST7789240×240, 240×320SPI16-bit (65K)
Large TFTILI9341240×320SPI16-bit (65K)
Nokia LCDPCD854484×48SPI1-bit (B/W)
E-PaperVarious200×200, 296×128SPI1-bit or 3-color

Hardware-Specific Libraries

For each display controller, you’ll need its companion library:

  • Adafruit_SSD1306 – Monochrome OLEDs (most common small displays)
  • Adafruit_ST7735 – 1.8″ color TFT displays
  • Adafruit_ST7789 – 1.3″, 1.54″, 2.0″ color TFT displays
  • Adafruit_ILI9341 – 2.4″, 2.8″, 3.2″ color TFT displays
  • Adafruit_SSD1331 – 0.96″ color OLED
  • Adafruit_PCD8544 – Nokia 5110/3310 LCD
  • RGBmatrixPanel – LED matrix panels

The Arduino Library Manager handles dependencies automatically, but if you’re installing manually, always install both Adafruit_GFX and Adafruit_BusIO along with your display-specific library.

Installation and Setup

Using Arduino Library Manager (Recommended)

The easiest installation method uses the Arduino IDE’s built-in Library Manager:

  1. Open Arduino IDE
  2. Navigate to Sketch → Include Library → Manage Libraries
  3. Search for your display driver (e.g., “SSD1306”)
  4. Click Install
  5. Dependencies (Adafruit_GFX, Adafruit_BusIO) install automatically

Manual Installation

If you need the latest development version:

  1. Download from Adafruit GFX GitHub
  2. Extract to Arduino/libraries/Adafruit_GFX
  3. Download Adafruit BusIO
  4. Extract to Arduino/libraries/Adafruit_BusIO
  5. Download your display-specific library
  6. Restart Arduino IDE

Basic Setup Code Structure

#include <Adafruit_GFX.h>     // Core graphics library

#include <Adafruit_SSD1306.h>  // Hardware-specific library

#define SCREEN_WIDTH 128

#define SCREEN_HEIGHT 64

#define OLED_RESET    -1  // Reset pin (-1 if sharing Arduino reset)

#define SCREEN_ADDRESS 0x3C

// Create display object

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {

  // Initialize display

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {

    Serial.println(F(“SSD1306 allocation failed”));

    for(;;); // Loop forever

  }

  // Clear the buffer

  display.clearDisplay();

  display.display();

}

Essential Graphics Functions

The Adafruit GFX Library provides a comprehensive set of drawing primitives. Here’s what you need to know about each category.

Pixel-Level Operations

// Set individual pixel

display.drawPixel(x, y, COLOR);

// Get pixel color (useful for collision detection)

uint16_t color = display.getPixel(x, y);

The coordinate system starts at (0,0) in the top-left corner, with X increasing to the right and Y increasing downward.

Line Drawing

// Draw line from (x0,y0) to (x1,y1)

display.drawLine(x0, y0, x1, y1, COLOR);

// Optimized horizontal line

display.drawFastHLine(x, y, width, COLOR);

// Optimized vertical line

display.drawFastVLine(x, y, height, COLOR);

For performance-critical applications, always use drawFastHLine() and drawFastVLine() when possible—they’re significantly faster than drawLine() for straight lines.

Shape Drawing Functions

FunctionParametersDescription
drawRect()x, y, w, h, colorRectangle outline
fillRect()x, y, w, h, colorFilled rectangle
drawCircle()x, y, radius, colorCircle outline
fillCircle()x, y, radius, colorFilled circle
drawRoundRect()x, y, w, h, radius, colorRounded rectangle outline
fillRoundRect()x, y, w, h, radius, colorFilled rounded rectangle
drawTriangle()x0, y0, x1, y1, x2, y2, colorTriangle outline
fillTriangle()x0, y0, x1, y1, x2, y2, colorFilled triangle

Complete Shape Examples

// Draw various shapes

display.clearDisplay();

// Rectangle

display.drawRect(10, 10, 50, 30, WHITE);

// Filled circle

display.fillCircle(64, 32, 15, WHITE);

// Rounded rectangle

display.drawRoundRect(80, 10, 40, 30, 5, WHITE);

// Triangle

display.drawTriangle(20, 50, 30, 60, 40, 50, WHITE);

display.display(); // Update screen

Text Rendering Capabilities

Text rendering is where the Adafruit GFX Library really shines. Understanding fonts and text positioning is crucial for creating professional interfaces.

Built-in Classic Font

The library includes a basic 5×7 pixel font that requires no additional memory:

display.setTextSize(1);      // Normal 1:1 pixel scale

display.setTextColor(WHITE); // Draw white text

display.setCursor(0, 0);     // Top-left position

display.print(“Hello World”);

// Can print various data types

display.print(1234.56);

display.println(0xDEADBEEF, HEX);

Text Size and Scaling

// Text size multipliers (1-10)

display.setTextSize(1); // 5×7 pixels per character

display.setTextSize(2); // 10×14 pixels (2x scale)

display.setTextSize(3); // 15×21 pixels (3x scale)

Note that text scaling uses simple pixel multiplication—larger sizes can look blocky. For better quality at larger sizes, use custom fonts.

Custom Font Support

The library supports TrueType font conversion through included tools:

#include <Fonts/FreeSans9pt7b.h>

#include <Fonts/FreeSansBold12pt7b.h>

// Set custom font

display.setFont(&FreeSans9pt7b);

display.setCursor(10, 20); // Note: baseline positioning with custom fonts

display.print(“Custom Font”);

// Return to classic font

display.setFont(); // or display.setFont(NULL);

Available Font Families

The library includes three font families derived from GNU FreeFont:

Font Comparison Table

FamilyStyleSizes AvailableCharacter
FreeMonoMonospace (Courier-like)9pt, 12pt, 18pt, 24ptFixed width
FreeSansSans-serif (Arial-like)9pt, 12pt, 18pt, 24ptVariable width
FreeSerifSerif (Times-like)9pt, 12pt, 18pt, 24ptVariable width

Each family also includes Bold, Italic, and BoldItalic variants.

Critical Font Positioning Difference

Classic font: Cursor position is top-left of text Custom fonts: Cursor position is the text baseline (bottom of characters)

// Classic font – cursor at top-left

display.setFont();

display.setCursor(0, 0); // Text starts at very top

// Custom font – cursor at baseline

display.setFont(&FreeSans9pt7b);

display.setCursor(0, 0); // Text would be ABOVE screen!

display.setCursor(0, 10); // Correct – gives room above baseline

Color Management Across Display Types

Color handling varies significantly between display types, and understanding this is critical for portable code.

Monochrome Displays (1-bit)

#define BLACK 0

#define WHITE 1

#define INVERSE 2  // XOR with current pixel

display.drawPixel(x, y, WHITE);

display.fillRect(0, 0, 64, 32, BLACK); // Erase area

Color Displays (16-bit)

Most color TFT displays use 565 RGB format (5 bits red, 6 bits green, 5 bits blue):

// Predefined colors

#define BLACK   0x0000

#define BLUE    0x001F

#define RED     0xF800

#define GREEN   0x07E0

#define CYAN    0x07FF

#define MAGENTA 0xF81F

#define YELLOW  0xFFE0

#define WHITE   0xFFFF

// Create custom colors

uint16_t color = display.color565(r, g, b); // r,g,b are 0-255

Color Conversion Example

// Convert 24-bit RGB to 16-bit 565 format

uint16_t rgb_to_565(uint8_t r, uint8_t g, uint8_t b) {

  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);

}

// Use in your code

uint16_t purple = rgb_to_565(128, 0, 128);

display.fillCircle(64, 32, 20, purple);

Bitmap and Image Display

Displaying bitmaps requires converting images to appropriate formats and storing them efficiently.

Bitmap Format Requirements

Bitmaps must be stored in program memory (PROGMEM) as byte arrays:

const unsigned char logo_bmp[] PROGMEM = {

  0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,

  0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,

  // … bitmap data continues

};

Drawing Bitmaps

// Draw bitmap from PROGMEM

display.drawBitmap(x, y, bitmap_data, width, height, color);

// Example

#define LOGO_WIDTH  16

#define LOGO_HEIGHT 16

display.drawBitmap(

  (SCREEN_WIDTH  – LOGO_WIDTH ) / 2,  // Center X

  (SCREEN_HEIGHT – LOGO_HEIGHT) / 2,  // Center Y

  logo_bmp,

  LOGO_WIDTH,

  LOGO_HEIGHT,

  WHITE

);

Image Conversion Tools

For converting images to bitmap arrays:

Online Tool: Image2Code GIMP: Can export .xbm format directly Custom Python Scripts: For batch processing

Performance Optimization Techniques

Graphics performance can make or break user experience, especially on slower microcontrollers.

Display Buffer Management

Understanding buffering is critical:

Buffered Displays (SSD1306, PCD8544):

  • Entire screen stored in RAM
  • Drawing operations modify RAM buffer
  • Must call display.display() to update screen
  • Can draw complex scenes then update once

Unbuffered Displays (Most TFT):

  • Drawing operations immediately write to screen
  • No RAM buffer overhead
  • Can’t easily preview before display
  • Partial screen updates more visible

Optimization Strategies

// BAD – Multiple display() calls

for(int i = 0; i < 100; i++) {

  display.fillRect(i, 0, 2, 64, WHITE);

  display.display(); // Slow! Repeated updates

}

// GOOD – Single display() call

for(int i = 0; i < 100; i++) {

  display.fillRect(i, 0, 2, 64, WHITE);

}

display.display(); // Fast! Single update

// BETTER – Use faster primitives

display.fillRect(0, 0, 100, 64, WHITE); // Much faster than loop

Memory Usage Considerations

Display Buffer Sizes

DisplayResolutionBuffer Size
SSD1306128×641024 bytes
SSD1306128×32512 bytes
PCD854484×48504 bytes
ST7735128×1600 bytes (unbuffered)

For memory-constrained projects on Arduino Uno (2KB RAM), larger buffered displays can be problematic. Consider:

  • Using smaller displays
  • Switching to unbuffered TFT displays
  • Upgrading to boards with more RAM (ESP32, Arduino Mega)

Advanced Features and Techniques

Display Rotation

// Rotate display orientation

display.setRotation(0); // Default (USB port on left)

display.setRotation(1); // 90° clockwise

display.setRotation(2); // 180°

display.setRotation(3); // 270° clockwise

// Width/height swap with rotation

int16_t w = display.width();  // Accounts for rotation

int16_t h = display.height(); // Accounts for rotation

Rotation is especially useful when mounting displays at different angles in enclosures.

Text Wrapping and Positioning

// Enable automatic text wrapping (default: on)

display.setTextWrap(true);

// Disable wrapping for scrolling text

display.setTextWrap(false);

// Get cursor position

int16_t x = display.getCursorX();

int16_t y = display.getCursorY();

// Get text bounds (for centering)

int16_t x1, y1;

uint16_t w, h;

display.getTextBounds(“Hello”, 0, 0, &x1, &y1, &w, &h);

// Center text

display.setCursor((SCREEN_WIDTH – w) / 2, (SCREEN_HEIGHT – h) / 2);

Custom Character Support (CP437)

The library supports extended ASCII (CP437) for symbols:

// Enable correct CP437 encoding

display.cp437(true);

// Print degree symbol

display.print(“Temperature: 25”);

display.write(0xF8); // Degree symbol

display.println(“C”);

// Print other symbols

display.write(0x94); // ö with umlaut

display.write(0xE0); // Greek alpha

Common Implementation Patterns

Creating a Custom Graphics Class

class MyDisplay {

private:

  Adafruit_SSD1306 display;

public:

  MyDisplay() : display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1) {}

  bool begin() {

    return display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  }

  void showSplash() {

    display.clearDisplay();

    display.setTextSize(2);

    display.setTextColor(WHITE);

    display.setCursor(10, 20);

    display.println(“My Device”);

    display.display();

    delay(2000);

  }

  void updateStatus(float temp, float humidity) {

    display.clearDisplay();

    display.setTextSize(1);

    display.setCursor(0, 0);

    display.print(“Temp: “);

    display.print(temp, 1);

    display.write(0xF8); // degree symbol

    display.println(“C”);

    display.print(“RH: “);

    display.print(humidity, 1);

    display.println(“%”);

    display.display();

  }

};

Multi-Screen UI Management

enum Screen {

  SCREEN_MAIN,

  SCREEN_SETTINGS,

  SCREEN_GRAPH

};

Screen currentScreen = SCREEN_MAIN;

void loop() {

  switch(currentScreen) {

    case SCREEN_MAIN:

      drawMainScreen();

      break;

    case SCREEN_SETTINGS:

      drawSettingsScreen();

      break;

    case SCREEN_GRAPH:

      drawGraphScreen();

      break;

  }

  // Handle button input to change screens

  if(buttonPressed()) {

    currentScreen = (Screen)((currentScreen + 1) % 3);

  }

}

Troubleshooting Common Issues

Display Not Initializing

Symptom: Display stays blank, begin() returns false

Solutions:

// Check I2C address (common alternatives: 0x3C or 0x3D)

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {

  // Try alternate address

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {

    Serial.println(“No display found!”);

  }

}

// Use I2C scanner to find address

#include <Wire.h>

Wire.begin();

Wire.beginTransmission(address);

if(Wire.endTransmission() == 0) {

  Serial.print(“Found device at 0x”);

  Serial.println(address, HEX);

}

Graphics Not Appearing

Symptom: Code runs but nothing displays

Solution: Always call display.display() for buffered displays:

display.clearDisplay();

display.drawLine(0, 0, 127, 63, WHITE);

// display.display(); // MISSING – Nothing will show!

display.display(); // REQUIRED for SSD1306 and similar

Library Conflicts

Symptom: Compilation errors about conflicting declarations

Solution: Ensure all libraries are updated to compatible versions:

Arduino IDE → Tools → Manage Libraries

Update: Adafruit GFX Library

Update: Adafruit BusIO

Update: Your display-specific library

Out of Memory Errors

Symptom: Sketch crashes or displays garbage

Solution: Display buffers consume significant RAM:

// Check free RAM

int freeRam() {

  extern int __heap_start, *__brkval;

  int v;

  return (int)&v – (__brkval == 0 ? (int)&__heap_start : (int)__brkval);

}

// If < 200 bytes available, you’re in trouble

// Solutions:

// 1. Use smaller display

// 2. Use unbuffered TFT

// 3. Upgrade to board with more RAM

// 4. Disable splash screen: #define SSD1306_NO_SPLASH

Resource Library for Adafruit GFX Development

Official Documentation and Repositories

Font Resources

Image Conversion Tools

Hardware Datasheets

  • SSD1306: 128×64 OLED controller datasheet
  • ST7735: Color TFT controller specifications
  • ST7789: Enhanced color TFT controller datasheet
  • ILI9341: High-resolution TFT controller reference

Example Projects and Code

  • Adafruit Product Tutorials: Specific guides for each display
  • Arduino Project Hub: Community projects using GFX
  • Instructables: Step-by-step GFX project guides
  • GitHub: Search “adafruit gfx” for hundreds of examples

Development Tools

  • Arduino IDE: Latest version with Library Manager
  • PlatformIO: Advanced IDE with better library management
  • Visual Studio Code: With Arduino extension for professional development
  • Serial Plotter: Built into Arduino IDE for graphing

Frequently Asked Questions

Q1: Can I use the Adafruit GFX Library with non-Adafruit displays?

Absolutely. The Adafruit GFX Library works with any display that has a compatible driver library, regardless of manufacturer. Many third-party displays use the same controllers (SSD1306, ST7735, etc.) as Adafruit products. Just make sure the driver library you’re using inherits from Adafruit_GFX. Chinese clone displays with SSD1306 controllers work perfectly with Adafruit_SSD1306 library. The key is matching the controller chip, not the brand. You might need to adjust I2C addresses or SPI pin configurations, but the graphics functions remain identical.

Q2: Why does my text look weird with custom fonts?

The most common issue is cursor positioning. Custom fonts use baseline positioning (bottom of characters) while the built-in font uses top-left positioning. If you set cursor to (0,0) with a custom font, the text renders above the visible screen. Always position the cursor at least the font height from the top. Use getTextBounds() to determine exact spacing needs. Also remember that custom fonts are bitmaps at specific sizes—scaling them with setTextSize() looks blocky. For best results, use fonts at their designed size or convert multiple sizes of the same font.

Q3: How do I choose between I2C and SPI for my display?

I2C uses fewer pins (just 2: SDA and SCL) but is slower—good for simple interfaces that update infrequently. Maximum I2C speed is typically 400kHz (fast mode) or 1MHz (fast-mode plus). SPI requires more pins (4-5: MOSI, SCK, CS, DC, optionally RST) but is much faster—essential for animated graphics or frequent full-screen updates. SPI can run at 8MHz or higher. For small monochrome displays showing mostly static content, I2C is fine. For color TFT displays or animations, SPI is mandatory. Consider your pin count budget and update frequency when choosing. Many SSD1306 OLEDs support both interfaces.

Q4: My Arduino sketch won’t compile after adding the GFX library—what’s wrong?

This usually indicates missing dependencies or version mismatches. The Adafruit GFX Library requires Adafruit_BusIO library as a dependency. If using Arduino Library Manager, it should install automatically. If installing manually, download and install Adafruit_BusIO separately. Also ensure your display-specific library (like Adafruit_SSD1306) is compatible with your GFX version—update all Adafruit libraries simultaneously. Another common issue is having old library versions in the libraries folder. Delete old libraries completely before installing new versions. Check that you’re including the correct header files and that your display constructor matches the library version you installed.

Q5: How can I improve graphics performance on my Arduino Uno?

Several strategies help. First, minimize calls to display.display() on buffered displays—draw all your graphics to the buffer, then update once. Use the fast horizontal and vertical line functions instead of general drawLine() when possible. Pre-calculate values outside loops rather than recalculating on every iteration. For TFT displays, consider using hardware SPI instead of software SPI—it’s 10x faster. Reduce text operations by only updating changed portions of the screen rather than clearing and redrawing everything. If you need high frame rates or complex animations, consider upgrading to a faster board like ESP32 or Arduino Due with more processing power and RAM. Finally, profile your code to identify bottlenecks—the display update itself might not be the slowest part.

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact Sales & After-Sales Service

Contact & Quotation

  • Inquire: Call 0086-755-23203480, or reach out via the form below/your sales contact to discuss our design, manufacturing, and assembly capabilities.

  • Quote: Email your PCB files to Sales@pcbsync.com (Preferred for large files) or submit online. We will contact you promptly. Please ensure your email is correct.

Drag & Drop Files, Choose Files to Upload You can upload up to 3 files.

Notes:
For PCB fabrication, we require PCB design file in Gerber RS-274X format (most preferred), *.PCB/DDB (Protel, inform your program version) format or *.BRD (Eagle) format. For PCB assembly, we require PCB design file in above mentioned format, drilling file and BOM. Click to download BOM template To avoid file missing, please include all files into one folder and compress it into .zip or .rar format.