Skip to content

About

OpenTherm proof of concept: KC1245 gateway (ESP32, Strux) and the PCB1246 OpenTherm modem (LPC11U68)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

18 Commits

Folders and files

Repository files navigation

KC-OT-Testbench

Test bench for OpenTherm on the KC1245 gateway and the PCB1246 OpenTherm plug-in board, built on the Strux framework. The goal is a rig that simulates both ends of the OpenTherm bus, a thermostat and a boiler, so OpenTherm devices and the gateway can be tested without real equipment. Work in progress. Lives at KooleControls/KC-OT-Testbench.

  • gateway/: ESP32 firmware for the KC1245 gateway. A copy of Strux at commit 3c2e4ca.
  • opentherm/: LPC11U68 firmware for the PCB1246 (bare metal, no RTOS, Strux-style). Laid out like the gateway: the board, the Strux command/settings/system managers, and the OpenTherm modem with its link to the gateway.

Each folder holds its full source; nothing is shared between the two.

Decided so far:

  • The LPC runs bare metal: one main loop, interrupts only set flags and fill buffers. No RTOS.
  • The gateway and the PCB1246 talk over the UART using the Strux channel protocol instead of KC2.
  • On the UART, each channel frame is COBS-framed with a CRC-16: 0x00 | COBS(frame | crc16) | 0x00. A frame that fails the check is dropped and counted. The code is lib/protocol/SerialFraming.h, meant to be the same file on both sides.
  • The PCB1246 is a modem and does not look inside a frame. Frames from either line go to the gateway on a stream the PCB1246 opens (opentherm stream); the gateway sends with opentherm send side=<thermostat|boiler> frame=<uint32>. Everything else is the gateway's.
  • The gateway keeps the PCB1246's firmware up to date. A release builds opentherm/ first and links its .bin into the gateway app, so one gateway OTA updates both boards. At boot, ModuleFirmwareManager resets the module into its ISP bootloader and compares the 32-byte image info at 0x300 (version, length, CRC-32, written by tools/lpc_image_info.py) with the image it carries. On a mismatch it flashes, with page 0 written last. module status / module update; the module.update setting turns the boot check off.
  • The gateway's end of the modem link is ModuleLinkManager. It runs the same framing and handshake as the module, sends opentherm send requests, and records the module's frame stream, plus what it sent, in a ring of the last 256 frames. The web UI's OpenTherm page polls that ring with module frames after=<seq>, decodes each frame for display (frontend/src/lib/opentherm.ts), and can compose and send one. The module's UART is shared with ModuleFirmwareManager under its lock; after every ISP session the link starts over.
  • How the thermostat and boiler simulation works is still open.

Build

Gateway, board pcb1245, with ESP-IDF 6.0:

cd gateway
idf.py -DBOARD=pcb1245 set-target esp32
idf.py -DBOARD=pcb1245 build

OpenTherm board, board pcb1246, with the Arm GNU Toolchain (arm-none-eabi-gcc, on PATH or in its default Windows install folder), CMake 3.20+, Ninja and Python 3:

cd opentherm
cmake -S . -B build -G Ninja
cmake --build build

Output in opentherm/build/: opentherm.elf, .hex, .bin and .map, with the LPC boot checksum and the image info already patched in.

Build opentherm/ before gateway/: the gateway build embeds opentherm/build/opentherm.bin when it exists, and warns and leaves the module alone when it does not (-DPCB1246_FIRMWARE=<path> points it elsewhere).

Release

Push a tag vX.Y.Z (or vX.Y.Z-rc.N for a pre-release). .github/workflows/release.yml builds both boards, checks that both report the tag's version, and publishes the gateway app and factory images plus the PCB1246 .bin/.hex. Running the workflow by hand builds the same files as artifacts without releasing.

About

OpenTherm proof of concept: KC1245 gateway (ESP32, Strux) and the PCB1246 OpenTherm modem (LPC11U68)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages