rWCHC is a project aimed at implementing a versatile weather-compensated central heating controller. The goal is to provide smart, accurate and optimal temperature control based on outdoor temperature variations, building structure and occupant habits, in order to maximize comfort and reduce power usage (minimize both the impact on the environment and the energy bill). The system is designed to be scalable and remote operable (via internet connection).

This project is composed of two parts: a custom-designed hardware module (the topic of this page) to perform the actual power control on heating appliances, and a software module (described here).

The software module is meant to run on a Raspberry Pi host to perform all computations and enhanced logic control.

This project stemmed from my need for a reliable and highly configurable controller after having had a bad experience with a brand-name device.

I have been operating two of these units in two separate locations for several years: it works! :-)



The information and methods described herein are provided “AS-IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED. Use the concepts, examples and information at your own risk. There may be errors and inaccuracies, that could be damaging to your devices. Proceed with caution, and although it is highly unlikely that accidents will happen because of following advice or procedures described in this document, the author does not take any responsibility for any damage claimed to be caused by doing so.

I’ll add an extra one since this particular design drives mains voltages:


Design goals

My design goals are simple. The system should be:

  • Safe
  • Reliable
  • Versatile
  • Affordable
  • KISS design

This is reflected in the list of hardware features.

The system is geared toward a “set and forget” approach, only requiring some attention at initial setup time.

The hardware design guidelines reflect several constraints:

  • Safety: the hardware must be safe to use and have safe failure modes
  • Reliability: the hardware must have a long service life (hence favoring solid-state throughout the design)
  • Power agnostic: the hardware must run from a broad range of voltage inputs
  • Efficiency: the hardware must consume as little energy as possible, in both the logic section and the power control section
  • Robustness: the hardware must cope with interferences (including high energy transients), in particular coming from the mains
  • Flexibility: the hardware must be adaptable to a variety of installation configurations
  • Form factor: the hardware must be small to reduce production costs and associated costs (casing), yet easy to install

For the current prototype, the choice of THT with a limited number of SMT devices has been made for greater ease of assembly. This prototype uses common components (which are easy and cheap to procure), with the exceptions of a specific high performance ADC, a level-shifter IC for interfacing with the rPi’s GPIOs, a couple of power control ICs and a PIC microcontroller.

Hardware features

The current prototype hardware features:

  • Up to 14 freely assignable RTD 2-wire sensor inputs
  • Up to 12 freely assignable Triac output channels, single phase with a maximum current budget of 5A total (fuse protected)
  • Up to 2 freely assignable Relay output channels, potential free (rated 5A/250VAC max each)
  • 1 2x16 alphanumeric LCD display with PWM backlight control, fully R/W addressable
  • 2 freely assignable tactile switches
  • 1 piezo buzzer for audible feedback (switch click and alarm)
  • 1 raspberrypi-compatible header connector for interfacing with any model of Raspberry Pi; PCB allows for embedding a Raspberry Pi Zero.
  • 1 Real-Time Clock with supercapacitor backup for host use
  • Automatic failsafe fallback in case of disconnection from the host controlling software, with host power-cycle (when self-powered)
  • Can be self- (8-28V DC input) or host- powered (no external power supply required in that case)


Here’s the schematic of the 1.5 revision of the design:



The schematic reflects the functional-block organization of the design: starting with the power supply on the upper left, a TPS54302 is wired in a typical 5V setup. Adequate long-life, low-ESR, high-current-ripple tolerance capacitors are used to smooth out the output voltage. D1 is used as a crowbar in case the wrong polarity is supplied. The EN pin is connected to the plug detection pin to ensure a complete shutdown in case the system is back-powered from the host (a design choice).

On the bottom left, this section connects the host system to the design. U5, a TPS22918 allows the microcontroller to power-cycle the host (when self-powered) as part of its watchdog duties. IC1, a TXB0104 performs level shifting for the SPI bus that the system uses to communicate with the host, as the design uses 5V-logic, whereas the Raspberry Pi host operates with 3.3V logic. U1, a PCF8523T provides RTC backup to the host. The chip has a 0.1F supercapacitor acting as a backup power-supply when the system is not powered, it provides about 1 week of battery life which should exceed most conceivable downtime scenarios for a system that is meant to be powered 24/7.

Moving on to the heart of the system, IC4, a PIC16F1783 MCU performs several tasks:

  • Power-on/reset management (ensuring consistent hardware state and managing fault conditions)
  • Input/output management (polling switches, sensors, updating triacs/relays (ensuring break-before-make), driving buzzer, LCD and LEDs)
  • Host interface (over SPI)
  • Watchdog (monitoring host, switching to alarm condition and power-cycling the host as needed)

The MCU interfaces with the rest of the system through a number of direct control signals and a 4-bit data/address bus shared between the LCD, the relay control latches and the ADCs. The unusual wiring of LED1 and LED2 stems from the need to drive two exclusive LEDs from a single pin, which is achieved through tri-state operation. Onboard ICSP is provided: this is a prototype after all :)

DIS1 is your typical 16x2 alphanumerical LCD. The firmware supports both HD44780 and ST7066U variants. Backlight dimming is implemented via PWM.

Let’s look at the output side now, at the bottom right of the schematic. Two banks of mains-capable relays are implemented. The first bank, driven by the old-school CD4099 addressable latch IC2 and its associated ULN2003 transistor array IC5 provides two potential-free electromechanical relays, as well as five solid-state triacs, each individually controllable. The next bank driven by IC3 and IC6 offers seven triacs, for a total of 12+2 individual mains-level controllable outputs. The triacs are themselves driven by an optotriac, a MOC3062M, to provide galvanic isolation.

Finally, on the input side, we have two tactile switches S1 and S2 whose functions can be freely assigned in host software, and on the upper right corner of the schematic, the analog part of the design formed around a pair of 16-bit ADS1148 ADCs.

Considering the target application (heating control) and its specificities, it was decided from the get-go to only implement support for 2-wire RTDs, which are prevalent in this application. To maximise the number of available sensors, a pseudo-differential wiring has been implemented, where each RTD share the same common pin. The selected ADC implements a very efficient digital noise filter that provides about 100dB of mains noise rejection at the target sample rate (10SPS). For this reason, no hardware filtering is implemented on the device (it would have made this pseudo-differential setup much less practical), with the exception of a simple RC filter on the positive side of the ADC reference input, as experiments showed that noise was not properly filtered on this side. Despite the datasheet’s recommendations, the 5V supply to the analog parts of the circuit is filtered through a LC circuit L2/C25 to reject the high frequency noise coming from the SMPS. Without this extra filtering the ADC performance was not satisfactory. In field testing, this design offers excellent performance with precision down to +/- 1LSB, which translates to about 0.02°C in the target application, more than sufficient for the intended purposes.

Of note, since the only available hardware SPI bus of the MCU is used to interface with the host, and since the selected ADCs are supposed to interface via SPI, a software big banged SPI bus is implemented over the aforementioned shared bus. Each ADC share the same MOSI signal, but have dedicated MISO. This makes it possible to read both ADCs simultaneously, a feature which is relied upon to ensure a complete read of all sensors in less than 1 second, the target sample rate on the host software side.


Here’s a compact two-sided through-hole prototype layout that fits on 150 x 100 mm PCB.



This is a prototype layout, routed by hand, and the focus has been put on ease of hand-assembly and in-situ wiring.

Two distinct sections are clearly separated: the “high” voltage control section, at the bottom (galvanically isolated from the control section via optocouplers and relays), with thick, short traces to handle the rated amperage and sufficient inter-trace spacing to avoid arcing. Because the mains voltage feed trace is both a bit narrower and longer than ideal for the chosen copper thickness (1oz), I arranged to bring the mains into that trace at a midpoint, and I run the same trace on both sides of the PCB: not necessarily very elegant, but effective nonetheless. In a more refined design, the mains voltage section would probably live on its own PCB (with a thicker copper layer and a more adequate layout). A fuse-protected live-phase out is provided on terminal OUT.

There is no provision for a snubber network for each triac, since the selected snubberless triacs proved quite capable of operating without it. The two relays are however fitted with a MOV suppressor.

The upper part of the PCB handles the user interface, the digital control logic circuitry and the analog sensor measurement circuitry. Again, due to the prototyping constraints, tradeoffs had to be made, but special attention has been paid to limit as much as possible noise pollution on the analog side: a separate filtered VCC feed and separate ground plane are used, and the incursion of digital signals into the analog section is kept to the bare minimum. Fast switching signals (including the PIC MCU, the 2x16 LCD and the RaspberryPi GPIO interface) are placed as far as possible from the analog signal processing part. No digital signal intersects with the analog ground plane. The analog/digital ground planes interface is located between the two ADCs. Attention has also been paid to return currents in the ground plane and plane disruptions have been carefully evaluated.

Due to the space, accessibility and safety constraints, components are placed on both sides of the PCB. This also reflects ventilation requirements for the triacs which are not heat-sinked in this prototype, and the design requirement that the user interface be straightforward, legible and safe to use (the PCB was designed from the start for integration in an acrylic case). As is, the design can – and is meant to – operate without heatsinking the triacs. This limits their current driving capabilities to a maximum of about 1A, sufficient for the typical purpose of controlling low-wattage pumps or servomotors.

The design is fully modular and can operate just fine with only partial implantation of components (e.g. only one output bank may be fitted, or even not all triacs/relays in each bank; only 1 ADC may be fitted, etc).

Finally, while the PCB is designed to accomodate a direct-mounted Raspberry Pi Zero (see picture below), it can operate correctly with 26-pin raspi GPIO header (original Rev1 “A” and “B” models).

Note: there is no D2 on the PCB rev 1.5b, numbering goes from D1 to D3.


The firmware for the MCU will be released soon.

The brain of the system lives in a software daemon that is now described on its own page.

Picture of a completed unit

This prototype unit is fully populated, and is fitted in a laser-cut custom acrylic case (not shown here):


Nylon spacers are used on the top side for extra safety.