Dit project beschrijft de ontwikkeling van een offline Wikipedia-lezer voor de ESP32-2432S028 ("Cheap Yellow Display") en de ESP32-C3. Het systeem maakt het mogelijk om volledige Wikipedia-databases, zoals de Simple English editie, te raadplegen vanaf een microSD-kaart zonder dat er een internetverbinding nodig is.
Belangrijkste aspecten van het project:
- Hardware: Het is compatibel met de CYD-module (ILI9341 touchscreen) en de ESP32-C3 in combinatie met een JC2432S024 displaymodule.
- Preprocessor: Omdat de ESP32 beperkt RAM-geheugen heeft, kan hij ZIM-bestanden niet direct lezen. Een Python-preprocessor converteert deze bestanden naar een optimaal binair formaat:
- Compressie wordt omgezet van zstd naar LZ4.
- Afbeeldingen worden omgezet van WebP naar JPEG of QOI.
- De complexe ZIM-index wordt vereenvoudigd naar een vaste-breedte index en een 'sparse index' die in het RAM past.
- Software: De firmware is gebouwd met PlatformIO en bevat een HTML-renderer voor het TFT-scherm, een on-screen QWERTY-toetsenbord en een zoekfunctie die zowel prefix-matching als full-text zoekopdrachten ondersteunt.
- Setup: Gebruikers moeten een ZIM-bestand downloaden, dit verwerken met het Python-script en de resulterende bestanden in een
/wiki/ map op een FAT32-geformatteerde SD-kaart plaatsen.
Offline Wikipedia-lezer voor ESP32 CYD
Geschreven door Alun Morris en Claude Code.
Hardware
Optie 1 — ESP32-2432S028 ("Cheap Yellow Display")
| Component | Detail |
| Board | ESP32-2432S028 (CYD) |
| Display | 320×240 ILI9341 (HSPI bus) |
| Touch | XPT2046 resistief (gedeelde HSPI) |
| SD-kaart | VSPI bus — CS=5, MOSI=23, MISO=19, SCK=18 |
| Achtergrondverlichting | GPIO 21 |
Gebruik de PlatformIO-omgeving cyd (pio run -e cyd -t upload).
Optie 2 — ESP32-C3 + JC2432S024 displaymodule
De JC2432S024 is een losse 2.4″ 320×240 ILI9341 displaymodule met XPT2046 resistieve touch en een SD-kaartsleuf. Deze heeft geen ingebouwde processor — verbind deze met een ESP32-C3 dev board (zoals de SuperMini of DevKitM-1).
De ESP32-C3 heeft één enkele SPI-peripheral, waardoor het display, de SD-kaart en de touch-controller allemaal één SPI-bus delen met aparte chip-select-lijnen.
| Module pin | ESP32-C3 GPIO | Notities |
| SCK | 4 | Gedeeld door TFT + Touch + SD |
| MOSI / SDI / TDIN / SDMOSI | 6 | Gedeeld |
| MISO / SDO / TDO / SDMISO | 5 | Gedeeld |
| CS (TFT) | 7 | |
| DC / RS | 1 | |
| RST | 3V3 | Hoog aansluiten — wordt niet aangestuurd door firmware |
| SD_CS | 10 | |
| T_CS | 3 | |
| T_IRQ | 8 | PENIRQ — idle HIGH, veilig op bootstrapping pin |
| LED / BL (backlight) | 0 | Of direct op 3V3 aansluiten voor altijd aan zijnde verlichting |
| VCC | 3V3 | |
| GND | GND | |
Vermijd GPIO 2 en GPIO 9 voor externe belastingen — dit zijn ESP32-C3 bootstrapping-pinnen. Gebruik de PlatformIO-omgeving c3 (pio run -e c3 -t upload).
Algemene hardware-opmerkingen
- Eerste boot: De touch-kalibratie wordt automatisch uitgevoerd. Tik op de twee rode kruislijnen wanneer daarom wordt gevraagd. De kalibratie wordt opgeslagen in het flashgeheugen en overgeslagen bij volgende boots.
- SD-kaart: Een microSD-kaart van minimaal 8 GB is vereist (Simple English Wikipedia neemt ongeveer 7 GB in beslag op de kaart).
Keuze van een ZIM-bestand
De database wordt gebouwd vanuit een Kiwix ZIM-bestand. Deze kunnen worden gedownload via de Wikimedia dumps.
Aanbevolen: Simple English Wikipedia — wikipediaensimpleallmaxi_YYYY-MM.zim
- Downloadgrootte: ~3.3 GB, bevat ~285.000 artikelen.
- Kortere artikelen en eenvoudigere taal — zeer geschikt voor een klein scherm.
- Bevat afbeeldingen (
_maxi variant).
- Verwerkte grootte is ongeveer 10 GB.
Andere ZIM-bestanden werken ook, maar grotere edities (bijv. de volledige Engelse versie van ~90 GB) kunnen de maximale SD-kaartgrootte overschrijden die de CYD ondersteunt (32 GB is OK, 64 GB kan werken).
Kies de maxi variant (inclusief afbeeldingen). De mini variant laat afbeeldingen weg en bevat slechts de top 50-100k artikelen. In de preprocessor map staat een kleine demo-Wiki over knopen.
Preprocessor
De preprocessor converteert een ZIM-bestand naar het binaire databaseformaat dat door de firmware wordt gelezen.
Waarom een preprocessor nodig is
De ESP32 kan een ZIM-bestand niet direct lezen vanwege verschillende harde beperkingen:
- Compressie: ZIM gebruikt zstd cluster-compressie. Het decompresseren van een zstd cluster vereist dat het hele cluster in het RAM wordt geladen. ZIM-clusters zijn doorgaans 1–4 MB, wat de bruikbare heap van de ESP32 (~300 KB) overschrijdt. De preprocessor comprimeert elk artikel individueel met LZ4, wat slechts enkele KB aan werkgeheugen vereist voor decompressie.
- Indexstructuur: De indexstructuur van ZIM is te complex voor embedded gebruik. ZIM gebruikt een URL-gesorteerde B-tree-stijl index met entries van variabele lengte. De hier geproduceerde binaire index heeft een vaste breedte (80 bytes per record), is gesorteerd op genormaliseerde titel en is gekoppeld aan een kleine "sparse index" (één entry per 64 artikelen) die volledig in het RAM past (~7 KB). Samen maken ze het mogelijk om titels op te zoeken zonder SD-seeks om het begin van de scan te vinden.
- Afbeeldingsformaten: Afbeeldingen moeten in formaten zijn die de ESP32 kan decoderen. De firmware decodeert JPEG via de hardware-versnelde
TJpgDec bibliotheek en QOI via een lichtgewicht software-decoder. ZIM slaat afbeeldingen intern op als WebP, wat de ESP32 niet gegarandeerd in het beschikbare RAM kan decoderen. De preprocessor converteert alles naar JPEG (foto's) of QOI (diagrammen/SVGs).
- HTML-opschoning: Wikipedia ZIM-bestanden voegen boilerplate footers, navigatie-elementen en complexe class-structuren toe aan elk artikel. De preprocessor verwijdert deze met
BeautifulSoup, zodat de minimale HTML-renderer van de firmware alleen de subset van tags hoeft te verwerken die daadwerkelijk in artikelteksten voorkomen.
Waarom de verwerkte map groter is dan het ZIM-bestand
- Afbeeldingscodering: ZIM gebruikt WebP-afbeeldingen, wat extreem efficiënt is. De preprocessor decodeert WebP en codeert dit opnieuw als JPEG (foto's) of QOI (diagrammen). QOI is lossless en behoudt elke pixel, wat goed is voor de kwaliteit maar veel groter is dan WebP. JPEG met een kwaliteit van 90 is eveneens groter dan WebP bij een gelijkwaardige visuele kwaliteit.
- Compressieverlies: ZIM gebruikt cross-artikel zstd-compressie. Artikelen worden in grote clusters (1–4 MB) gepakt en samen gecomprimeerd, waardoor herhaalde zinnen en boilerplate over verschillende artikelen heen worden weggefilterd. De preprocessor comprimeert elk artikel individueel met LZ4, waardoor deze cross-artikel redundantie verloren gaat. LZ4 is gekozen vanwege de decompressiesnelheid op de ESP32, niet vanwege de compressieratio.
Vereisten
- Python 3.9+
- Afhankelijkheden (vermeld in
preprocessor/requirements.txt):
pip install libzim lz4 beautifulsoup4 lxml Pillow cairosvg qoi
cairosvg vereist daarnaast de systeem-cairo bibliotheek:
- Ubuntu/Debian:
sudo apt install libcairo2
- macOS:
brew install cairo
De build uitvoeren
cd preprocessor
python3 build_wiki_db.py <input.zim> <output_dir>
Voorbeeld:
python3 build_wiki_db.py --thumb-size 240x159 wikipedia_en_simple_all_maxi_2026-05.zim output_en_simple_all_maxi
Dit proces doorloopt twee fasen:
- Pass 1: Indexeert alle artikeltitels en bouwt
index.bin, sparseindex.bin en idindex.bin.
- Pass 2: Decomprimeert, schoont op (verwijdert ZIM boilerplate) en comprimeert artikelen parallel, wat resulteert in
articles_NNNN.dat chunks.
- Afbeeldingen: Rendert en codeert thumbnails naar
img_NNNN.dat chunks.
- Woordindex: Bouwt
wordindex.bin + titleindex.bin voor full-text "contains" zoekopdrachten.
De bouwtijd is ongeveer 30–60 minuten op een moderne PC (gebruikt standaard tot 4 CPU-cores).
Opties
| Vlag | Standaard | Beschrijving |
--limit N | 0 (alle) | Verwerk alleen de eerste N artikelen (handig voor testen) |
--workers N | auto | Aantal parallelle compressie-workers (threads) |
--thumb-size WxH | 320x212 | Maximale afmetingen van thumbnails in pixels |
--jpeg-quality Q | 90 | JPEG-kwaliteit voor fotothumbnails, 1–95 |
--no-images | off | Sla beeldverwerking over |
--images-only | off | Bouw alleen de beeldendatabase opnieuw |
--word-index-only | off | Bouw alleen de woord/titel index opnieuw |
--verbose | off | Extra voortgangsoutput |
Output-bestanden
Alle bestanden komen in de <output_dir>/ terecht en moeten worden gekopieerd naar een wiki/ map op de root van de SD-kaart.
| Bestand | Beschrijving |
index.bin | Vaste-breedte titelindex (binair doorzoekbaar, gesorteerd) |
sparse_index.bin | Elke 64e titelkey — geladen in ESP32 RAM voor snelle zoekacties |
id_index.bin | Mapt artikel ID → chunk + offset + lengte |
index_meta.txt | Metadata: aantal artikelen, chunk-grootte, databasenaam |
articles_NNNN.dat | LZ4-gecomprimeerde artikel HTML, gesplitst in chunks van 32 MB |
img_index.bin | Mapt afbeelding ID → chunk + offset + lengte |
img_NNNN.dat | Gecodeerde afbeelding-thumbnails (JPEG of QOI), gesplitst in chunks van 4 MB |
word_index.bin | Woord → lijst met artikel ID's voor "contains" zoekopdrachten |
title_index.bin | Artikeltitel-index voor "contains" zoekopdrachten |
SD-kaart Setup
- Formatteer de kaart als FAT32. Een allocatie-eenheid van 64KB is optimaal.
- Maak een map
wiki/ aan op de root.
- Kopieer alle bestanden uit de
<output_dir>/ naar /wiki/.
De mappenstructuur moet er als volgt uitzien: /wiki/
index.bin
sparse_index.bin
id_index.bin
index_meta.txt
articles_0000.dat
articles_0001.dat
- ...
img_index.bin
img_0000.dat
- ...
word_index.bin
title_index.bin
Firmware Build & Upload
De firmware is een PlatformIO-project.
cd firmware
pio run -t upload
Monitor de seriële output op 115200 baud:
pio device monitor
Bij de eerste boot wordt de sparse index gecached naar LittleFS, zodat volgende boots sneller verlopen.
Gebruik
- Zoeken: Tik op het zoekveld om het toetsenbord te tonen. Typ een zoekterm en druk op GO. Resultaten op basis van prefix-matching verschijnen eerst; een "contains:" scheidingsteken markeert de full-text matches.
- Navigeren: Tik op een blauwe onderstreepte link om deze te volgen. Tik op
< BACK om terug te keren.
- Scrollen: Swipe omhoog/omlaag, of gebruik de pijlknoppen in de navigatiebalk.
- Afbeeldingen: Tik op een afbeelding-thumbnail om deze op volledig scherm te bekijken.
Projectstructuur
firmware/ (PlatformIO ESP32 firmware)
src/main.cpp: Boot, splash screen.
src/ui.cpp: Zoek-, artikel- en beeldweergaven.
src/wiki_db.cpp: Toegang tot de SD-database (zoeken, laden, afbeeldingen).
src/html_render.cpp: HTML → TFT renderer.
src/display.cpp: TFT helpers, UTF-8 transliteratie.
src/keyboard.cpp: On-screen QWERTY-toetsenbord.
src/touch.cpp: XPT2046 touch-driver.
src/config.h: Hardware-pinnen, bestandspaden, constanten.
preprocessor/ (PC-side database builder)
buildwikidb.py: Hoofdscript voor de build (ZIM → binaire DB).
debug_server.py: Lokale HTTP-server voor browser-gebaseerde preview.
outputenknots_maxi/: Klein voorbeeld van een wiki met kleinere afbeeldingen om de grootte te beperken.
Offline Wikipedia-lezer voor ESP32 CYD
Geschreven door Alun Morris en Claude Code.
Hardware
Optie 1 — ESP32-2432S028 ("Cheap Yellow Display")
| Component | Detail |
| Board | ESP32-2432S028 (CYD) |
| Display | 320×240 ILI9341 (HSPI bus) |
| Touch | XPT2046 resistief (gedeelde HSPI) |
| SD-kaart | VSPI bus — CS=5, MOSI=23, MISO=19, SCK=18 |
| Achtergrondverlichting | GPIO 21 |
Gebruik de PlatformIO-omgeving cyd (pio run -e cyd -t upload).
Optie 2 — ESP32-C3 + JC2432S024 displaymodule
De JC2432S024 is een losse 2.4″ 320×240 ILI9341 displaymodule met XPT2046 resistieve touch en een SD-kaartsleuf. Deze heeft geen ingebouwde processor — verbind deze met een ESP32-C3 dev board (zoals de SuperMini of DevKitM-1).
De ESP32-C3 heeft één enkele SPI-peripheral, waardoor het display, de SD-kaart en de touch-controller allemaal één SPI-bus delen met aparte chip-select-lijnen.
| Module pin | ESP32-C3 GPIO | Notities |
| SCK | 4 | Gedeeld door TFT + Touch + SD |
| MOSI / SDI / TDIN / SDMOSI | 6 | Gedeeld |
| MISO / SDO / TDO / SDMISO | 5 | Gedeeld |
| CS (TFT) | 7 | |
| DC / RS | 1 | |
| RST | 3V3 | Hoog aansluiten — wordt niet aangestuurd door firmware |
| SD_CS | 10 | |
| T_CS | 3 | |
| T_IRQ | 8 | PENIRQ — idle HIGH, veilig op bootstrapping pin |
| LED / BL (backlight) | 0 | Of direct op 3V3 aansluiten voor altijd aan zijnde verlichting |
| VCC | 3V3 | |
| GND | GND | |
Vermijd GPIO 2 en GPIO 9 voor externe belastingen — dit zijn ESP32-C3 bootstrapping-pinnen. Gebruik de PlatformIO-omgeving c3 (pio run -e c3 -t upload).
Algemene hardware-opmerkingen
- Eerste boot: De touch-kalibratie wordt automatisch uitgevoerd. Tik op de twee rode kruislijnen wanneer daarom wordt gevraagd. De kalibratie wordt opgeslagen in het flashgeheugen en overgeslagen bij volgende boots.
- SD-kaart: Een microSD-kaart van minimaal 8 GB is vereist (Simple English Wikipedia neemt ongeveer 7 GB in beslag op de kaart).
Keuze van een ZIM-bestand
De database wordt gebouwd vanuit een Kiwix ZIM-bestand. Deze kunnen worden gedownload via de Wikimedia dumps.
Aanbevolen: Simple English Wikipedia — wikipediaensimpleallmaxi_YYYY-MM.zim
- Downloadgrootte: ~3.3 GB, bevat ~285.000 artikelen.
- Kortere artikelen en eenvoudigere taal — zeer geschikt voor een klein scherm.
- Bevat afbeeldingen (
_maxi variant).
- Verwerkte grootte is ongeveer 10 GB.
Andere ZIM-bestanden werken ook, maar grotere edities (bijv. de volledige Engelse versie van ~90 GB) kunnen de maximale SD-kaartgrootte overschrijden die de CYD ondersteunt (32 GB is OK, 64 GB kan werken).
Kies de maxi variant (inclusief afbeeldingen). De mini variant laat afbeeldingen weg en bevat slechts de top 50-100k artikelen. In de preprocessor map staat een kleine demo-Wiki over knopen.
Preprocessor
De preprocessor converteert een ZIM-bestand naar het binaire databaseformaat dat door de firmware wordt gelezen.
Waarom een preprocessor nodig is
De ESP32 kan een ZIM-bestand niet direct lezen vanwege verschillende harde beperkingen:
- Compressie: ZIM gebruikt zstd cluster-compressie. Het decompresseren van een zstd cluster vereist dat het hele cluster in het RAM wordt geladen. ZIM-clusters zijn doorgaans 1–4 MB, wat de bruikbare heap van de ESP32 (~300 KB) overschrijdt. De preprocessor comprimeert elk artikel individueel met LZ4, wat slechts enkele KB aan werkgeheugen vereist voor decompressie.
- Indexstructuur: De indexstructuur van ZIM is te complex voor embedded gebruik. ZIM gebruikt een URL-gesorteerde B-tree-stijl index met entries van variabele lengte. De hier geproduceerde binaire index heeft een vaste breedte (80 bytes per record), is gesorteerd op genormaliseerde titel en is gekoppeld aan een kleine "sparse index" (één entry per 64 artikelen) die volledig in het RAM past (~7 KB). Samen maken ze het mogelijk om titels op te zoeken zonder SD-seeks om het begin van de scan te vinden.
- Afbeeldingsformaten: Afbeeldingen moeten in formaten zijn die de ESP32 kan decoderen. De firmware decodeert JPEG via de hardware-versnelde
TJpgDec bibliotheek en QOI via een lichtgewicht software-decoder. ZIM slaat afbeeldingen intern op als WebP, wat de ESP32 niet gegarandeerd in het beschikbare RAM kan decoderen. De preprocessor converteert alles naar JPEG (foto's) of QOI (diagrammen/SVGs).
- HTML-opschoning: Wikipedia ZIM-bestanden voegen boilerplate footers, navigatie-elementen en complexe class-structuren toe aan elk artikel. De preprocessor verwijdert deze met
BeautifulSoup, zodat de minimale HTML-renderer van de firmware alleen de subset van tags hoeft te verwerken die daadwerkelijk in artikelteksten voorkomen.
Waarom de verwerkte map groter is dan het ZIM-bestand
- Afbeeldingscodering: ZIM gebruikt WebP-afbeeldingen, wat extreem efficiënt is. De preprocessor decodeert WebP en codeert dit opnieuw als JPEG (foto's) of QOI (diagrammen). QOI is lossless en behoudt elke pixel, wat goed is voor de kwaliteit maar veel groter is dan WebP. JPEG met een kwaliteit van 90 is eveneens groter dan WebP bij een gelijkwaardige visuele kwaliteit.
- Compressieverlies: ZIM gebruikt cross-artikel zstd-compressie. Artikelen worden in grote clusters (1–4 MB) gepakt en samen gecomprimeerd, waardoor herhaalde zinnen en boilerplate over verschillende artikelen heen worden weggefilterd. De preprocessor comprimeert elk artikel individueel met LZ4, waardoor deze cross-artikel redundantie verloren gaat. LZ4 is gekozen vanwege de decompressiesnelheid op de ESP32, niet vanwege de compressieratio.
Vereisten
- Python 3.9+
- Afhankelijkheden (vermeld in
preprocessor/requirements.txt):
pip install libzim lz4 beautifulsoup4 lxml Pillow cairosvg qoi
cairosvg vereist daarnaast de systeem-cairo bibliotheek:
- Ubuntu/Debian:
sudo apt install libcairo2
- macOS:
brew install cairo
De build uitvoeren
cd preprocessor
python3 build_wiki_db.py <input.zim> <output_dir>
Voorbeeld:
python3 build_wiki_db.py --thumb-size 240x159 wikipedia_en_simple_all_maxi_2026-05.zim output_en_simple_all_maxi
Dit proces doorloopt twee fasen:
- Pass 1: Indexeert alle artikeltitels en bouwt
index.bin, sparseindex.bin en idindex.bin.
- Pass 2: Decomprimeert, schoont op (verwijdert ZIM boilerplate) en comprimeert artikelen parallel, wat resulteert in
articles_NNNN.dat chunks.
- Afbeeldingen: Rendert en codeert thumbnails naar
img_NNNN.dat chunks.
- Woordindex: Bouwt
wordindex.bin + titleindex.bin voor full-text "contains" zoekopdrachten.
De bouwtijd is ongeveer 30–60 minuten op een moderne PC (gebruikt standaard tot 4 CPU-cores).
Opties
| Vlag | Standaard | Beschrijving |
--limit N | 0 (alle) | Verwerk alleen de eerste N artikelen (handig voor testen) |
--workers N | auto | Aantal parallelle compressie-workers (threads) |
--thumb-size WxH | 320x212 | Maximale afmetingen van thumbnails in pixels |
--jpeg-quality Q | 90 | JPEG-kwaliteit voor fotothumbnails, 1–95 |
--no-images | off | Sla beeldverwerking over |
--images-only | off | Bouw alleen de beeldendatabase opnieuw |
--word-index-only | off | Bouw alleen de woord/titel index opnieuw |
--verbose | off | Extra voortgangsoutput |
Output-bestanden
Alle bestanden komen in de <output_dir>/ terecht en moeten worden gekopieerd naar een wiki/ map op de root van de SD-kaart.
| Bestand | Beschrijving |
index.bin | Vaste-breedte titelindex (binair doorzoekbaar, gesorteerd) |
sparse_index.bin | Elke 64e titelkey — geladen in ESP32 RAM voor snelle zoekacties |
id_index.bin | Mapt artikel ID → chunk + offset + lengte |
index_meta.txt | Metadata: aantal artikelen, chunk-grootte, databasenaam |
articles_NNNN.dat | LZ4-gecomprimeerde artikel HTML, gesplitst in chunks van 32 MB |
img_index.bin | Mapt afbeelding ID → chunk + offset + lengte |
img_NNNN.dat | Gecodeerde afbeelding-thumbnails (JPEG of QOI), gesplitst in chunks van 4 MB |
word_index.bin | Woord → lijst met artikel ID's voor "contains" zoekopdrachten |
title_index.bin | Artikeltitel-index voor "contains" zoekopdrachten |
SD-kaart Setup
- Formatteer de kaart als FAT32. Een allocatie-eenheid van 64KB is optimaal.
- Maak een map
wiki/ aan op de root.
- Kopieer alle bestanden uit de
<output_dir>/ naar /wiki/.
De mappenstructuur moet er als volgt uitzien: /wiki/
index.bin
sparse_index.bin
id_index.bin
index_meta.txt
articles_0000.dat
articles_0001.dat
- ...
img_index.bin
img_0000.dat
- ...
word_index.bin
title_index.bin
Firmware Build & Upload
De firmware is een PlatformIO-project.
cd firmware
pio run -t upload
Monitor de seriële output op 115200 baud:
pio device monitor
Bij de eerste boot wordt de sparse index gecached naar LittleFS, zodat volgende boots sneller verlopen.
Gebruik
- Zoeken: Tik op het zoekveld om het toetsenbord te tonen. Typ een zoekterm en druk op GO. Resultaten op basis van prefix-matching verschijnen eerst; een "contains:" scheidingsteken markeert de full-text matches.
- Navigeren: Tik op een blauwe onderstreepte link om deze te volgen. Tik op
< BACK om terug te keren.
- Scrollen: Swipe omhoog/omlaag, of gebruik de pijlknoppen in de navigatiebalk.
- Afbeeldingen: Tik op een afbeelding-thumbnail om deze op volledig scherm te bekijken.
Projectstructuur
firmware/ (PlatformIO ESP32 firmware)
src/main.cpp: Boot, splash screen.
src/ui.cpp: Zoek-, artikel- en beeldweergaven.
src/wiki_db.cpp: Toegang tot de SD-database (zoeken, laden, afbeeldingen).
src/html_render.cpp: HTML → TFT renderer.
src/display.cpp: TFT helpers, UTF-8 transliteratie.
src/keyboard.cpp: On-screen QWERTY-toetsenbord.
src/touch.cpp: XPT2046 touch-driver.
src/config.h: Hardware-pinnen, bestandspaden, constanten.
preprocessor/ (PC-side database builder)
buildwikidb.py: Hoofdscript voor de build (ZIM → binaire DB).
debug_server.py: Lokale HTTP-server voor browser-gebaseerde preview.
outputenknots_maxi/: Klein voorbeeld van een wiki met kleinere afbeeldingen om de grootte te beperken.