Implementing the ELV FHT Protocol with an RFM23

Over the last few weeks I have been helping out the guys over at OpenTRV with an implementation of the FHT protocol for use with HopeRF RFM22B and RFM23B modules.  My as-yet unreleased sensor modules (as seen in another post) make use of an RFM23B, and I have an interest in evaluating the Conrad/ELV FHT8V valve head as part of my own central heating upgrades, so this was a job that I needed to do anyway.

The FHT protocol is similar to FS20, but the receivers are battery powered and so use a timeslot technique to avoid the need for a permanently powered receiver.  This necessitates a synchronisation procedure between the controller and its valve.  Once completed, the controller will send a packet approximately every two minutes, keeping the valve in sync.  This means that it can take up to two minutes for a change to take effect, but it does mean that the receiver remains un-powered for most of the time.

This example implements the protocol using the module’s FIFO mode, requiring minimal intervention from the host MCU.  Source is available for ATMEGA328, so it should work on an Arduino, although I have not tested it yet.

The protocol is modulated using on-off-keying (OOK) with a zero represented as 400 us on then 400 us off, and a one as 600 us on, then same off.  To generate this using the RFM2x a bitrate of 5000 bps was chosen.  This gives a bit period of 200 us, which is the lowest common denominator for the required timings.  A pre-processed bitstream can then be produced which results in the correct modulation for the message being sent.

The code also includes a proof-of-concept receiver, again using FIFO mode.  To support this some additional preamble is sent outside of the normal FHT encoding.  This does not affect the ability of a genuine FHT device to receive the packet, but makes it much easier for an RFM2x based receiver to participate in the network.  At present the receiver implementation cannot receive packets from a real FHT transmitter, but there are a couple of approaches that I have in mind which could solve this limitation.

The firmware, for AVR ATMEGA328, has been tested on one of my sensor boards, but should run on an Arduino with minimal changes.  The radio module is connected to the SPI bus, and a serial converter is required on the UART pins to access the embedded command line interface.  Connection details can be found in board.h and comms parameters for the UART are 19200,8,n,1.

Before any command can be sent the sync process must first be completed.  This defines the target house code.  The command “fht sync <hc1> <hc2>” can be used to achieve this, where the house codes are given in decimal.  This takes two minutes to complete.  Afterwards, issue “fht set <setting 0-255>” to adjust the valve position.  The receiver can only be invoked independently using the command “fhtrx”, so two devices running this code would be required to try this out.


38 thoughts on “Implementing the ELV FHT Protocol with an RFM23

  1. Jiri Tlusty

    I am very sorry for may be a stupid questions since I am not an expert in this field.

    I want to build a home heating control based on Conrad/ELV FHT8V (which I already have) driven by Raspberry Pi. I am trying to avoid the use of Arduino board (or similar USB transceivers), since it is too power-consuming, too complex and also too expensive solution. My questions are:

    1. Do you think it is a good idea to connect RFM23B module directly to Raspberry Pi using I2C bus and control FHT8V’s?

    2. If the answer is Yes, do you thing is there any part of your code usable, resp. do you have any hint how to do it?

    3. If not, please, can you give some details about your experiments with wireless driving of FHT8V (what HW you used? it seems you not using Arduino)

    Thanks a lot, JT

  2. Mike Post author


    You should be able to drive the RFM23B direct from the Pi via SPI (not I2C), but it will probably require a Linux kernel module to get the timing right. My AVR code will need modification to work properly with the operating system as well if you wanted to go down this route, and there will be some additional work to get it to synchronise with more than one valve at a time.

    I actually have some RFM23B->Pi add-on boards that I designed but haven’t yet used, partly because I am waiting to see if the RFM69W would be a better option. If you can wait a little while I will see how easy it would be to port the AVR code to it.

    The demo code runs on a custom sensor board of mine with an ATMEGA328. I did intend to port it to Arduino Uno, which uses the same microcontroller, but I never got around to it. It should just be a case of re-linking it so it works properly with the Arduino bootloader.

    Check back in a couple of weeks and/or follow me on Twitter.


  3. Jiri Tlusty

    Thanks for the prompt answer, since the winter season is over I surely can wait for the results of your RFM69W investigation.

    By the way, is your sensor board usable as a remote wireless temperature sensor equipped for example with Dallas DS18B20 (in my case, using Rasbperry Pi + FM23B-like module to read the data)?

  4. Mike Post author

    Yes. It has space on the board for a TI TMP112 or TMP102 digital sensor, or you can use a thermistor, which is much cheaper and almost as accurate. You could certainly use a Pi and suitable RF module as a receiver.

  5. Tom

    Hi Mike,

    sorry that I must ask even more stupid questions, but I’m still not sure which hardware I need to control the Conrad/ELV FHT8V

    I have an Arduino Uno with ATMEGA328. Now I will buy an RFM22 shield from sparkfun Now using your code above, it should work ?

    Thanks a lot, Tom

  6. John Magill

    Hi Mike
    Do you know if your firmware for AVR ATMEGA328 has ever been converted to Arduino “ino” format. I’m simply trying to drive the valve with a jeenode. If not do you have any guidance on the use of makefile.

  7. Mike Post author

    Hi John. I know someone who may have made it Arduino friendly – I will get back to you. However, Jeenode is RFM12B based so the code is probably not directly applicable (the RFM23B is not software compatible).


  8. John Magill

    Hi Mike.
    I have since procured an RFM22B and am keen to have a go. Any luck finding the Arduino sketch?

  9. Jiri Tlusty

    Hi Mike,
    the heating season started at my home. Any progress on RFM69W testing or Arduino re-implementation?
    Thanks JT

  10. Mike Post author


    I haven’t had time to do anything on this really, although I did obtain some RFM69W modules and do a small amount of testing with them. Have you looked at the OpenTRV code? This is more Arduino-like implementation of my code and is probably what you are after.


  11. Mike Post author

    …and yes it is RFM22B compatible as long as you remember to set up two GPIO registers to handle the Tx/Rx switching. There are also two additional connections that need to be made on the module (which are included in OpenTRV).

  12. Mike Post author

    You can use either. The 23B is not as powerful, but still capable of the legal maximum. The 22B is sometimes easier to obtain, however (and can be turned down if you want to remain legal).

    The temperature sensor isn’t very accurate at least without calibration, which I wanted to avoid.

  13. andy anten


    If its of any help, I’m just trying the fht_avr example on a plain arduino 16mhz pro-mini board, running 16meg 3.3v (a little out of spec. – waiting on 8meg pro-mini to arrive). Also using the RFM23b module.

    I loaded and compiled the source code, and works very well – thanks Mike.

    I’m using eclipse arduino plugin rather than Arduino IDE – but if anyone interested, I can load into Arduino INO, test and share – provided Author gives permission.

    A couple of questions.
    1. I couldn’t get the fhtrx receiver to pick up transmission from FHT room stats – did I read somewhere that this isn’t possible ?
    2. Are there any plans to release the sensor board eagle files ?



  14. Mike Post author

    Hi Andy,

    No problem distributing as a .ino. Let me know where you put it and I’ll provide a link.

    You are correct that the receiver can’t pick up normal FHT transmissions. It still uses the RFM23’s packet engine, which requires some 1010 preamble before the sync word. I worked around this in the transmitter simply by adding the preamble (the valves just ignore it). If you want to be able to pick up the room stats then you’ll probably need to put the RFM23 into “direct mode” and handle all the protocol timing yourself on the micro.

    I wasn’t planning on releasing this rev of the sensor boards, mainly because there are a number of issues that I wanted to rectify first. When I get around to doing a rev B I’ll be releasing that one, but it is likely to use the RFM69W (or CW) for its radio because of the built-in crypto engine.


  15. Jiri Tlusty

    Hi Mike and Andy,
    after a couple of evenings, I am successfully driving my FHT8V valves (and the boiler wired to FHT 8W) from Raspberry Pi by AVR 328P (no crystal, internal 8 MHz clock, 3.3 V) + RFM23. Mike, thanks a lot!

    If someone interested, I may give a little details.

    By the way, OpenTRV does not precisely what I am looking for (but it is a great project, I learned a lot from their source code and hw wiring schema, thanks) since I am not going to build an independent battery-powered device (I have FHT80) but I am trying to build an server running on Raspberry Pi (or arbitrary linux-like machine)
    1. which will drive all valves in the house (divided into groups, one group per room) and the boiler,
    2. having a simple web interface,
    3. reading rooms temperatures from wireless nodes ( AVR328P + RFM22 ?) or 1-wire connected DS18B20+

    To start my project seriously, I need to find some easy way how to debug the low-level code (based on Mike’s work) for AVR. Unfortunately, I dont know how to upload the code using some bootloader. At the moment, I am using an auxiliary secondary Arduino Pro Mini clone as an ISP programmer for the main AVR328 on a breadboard (and I have to reconnect wires every time I compile in order to upload).
    You may help me a lot if you create an Arduino port of Mike’s code (since in that case I may use bootloader for upload). Or, I will appreciate two hints:
    1. How to compile Mike’s code in Eclipse (‘make program’ works fine in command line but I did not succeeded with Eclipse)?
    2. How to upload Mike’s code without ISP (the auxiliary secondary Arduino in my case)?


  16. John Magill

    Hi Andy
    Any progress with the Arduino “ino” sketch. I’m simply trying to open and close the FHT8V valve and have reached stalemate with the pic route.

  17. andy anten

    Hi Mike,

    Apologies for not seeing posts earlier – I had mistakenly thought that I had subscribed to seeing posts in email.

    Thanks for the confirmation on receiving packets. No problem on the boards – I look forward to rev.B.
    I’ve spent a little time in the last week fiddling with eagle, and I’m hoping to have a simple “hack” board on which I can solder any of the RFM12/RFM23/RFM69/nRF24L01 that I’m currently playing with. I would be very interested in your thoughts on how difficult it would be to port the FHT code to RFM69 ?

    John – I will send Mike a link to INO and eclipse project asap. Here is a link to the blog that I followed for eclipse/arduino stuff. I use eclipse all day long, so its a much better choice for me than Arduino IDE.

    Jiri – I’m currently working on a similar project. So far Mike’s code has been an excellent guide. I did look at openTRV project, but I wanted simplest/clearest code possible to begin. I too plan to have wireless sensors, and I’d looked at nRF24L01 wireless module in conjunction with dht11 as a cheapish solution to give temperature and humidity in every room. I plan to use another wireless arduino with relay for the boiler. Not too fussed about having control under linux, as my PC is running 24/7 – although if development goes well, I might look at porting to Beaglebone black (similar to Rpi). I’ve posted the link I followed for eclipse/arduino above. I’d be interested to share idea’s – since we both seem to have similar goals.


  18. andy anten

    Hi Mike,

    I’ve just uploaded both arduino and eclipse/arduino projects to
    the files are and

    both have been tested this evening against a 16mhz minipro and rfm23

    the readme.txt file give instructions on how i pair with valves.

    the code changes i made are a bit hacky, they are basically
    1. add some defines to get working for arduino
    2. add pair command to CLI


  19. Jiri Tlusty

    perfect work, thanks a lot! Pairing is ok. And once again thanks to Mike, too!

    I just tested Andy’s INO code using Arduino IDE and ATmega328P with 16MHz crystal clock on breadboard (+ a few capacitors, resistors and USB/UART converter).
    Unfortunately, I am still not able to compile it under Eclipse, but Arduino IDE work well (including uploading by bootloader).

    Meantime, I spent some time in attempt to change Mike’s code to drive several independent groups of valves, but I have not succeeded. The idea is simply add a new parameter to each fht command (having an array of groups). There are some global variables in Mikes code (mainly in fht.c) but I do not understand which suppose to be common for all groups and which must be independent (I tried to make array of them and iterate fht_tick on it but this naive attempt failed).
    Maybe we better to open a new discussion out of Mike’s web?


  20. John Magill

    I have just returned to this project and am trying to upload Andy’s Arduino “ino” code. I am out of my depth and have no idea how to deal with errors like:
    conflicting types of strcmp_P

    I have tried various iterations of the IDE right up to the recent 1.6.11
    Anyone help please.

  21. John Magill

    This from IDE 1.6.11:
    In file included from sketch\common.h:54:0,
    from sketch\cli.c:31:
    defs.h:1: error: conflicting types for ‘strcmp_P’
    #define strcmp_PF strcmp_P
    In file included from sketch\common.h:58:0,
    from sketch\cli.c:31:
    c:\jmstuff\arduino\arduino-1.6.11\hardware\tools\avr\avr\include\avr\pgmspace.h:1258:12: note: previous declaration of ‘strcmp_P’ was here
    extern int strcmp_P(const char *, const char *) __ATTR_PURE__;
    exit status 1
    conflicting types for ‘strcmp_P’

  22. Mike

    Apologies – I didn’t notice you’d replied. I don’t really do Arduino so I’m not sure why Andy has changed the PSTR stuff in cli.h, but i believe it should be OK as it was (I think PSTR is only a problem if you are passing the strings to Arduino stuff, but in the CLI code all the strings are in native AVR C anyway). Try commenting out the #define strcmp_PF in defs.h and replacing the bit at the top of cli.h with (changes in bold):

    #ifdef __ARDUINO__
    #define CLI_FPUTS fputs_P
    #define CLI_FPRINTF fprintf_P
    #define CLI_STRCMP strcmp_P
    #define STR(a) PSTR(a)
    #elif __AVR__

    The #define in defs.h should have been assigning CLI_STRCMP to strcmp_P anyway, but this makes it more explicit and may make the error messages more informative, if indeed the error still occurs. You certainly need the PSTR in there, as strcmp_P expects the second string to be in program space, which is what PSTR does.

  23. John Magill

    Thanks for that, it now compiles.
    Now to upload and test…
    By any chance do you have a simple schematic diagram for connection.
    thanks a lot

  24. John Magill

    I bought an RF module when I first attempted this project 2 years ago and now cannot find it. Which module do you recommend so I can buy another.

  25. Mike

    RFM23B or RFM22B – 868 MHz version. Wire it up according to the TRX_* pins in board.h, bearing in mind that these are AVR port numbers and will need translating to Arduino pins.

    Should be this:

    digital 8 – SDN
    digital 9 – nSEL
    digital 11 – MOSI
    digital 12 – MISO
    digital 13 – SCK
    digital 2 – nIRQ

  26. Mike

    Oh, also note that the RFM23B and RFM22B is a 3.3V device and is NOT 5V tolerant. This means you will either need to drop the Arduino outputs (SDN, nSEL, MOSI and SCK) through resistor dividers, or just use a 3.3V Arduino like the Pro Mini.

  27. Mike

    Hi John. No it’s not, but funny you should ask that as I’ve just reverse engineered the MAX! protocol as well. Currently I have that working on a CC1101 based transceiver, but it should be possible to use an RFM22 or RFM23.

  28. Mike

    Not yet no. The current one is based on a Ciseco SRF USB stick that I had lying around, but unfortunately they (later known as Wireless Things) went out of business I believe. I’ll be porting this to my STM32 based stack at some point, which would be a better candidate for an Arduino port.

  29. John

    Hi Mike
    I have put together a nano and a CC1101 and have been messing with some “fhem” and CULFW firmware.
    As of yet I have had no success with pairing. All I want to do is fully open or close the EQ3 MAX! valve from my existing home brew automation and would love to have (after pairing) some simple method to do that.
    You said you had achieved some success….. care to share?

Leave a Reply

Your email address will not be published. Required fields are marked *