Heltec V4 (TFT)
The first colour panel and the first amplified front end in this firmware, and the first 16 MB board. The pin map has one published source — the board definition in the open-source firmware it ships with (variants/esp32s3/heltec_v4, the TFT build) — rather than the two this project prefers, so the panel, touch, button and sounder pins are unverified; the LoRa pins are the V3's and carry more weight. The front end is the part with no equivalent elsewhere here: the radio is deaf and mute until the amplifier rail is powered and its mode pins are driven, and which of two parts is fitted is read off GPIO 2 at boot. Native USB, so it enumerates as an Espressif JTAG/serial device with its MAC in the by-id name and none of the CP2102 ambiguity the rest of this bench has. OTG runs the composite device: CDC-ACM console plus CDC-NCM networking, the same stack the T3-S3s carry — note the by-id name changes to the RetiMesh identity once this firmware boots.
No photograph is published for this exact variant. Heltec's WiFi LoRa 32 V4 carries a 0.96" OLED; this build targets the TFT model, whose only published pin map is the board's own shipped firmware.
The pin map below is drawn from this board's own header in the firmware, so it is right whether or not a picture is.
01 Hardware
| Vendor | Heltec |
| PlatformIO env | heltec-v4 |
| Board header | src/boards/heltec_v4.h |
| MCU | ESP32-S3: 16 MB flash, 2 MB PSRAM in package |
| Chip family | ESP32-S3 |
| Radio | SX1262 (TCXO, DIO2 drives the RF switch) behind a GC1109 or KCT8103L front end |
| Display | 2.4" 240x320 ST7789 with a CHSC6X touch layer |
| Extras | two buttons + case power button (charger /QON), DA217 accelerometer, BQ25896-ready charging state, battery ADC, GNSS on the expansion header; expansion slots for sounder/sensors (no SD) |
| Host links | Wi-Fi access point + station · USB CDC-NCM Ethernet · native USB console |
| Flashing | esptool can reset the chip through this port |
02 Radio
| Transceiver | Semtech SX1262 |
| Radio family | SX126x |
| As the registry states it | SX1262 (TCXO, DIO2 drives the RF switch) behind a GC1109 or KCT8103L front end |
| TCXO | 1.8 V reference |
| DIO2 drives the RF switch | yes |
| Default channel | 869.525 MHz · BW 125 kHz · SF8 · CR 4/5 · 7 dBm inherited from Config.h |
| SPI bus | FSPI |
Every node on a channel must agree on frequency, bandwidth, spreading factor,
coding rate and sync word. These are the defaults this build ships with; they are changed
live on the node's settings page, which prints the matching RNodeInterface block.
03 Pin map
Read straight out of src/boards/heltec_v4.h — every peripheral
the firmware drives on this board, and the GPIO it drives it on. A harness diagram, not a
picture of where the parts sit.
Every pin as a table, with the define it comes from
| Peripheral | Signal | GPIO | Define | Note |
|---|---|---|---|---|
| Radio | SCK | GPIO 9 | PIN_LORA_SCK | |
| MISO | GPIO 11 | PIN_LORA_MISO | ||
| MOSI | GPIO 10 | PIN_LORA_MOSI | ||
| CS | GPIO 8 | PIN_LORA_CS | ||
| RST | GPIO 12 | PIN_LORA_RST | ||
| BUSY | GPIO 13 | PIN_LORA_BUSY | ||
| DIO1 | GPIO 14 | PIN_LORA_DIO1 | ||
| RF front end | PWR | GPIO 7 | PIN_FEM_POWER | LDO enable for the FEM rail |
| EN | GPIO 2 | PIN_FEM_ENABLE | CSD on both parts: high to run | |
| MODE·GC1109 | GPIO 46 | PIN_FEM_MODE_GC1109 | CPS: high = full PA, low = bypass | |
| MODE·KCT | GPIO 5 | PIN_FEM_MODE_KCT | CTX: high = TX / RX bypass, low = RX LNA | |
| TFT panel | SCK | GPIO 17 | PIN_TFT_SCK | |
| MOSI | GPIO 33 | PIN_TFT_MOSI | ||
| CS | GPIO 15 | PIN_TFT_CS | ||
| DC | GPIO 16 | PIN_TFT_DC | ||
| RST | GPIO 18 | PIN_TFT_RST | ||
| BL | GPIO 21 | PIN_TFT_BL | ||
| Touch layer | SDA | GPIO 47 | PIN_TOUCH_SDA | |
| SCL | GPIO 48 | PIN_TOUCH_SCL | ||
| RST | GPIO 44 | PIN_TOUCH_RST | ||
| GNSS | RX | GPIO 39 | PIN_GPS_RX | |
| TX | GPIO 38 | PIN_GPS_TX | ||
| EN | GPIO 34 | PIN_GPS_EN | ||
| RST | GPIO 42 | PIN_GPS_RST | low for >100 ms resets an L76K | |
| PPS | GPIO 41 | PIN_GPS_PPS | ||
| STBY | GPIO 40 | PIN_GPS_STANDBY | high forces the receiver awake | |
| I²C bus | SDA | GPIO 4 | PIN_I2C_SDA | |
| SCL | GPIO 3 | PIN_I2C_SCL | ||
| Power | VBAT | GPIO 1 | PIN_BATTERY_ADC | |
| VBAT·EN | GPIO 37 | PIN_BATTERY_ADC_EN | ||
| Controls & indicators | BTN | GPIO 0 | PIN_BUTTON | PRG/BOOT, the navigation key |
| BTN2 | GPIO 35 | PIN_BUTTON2 | ||
| BUZZ | GPIO 6 | PIN_BUZZER |
04 Firmware support
What this build actually drives on this board. Where a part is fitted but left alone, the firmware's own reason is quoted underneath rather than summarised.
| Capability | State | Detail |
|---|---|---|
| Reticulum transport | driven | Path table, announce propagation, hop-by-hop forwarding |
| Wi-Fi AP + captive portal | driven | Status page, neighbours, bulletin board, settings |
| TCP 4242 + AutoInterface | driven | Stock RNS clients, zero-config discovery |
| LoRa radio | driven | Semtech SX1262 |
| Radio self-test at boot | driven | Proves the IRQ line on first boot A transmit at boot, timed against the interrupt. Worth more here than on any board so far: with the front end unpowered the chip still answers over SPI and still reports itself online, and the failure is silence |
| RF front end | driven | Driven before the radio can hear anything The front end. This is the part that has no equivalent on any other board here: an SX1262 wired straight to an antenna works with nothing driven, while this one is deaf and mute until the amplifier is powered and told which way to face. See src/radio/LoRaFem.h for the sequence and for why the board is asked at boot which of two parts it carries |
| External PA | driven | — An amplifier is fitted, which this firmware reports rather than compensates for: RF_TX_DBM is what the chip is driven at, here as on the SX1280+PA board, and the operator accounts for the gain. That gain is not a constant — the part compresses, so it falls from about 11 dB at low drive to 7 dB at the top (GC1109; the KCT8103L starts at 13 dB). The tables are in LoRaFem.h. The default drive is left at the firmware's usual 7 dBm, which through this front end leaves the antenna at roughly 18 dBm. That is inside the 500 mW allowance of the 869.4-869.65 MHz sub-band the default channel sits in, and it is over the 25 mW allowed in most of the rest of EU868 — so a channel change on this board is a power decision as well as a frequency one |
| Display | driven | TFT · 240×320 |
| Backlight control | driven | — |
| Touch layer | driven | — The touch layer is a CHSC6X on its own I2C bus, away from everything else |
| Keyboard | no | On its own microcontroller, over I²C |
| Trackball | no | — |
| microSD | no | Reticulum store moves onto the card when one is present |
| GNSS | driven | 9600 baud The published pin map is explicit that the receiver (9600 baud) is part of the V4 expansion kit rather than of the board itself. This build assumes the kit is fitted, because the bench unit has one; a bare V4 wants HAS_GPS 0 |
| Real-time clock | no | Seeds the system clock at boot |
| Power management IC | no | — |
| Battery gauge | driven | — The cell is read through a divider that is only connected while GPIO 37 is held high — the same arrangement the V3 has and the reason the V3 reports no battery at all. Reading the pin without raising the control line returns a plausible number that is not the battery, which is why the enable is part of the board description rather than something the reader assumes. The ratio is not the usual halving: this board divides deep and trims the result, 4.9 * 1.045, and reads it at 2.5 dB attenuation rather than the 11 dB the other boards use — which is what a divider this deep needs to keep the reading inside the converter's range |
| IMU | driven | DA217 a DA217; the panel follows the hand |
| Magnetometer | no | — |
| Environment sensor | no | — |
| Sounder | driven | — A piezo sounder on a PWM channel — not an audio path. The pin is the published map's; the bench unit produced no sound from it at any drive while everything else worked, so the part may not be fitted on all builds of the board. Driving it costs nothing either way |
| USB networking (CDC-NCM) | driven | The node is an Ethernet link with DHCP over the cable |
| PPP over the serial bridge | no | — |
05 Bench notes
verified on hardware: radio through the KCT8103L front end (TX and RX on air), GNSS fix + clock, panel, touch, both buttons; sounder silent — possibly not fitted. The DA217 accelerometer is suspended while the screen is dark and comes back with it — a dark panel needs no orienting — and `STATUS` reports it as `imu=asleep`; the suspend register value is the kernel da280 driver's and has not yet been exercised on this board, so that line is what confirms it took.
06 Install
Browser
Pick Heltec V4 (TFT) in the web flasher and click Install. Desktop Chrome or Edge, over HTTPS.
Terminal
pipx run --spec "git+https://github.com/dobrevit/RetiMesh_Node#subdirectory=tools/retimesh-flash" \ retimesh-flash install --board heltec-v4
From source
pio run -e heltec-v4 pio run -e heltec-v4 -t upload pio run -e heltec-v4 -t uploadfs