Skip to the content
PCBKitNew board
2 layers79.3 × 59.8 mmController, the printed circuit board in 3D

Display is een liteon De 8 segementen worden in volgorde aan gestuurd met een freq van 500uS Welke segmenten verlicht worden gaat met digit 1 - 4

Size
79.3 × 59.8 mm
Copper layers
2
Thickness
1.6 mm
Parts
74
Nets
169
Pads
452
Tracks, vias
323, 54
Pours
5
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
6 Apr 2026
Updated
5 Jul 2026

Overview

Controller is an open-source printed circuit board by Anderman, from the Anderman/Renovent repository on GitHub. It is a 2-layer board of 79.3 × 59.8 mm with 74 parts on 169 nets, routed with 323 tracks and 54 vias.

It is built around the ESP32-S3-MINI-1-N8, SN74LVC245APW and AP63203WU, with the SCD41-D-R2, WS2812B-2020 and BSS138 among its other parts. Its parts include 21 capacitors, 14 connectors, 13 resistors, 9 ICs and 5 diodes. It belongs with the ESP32 boards of this library.

Main components

9

README

readme.md

Renovent

Installatie Screenshot

Installatie connector aan flatkabel Co2 sensor plaatsen

Web interface

homepage debug

homeassistant

History Controls Sensors

software documentatie

De originele controller is een display met toetsen en 1 IC De IC zet een 3 bit counter om in 8 select lijnen van het display.

Display is een liteon De 8 segementen worden in volgorde aan gestuurd met een freq van 500uS Welke segmenten verlicht worden gaat met digit 1 - 4

Het programma zal dus het continue het display moeten uitlezen en wat er op staat omzetten in een 4 char array. Hiervan met gebruik gemaakt worden van mapping om een 8 bit array om te zetten in een Char. Waarschijnlijk kan de DP los en hebben we een 7 bitarray naar char mapping nodig.

De switches werken als volgt

Er is 1 output Key_node. sw1 (OK) = key_node=1 als C=1 (counter=1) Sw2 (+ ) = key_node=1 als D=1 (counter=5) Sw3 (F ) = key_node=1 als E=1 (counter=6) Sw4 (- ) = key_node=1 als DP=1 (counter=3)

ESP32 aansluiting

In het ESP32-schema worden de relevante signalen van de originele controller eerst via een SN74LVC245 naar 3V3 gebracht. De ESP32 ziet dus alleen de 3V3-varianten van deze signalen.

Ingangen voor het uitlezen van display en toetsen

  • BIT0 -> BIT0_3V3 -> GPIO35
  • BIT1 -> BIT1_3V3 -> GPIO36
  • BIT2 -> BIT2_3V3 -> GPIO37
  • Digit1 -> Digit1_3V3 -> GPIO38
  • Digit2 -> Digit2_3V3 -> GPIO39
  • Digit3 -> Digit3_3V3 -> GPIO40
  • Digit4 -> Digit4_3V3 -> GPIO41
  • KEY_NODE -> KEY_NODE_3V3 -> GPIO42

Deze acht ingangen zijn voldoende om het gemultiplexte display en de toetsstatus te reconstrueren.

Uitgang voor toets simulatie

  • KEY_DOWN <- GPIO43

KEY_DOWN gaat via een BSS138-transistor naar de originele schakeling. Daarmee kan de ESP32 een toetsdruk simuleren zonder direct 5V op een GPIO te zetten.

Overige aansluitingen op het ESP32-bord

  • SDA_1 -> GPIO7
  • SCL_1 -> GPIO8
  • LED -> GPIO12

Aanpak in software

De displaycontroller loopt elke 500 us door de 8 segment-selects. De software leest dus niet "digit 1", daarna "digit 2", enzovoort, maar leest per segment-select in een keer de toestand van alle 4 digitlijnen.

Concreet:

  1. BIT0, BIT1 en BIT2 vormen samen een tellerwaarde van 0..7.
  2. Die tellerwaarde bepaalt welk segment op dat moment actief is.
  3. Tegelijk wordt gekeken welke van Digit1..Digit4 hoog zijn.
  4. Voor het actieve segment wordt dat bit gezet in alle digits die op dat moment hoog zijn.
  5. Na 8 select-stappen is er een compleet 4-digit frame opgebouwd.

De mapping van de tellerwaarde naar segment is:

BIT2 BIT1 BIT0indexsegment
0 0 00A
0 0 11C
0 1 02B
0 1 13DP
1 0 04F
1 0 15D
1 1 06E
1 1 17G

Schematisch ziet een volledige scan er zo uit:

mermaid
flowchart LR
	A[GPIO snapshot] --> B[Lees BIT0..2]
	B --> C[Select-index 0..7]
	C --> D[Segment voor deze stap kiezen]
	D --> E{Lees Digit1..4 in dezelfde snapshot}
	E --> F[Zet dit ene segment in digit 1..4 als die hoog zijn]
	F --> G[Werk lopend frame bij]
	G --> H{Zijn alle 8 select-stappen gezien?}
	H -- nee --> A
	H -- ja --> I[4 complete digitmasks klaar]
	I --> J[Zet digitmasks om naar displaytekst]

Eén interrupt-snapshot doet dus niet alles. Per snapshot gebeurt maar dit:

  • bepaal welk segment nu actief is via BIT0..2
  • lees tegelijk welke van de 4 digitlijnen actief zijn
  • zet dat ene segment in de digits die op dat moment hoog zijn

Pas nadat dit 8 keer gebeurd is, hebben we voor alle 4 digits een volledig segmentmasker.

Je kunt het ook zo lezen: we lezen niet "4 displays na elkaar", maar per segment in een keer alle 4 displays.

Voorbeeld:

  • BIT2..0 = 000 betekent segment A
  • als op dat moment Digit1 en Digit3 hoog zijn, dan krijgt digit 1 en digit 3 het segment A
  • bij de volgende select-stap wordt bijvoorbeeld segment C op dezelfde manier verdeeld over de 4 digits
  • na alle 8 segmenten kennen we van elke digit het volledige segmentmasker

KEY_NODE wordt in diezelfde scan meegelezen. Een actieve key tijdens een specifieke select-index betekent een specifieke toets.

Interrupt of polling

De huidige implementatie gebruikt juist een interrupt op BIT0.

Waarom:

  • de select-bits veranderen snel genoeg dat polling onnodig veel jitter gaf
  • de reader wil alle relevante lijnen op exact hetzelfde moment samplen
  • daarom leest de ISR direct een volledige GPIO-snapshot en reconstrueert daaruit de actuele select-index, digitlijnen en KEY_NODE

De implementatie in src/display_reader.cpp werkt zo:

  1. BIT0 triggert onBit0ChangeInterrupt() op elke flank.
  2. De ISR leest direct GPIO.in1.val, zodat alle ingangssignalen uit hetzelfde tijdsmoment komen.
  3. Uit BIT0..2 wordt de verwachte select-index bepaald.
  4. Als een select-stap ontbreekt of de volgorde niet klopt, wordt het huidige frame weggegooid.
  5. Na select 7 is een volledig frame klaar.
  6. De hoofdloop publiceert pas een frame als twee opeenvolgende complete frames gelijk zijn.

Daardoor is de reader robuuster tegen timingglitches en worden half-opgebouwde displaybeelden niet gepubliceerd.

Huidige softwarebasis

Er is nu een eerste ESP32 software-opzet toegevoegd in de map src.

  • src/main.cpp start WiFi, de webserver en de display reader.
  • src/wifiSetup.* gebruikt WiFiManager, net als in het andere project.
  • src/display_reader.* leest BIT0..2, Digit1..4 en KEY_NODE in en bouwt daar een stabiel displayframe van op.
  • src/webui/webui.* publiceert een simpele HTTP API en serveert statische bestanden uit SPIFFS.
  • data/index.html is een eenvoudige debugpagina.

Webinterface

Na boot:

  • hoofd-UI op poort 80
  • WiFiManager portal op poort 8080

Beschikbare endpoints:

  • GET /api/status
  • POST /api/keydown

/api/status geeft onder andere terug:

  • gedecodeerde displaytekst
  • actieve toets op basis van KEY_NODE
  • WiFi-status

PlatformIO

Er is ook een partitions/default.csv toegevoegd zodat de SPIFFS data-partitie beschikbaar is voor de webpagina.

Voor lokaal gebruik zijn deze commando's relevant:

  1. platformio run
  2. platformio run --target buildfs
  3. platformio run --target uploadfs
  4. platformio run --target upload

OTA artifacts lokaal bouwen

De automatische firmware-update leest OTA-bestanden uit release/firmware, release/spiffs en release/latest.json.

Deze artifacts worden lokaal gegenereerd door scripts/generate_build_info.py, dat als PlatformIO build hook meeloopt. De hook:

  • berekent een aparte hash voor src en data
  • bewaart per component precies een markerbestand *.hash in src en ui-hashes
  • schrijft alleen een nieuwe build-id als de hash van die component gewijzigd is
  • kopieert de nieuwe .bin naar release/firmware of release/spiffs
  • werkt daarna release/latest.json bij

Voor een volledige lokale OTA release bouw je beide artifacts:

  1. platformio run -e esp32s3mini_ota
  2. platformio run -e esp32s3mini_ota -t buildfs

Daarna kun je de bijgewerkte bestanden in release/ zelf committen of op een andere manier publiceren, zolang release/latest.json en de bijbehorende .bin bestanden bereikbaar blijven voor de ESP32.

Backtrace decoderen

Een ESP32-S3 backtrace uit de WebUI of seriele output kun je direct tegen de actuele firmware-ELF symboliseren met:

powershell
.\scripts\decode_backtrace.ps1 "0x4037EF71 -> 0x40377C96 -> 0x40376AEF"

Het script gebruikt standaard:

  • .pio/build/esp32s3mini_ota/firmware.elf
  • de PlatformIO xtensa-esp32s3-elf-addr2line.exe

Belangrijk: decode altijd tegen de ELF van dezelfde firmware-build als waarmee de crash is ontstaan, anders kloppen functies en regelnummers mogelijk niet.

Parts

74
QtyValueFootprintReferences
6100nFCapacitor_SMD:C_0201_0603MetricC6, C25, C31, C32, C33, C34
647Resistor_SMD:R_0603_1608MetricR24, R25, R26, R27, R28, R29
510KResistor_SMD:R_0402_1005MetricR1, R2, R3, R6, R21
4100uFCapacitor_SMD:C_1206_3216MetricC4, C5, C29, C30
4Conn_01x06123:PinSocket_1x06_P2.00mm_Vertical_female_C7499363J4, J5, J6, J7
4Conn_01x06123:PinHeader_1x06_P2.00mm_Vertical_male_C706993J8, J9, J10, J11
4MountingHole123:MountingHole_2.5mmH1, H2, H3, H5
322nFCapacitor_SMD:C_0603_1608MetricC26, C27, C28
3INA238Package_SO:VSSOP-10_3x3mm_P0.5mmU23, U24, U25
2100nFCapacitor_SMD:C_0603_1608MetricC2, C3
210KResistor_SMD:R_0603_1608MetricR22, R23
210uFCapacitor_SMD:C_1210_3225MetricC21, C22
2Conn_01x04Connector_JST:JST_PH_S4B-PH-SM4-TB_1x04-1MP_P2.00mm_HorizontalJ2, J3
2ESP32-S3-MINI-1PCM_Espressif:ESP32-S3-MINI-1U1, U21
2TC2030Connector:Tag-Connect_TC2030-IDC-NL_2x03_P1.27mm_VerticalJ1, J22
2WS2812B-2020123:LED_WS2812B-2020_2x2.2mmD1, D21
1100nFCapacitor_SMD:C_0402_1005MetricC23
11uFCapacitor_SMD:C_0603_1608MetricC24
122uFCapacitor_SMD:C_0805_2012MetricC1
14.7uFCapacitor_SMD:C_0603_1608MetricC7
14.7uHInductor_SMD:L_Bourns-SRN4018L1
147uHInductor_SMD:L_APV_ANR5040L21
1AP63203WUPackage_TO_SOT_SMD:TSOT-23-6U2
1BSS138Package_TO_SOT_SMD:SOT-23Q1
1Conn_01x06Connector_JST:JST_PH_S6B-PH-SM4-TB_1x06-1MP_P2.00mm_HorizontalJ23
1Conn_02x07_Odd_Even123:IDC-Header_2x07_P2.54mm_VerticalX1
1L7983123:TDFN-10-1EP_3x3mm_P0.5mmU22
1MountingHole123:MountingHole_7mmH4
1SCD41-D-R2Sensor:Sensirion_SCD4x-1EP_10.1x10.1mm_P1.25mm_EP4.8x4.8mmU3
1SMBJ64ADiode_SMD:D_SMBD22
1SN74LVC245APWPackage_SO:TSSOP-20_4.4x6.5mm_P0.65mmU5
1SS14Diode_SMD:D_SMAD23
1SS510Diode_SMD:D_SMAD24
1Terminal_block_2pTerminalBlock_Phoenix:TerminalBlock_Phoenix_MKDS-1-2-3.81_1x02_P3.81mm_HorizontalJ21
1fuseFuse:Fuse_1812_4532MetricF21

The 72 most common of 74 parts.

Questions

How big is the Controller PCB?

It measures 79.3 × 59.8 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Controller use?

74 parts, built around the ESP32-S3-MINI-1-N8, SN74LVC245APW, AP63203WU and SCD41-D-R2. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Controller KiCad files?

From the Anderman/Renovent repository on GitHub, at the commit this page was made from: the board is Hardware/Esp32/Controller/Controller.kicad_pcb and its schematic Hardware/Display/Display.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Controller design in my own project?

Its repository states no licence, so its author keeps all rights: ask Anderman before reusing the design.

More from Anderman/Renovent

1
  • 2 layersSensor, the printed circuit board in 3D

    Sensor

    Anderman/Renovent

    Display is een liteon De 8 segementen worden in volgorde aan gestuurd met een freq van 500uS Welke segmenten verlicht worden gaat met digit 1 - 4

    16 parts

Similar boards

  • 2 layers22 × 53.5 mmIsolated RS485 Bridge, the printed circuit board in 3D

    Isolated RS485 Bridge

    Anderman/tombask

    All message send Slave can send after a poll frame. Slave is ready sending when the last padding byte is 0x55 To write byte 0x08 must be 0x02

    22 parts
  • 4 layers110 × 175 mmPrinter Mainboard, the printed circuit board in 3D

    Printer Mainboard

    NEOgHacking/SCORPION-MAX-V1

    4x Power Mosfets for controlling heated beds, heaters, ext.

    286 parts3
  • 6 layers56.6 × 33.7 mmBattery, the printed circuit board in 3D

    Battery

    86kkd/millionBoard

    Amazing 500million sensor enetric skateboard use body center of gravity to control !!!

    143 parts
  • 4 layers100 × 80 mmCharge board, the printed circuit board in 3D

    Charge board

    Franzelfx/vertical-wind-turbine

    Design study: a 3D-printed vertical-axis wind turbine on a timber post, charging a 3S Li-ion pack. Parts, circuit and figures generated by scripts with FreeCAD, KiCad and Blender. Nothing built yet.

    85 parts
  • 2 layers116.8 × 116.8 mmBentoboard, the printed circuit board in 3D

    Bentoboard

    torbers/bentoboard

    as many ready-to-use electronics as i could fit on a 4"x4" PCB.

    381 parts
  • 2 layers63 × 99 mmBionxBatteryBoard, the printed circuit board in 3D

    BionxBatteryBoard

    William-Yen/Bionx-3rdParty-BMS

    A supplemental PCB to retrofit a Bionx e-bike battery pack with a 3rd-party BMS

    144 partsGPL-3.0
  • 4 layers90 × 70 mmDst-01x4, the printed circuit board in 3D

    Dst-01x4

    alxhub/arc

    Addy's Railroad Company

    172 parts
  • 2 layers71.5 × 71.5 mmEsp32-venmar hrv, the printed circuit board in 3D

    Esp32-venmar hrv

    oskirby/esp32-venmar-hrv

    ESPHome Controller for Venmar HRV

    41 partsMIT