1 # Migrating from the v1 API to the v2 API
3 lcdgfx evolved from the older `ssd1306` library. The v2 API
4 (under `src/v2/`) is the preferred entry point — it is the only API
5 that supports colour displays (TFT, SSD1331, SSD1351), `NanoCanvas`
6 templates parameterised by colour depth, and the modern `NanoEngine`.
8 This guide is a side-by-side cheatsheet for projects originally written
9 against the legacy v1 (`ssd1306.h` style) API, and for v1 patterns that
10 still appear in older examples.
12 > **TL;DR**: Include `lcdgfx.h`, instantiate a `Display…` object, call
13 > `display.begin()`, and use member functions instead of free functions.
14 > Pixel coordinates and font handles are unchanged.
18 | v1 (legacy) | v2 (current) |
20 | `#include "ssd1306.h"` | `#include "lcdgfx.h"` |
21 | `#include "nano_gfx.h"` | included transitively from `lcdgfx.h` |
22 | `#include "nano_engine.h"` | included transitively from `lcdgfx.h` |
23 | `#include "intf/i2c/ssd1306_i2c.h"` | not needed — bus selection is via the display class name |
24 | `#include "ssd1306_console.h"` | included transitively from `lcdgfx.h` |
25 | `#include "menu.h"` | `#include "lcdgfx_gui.h"` |
27 ## Display construction
29 | v1 (free functions, mutates global state) | v2 (member functions on a Display object) |
31 | `ssd1306_128x64_i2c_init();` | `DisplaySSD1306_128x64_I2C display(-1);` then `display.begin();` |
32 | `ssd1306_128x64_spi_init(rstPin, ces, dc);` | `DisplaySSD1306_128x64_SPI display(rstPin, {-1, ces, dc, 0, -1, -1});` then `display.begin();` |
33 | `il9163_128x128_spi_init(rst, ces, dc);` | `DisplayIL9163_128x128x16_SPI display(rst, {-1, ces, dc, 0, -1, -1});` |
34 | `ssd1331_96x64_spi_init(rst, ces, dc);` | `DisplaySSD1331_96x64x16_SPI display(rst, {-1, ces, dc, 0, -1, -1});` |
36 The v2 display class name encodes the controller, resolution, and (for
37 colour controllers) the bit depth. See
38 [docs/controller_matrix.md](controller_matrix.md) for the full list.
42 All the pixel coordinates, colour conventions, and font handles are
43 identical between v1 and v2. The only change is that you call them on
44 the `display` object instead of as free functions.
48 | `ssd1306_clearScreen()` | `display.clear()` |
49 | `ssd1306_fillScreen(0xFF)` | `display.fill(0xFF)` |
50 | `ssd1306_putPixel(x, y)` | `display.putPixel(x, y)` |
51 | `ssd1306_drawLine(x1, y1, x2, y2)` | `display.drawLine(x1, y1, x2, y2)` |
52 | `ssd1306_drawRect(x1, y1, x2, y2)` | `display.drawRect(x1, y1, x2, y2)` |
53 | `ssd1306_drawHLine(x1, y1, x2)` | `display.drawHLine(x1, y1, x2)` |
54 | `ssd1306_drawVLine(x1, y1, y2)` | `display.drawVLine(x1, y1, y2)` |
55 | `ssd1306_drawBitmap(x, y, w, h, bmp)` | `display.drawBitmap1(x, y, w, h, bmp)` (mono) |
56 | `ssd1306_drawXBitmap(x, y, w, h, bmp)` | `display.drawXBitmap(x, y, w, h, bmp)` |
57 | `ssd1306_setColor(c)` | `display.setColor(c)` |
58 | `ssd1306_negativeMode()` / `ssd1306_positiveMode()` | `display.invertColors()` / `display.normalColors()` (semantics preserved) |
60 For colour displays, prefer the explicit-depth variants:
61 `drawBitmap1` (1 bpp), `drawBitmap4` (4 bpp), `drawBitmap8` (8 bpp),
62 `drawBitmap16` (16 bpp).
68 | `ssd1306_setFixedFont(ssd1306xled_font6x8)` | `display.setFixedFont(ssd1306xled_font6x8)` |
69 | `ssd1306_printFixed(0, 8, "hi", STYLE_NORMAL)` | `display.printFixed(0, 8, "hi", STYLE_NORMAL)` |
70 | `ssd1306_printFixedN(0, 8, "BIG", STYLE_NORMAL, FONT_SIZE_2X)` | `display.printFixedN(0, 8, "BIG", STYLE_NORMAL, FONT_SIZE_2X)` |
71 | `ssd1306_setFont6x8(...)` *(deprecated even in v1)* | use `setFixedFont` with a 6x8 font handle |
73 Font binaries themselves (`ssd1306xled_font6x8`, `digital_font5x7`,
74 etc.) are unchanged. The only runtime difference is that v2 stores the
75 active font on the `display` object rather than as a global.
77 ## Display modes / control
81 | `ssd1306_displayOff()` / `ssd1306_displayOn()` | `display.getInterface().displayOff()` / `displayOn()` *(controller-dependent — see capability matrix)* |
82 | `ssd1306_setContrast(level)` | `display.getInterface().setContrast(level)` |
83 | `ssd1306_flipHorizontal(1)` / `ssd1306_flipVertical(1)` | `display.getInterface().flipHorizontal(1)` / `flipVertical(1)` |
84 | `ssd1306_setStartLine(n)` | `display.getInterface().setStartLine(n)` *(mono OLEDs only)* |
86 The `getInterface()` call returns a reference to the controller-specific
87 implementation, which exposes only the operations that controller
88 actually supports. See `docs/controller_matrix.md`.
90 ## NanoCanvas (offscreen buffer)
92 v2 introduces depth-parameterised canvases.
96 | `NanoCanvas1 canvas(W, H, buf);` | `NanoCanvas<W,H,1> canvas;` (template) or `NanoCanvas1 canvas(W,H,buf)` (still available) |
97 | `NanoCanvas8 canvas(W, H, buf);` | `NanoCanvas<W,H,8> canvas;` |
98 | `ssd1306_drawCanvas(x, y, canvas);` | `display.drawCanvas(x, y, canvas);` |
100 The template form sizes the buffer at compile time (no manual
101 `buf[W*H/8]` array), which is the recommended pattern for new code.
103 ## NanoEngine (sprite / tile engine)
105 v1's `NanoEngine` was tied to monochrome SSD1306. v2 generalises it
106 across all controllers.
110 | `NanoEngine<TILE_8x8_MONO> engine;` | `NanoEngine1<DisplaySSD1306_128x64_I2C> engine(display);` |
111 | `engine.begin(); engine.refresh(); engine.display();` | identical method names |
112 | `engine.canvas.drawRect(...)` | `engine.canvas.drawRect(...)` (canvas type matches the display) |
113 | `engine.insertSprite(x, y, w, h, bmp);` | identical signature |
115 The integer suffix on the engine class (`NanoEngine1`, `NanoEngine8`,
116 `NanoEngine16`) selects the colour depth.
118 ## Menu / GUI widgets
120 | v1 (`menu.h`) | v2 (`lcdgfx_gui.h`) |
122 | `SAppMenu menu; ssd1306_createMenu(&menu, items, count);` | `LcdGfxMenu menu(items, count);` |
123 | `ssd1306_showMenu(&menu);` | `menu.show(display);` |
124 | `ssd1306_menuDown(&menu);` | `menu.down();` |
125 | `ssd1306_menuUp(&menu);` | `menu.up();` |
126 | `ssd1306_menuSelection(&menu);` | `menu.selection();` |
128 v2 additionally ships `LcdGfxCheckboxMenu`, `LcdGfxButton`, and
129 `LcdGfxYesNo` — see `examples/gui/`.
133 - **Two displays in one sketch.** v1's free-function API made this
134 impossible. v2 supports it — just instantiate two display objects.
135 - **Forgetting `display.begin()`.** v1's `*_init()` did this implicitly
136 on first call; v2 requires an explicit `begin()`.
137 - **Mixing v1 and v2 headers.** Don't include both `ssd1306.h` and
138 `lcdgfx.h` in the same translation unit. Pick one.
139 - **Colour displays and `setColor`.** The `RGB_COLOR8` and
140 `RGB_COLOR16` macros (and, soon, the `Color` helper in
141 `src/canvas/color.h`) are the supported ways to compose values for
142 `setColor()` on colour controllers.
143 - **Rotation.** v1 had software rotation only. v2 colour displays use
144 hardware rotation via `setRotation(0..3)`. See the capability matrix
145 for which controllers support which.
147 ## Where to look next
149 - `examples/` — every example in the repo uses the v2 API.
150 - [docs/controller_matrix.md](controller_matrix.md) — per-controller
152 - `src/lcdgfx.h` and `src/lcdgfx_gui.h` — top-level entry headers.
153 - `src/v2/` — implementation. Note that `src/v2/lcd/<controller>/` is
154 auto-generated; edit templates in `tools/templates/lcd/<controller>/`
155 and re-run the code generator.