RFM69 – Energy Count 3000 / ELV Cost Control

Conrad Energy Count 3000 and ELV Cost Control are wireles 230V electricity consumption measuring plugs Thomas Schulz has cracked the RF protocol of these device back in 2011 on the JeeLabs forum. The signals are FSK encoded and use the 868Mhz band. Thomas was able to receive them with a RFM12B module. Together with a JeeLink V3, it has found popular use with the German home automation software FEHM.

In this post I describe how the RFM69 can take over a task that earlier had to be performed in software.

One of the complications of the protocol is that the preamble of a series of 0x55 is scramble (whitened), and therefore more difficult to recognize. However, after scrambling it is still identical for all packets.

raw data 25 8A F9 59 DA 02 7E 15 ED 67 13 F1 85 D3 AC D2   [payload]   13 E6 84 A8 3B 
descramb 48 BB 55 55 55 55 55 55 55 55 55 55 55 55 55 7E   [payload]   7E 55 55 55 55 
               -------------------------------------- --   ---------   -- -----------
                             preamble                 HDLC  payload  HDLC  postamble

The original Jeelib-based RFM12B programs detection of valid packets was clumsy.

It started matching the last 4 bytes of the preamble with the received signals
13 F1 85 D3 AC
The problem was that it is undetermined which is the first bit received from the preamble, as the receiver first has to detect a signal and then tune its gain and frequency. Some bits are lost. So Thomas Schulz had to not only check for the given series of bytes, but also for all 7 bit shifted variants. The code checks on:
13 F1 85 D3 | F8 C2 E9 D6 | FC 61 74 EB | 7E 30 BA 75 | 3F 18 5D 3A | 9F 8C 2E 9D | 4F C6 17 4E | 27 E3 0B A7

After detecting one of these pattern, the complete receive buffer gets bit-shifted the proper amount so that the buffer shows the last 5 preamble bytes as 13 F1 85 D3 AC

Sync words

Here comes the RFM69 to the rescue. Where the RFM12B can only program one user defined syncword-byte, the RFM69 can have 8. When programming those last five preamble bytes as sync-words, the task of detecting a proper packet and bit-aligning it is fully left to the RFM69.
The received signal now no longer contains the preamble, but starts at the HDLC control word 0x7E.

raw data    D2   [payload]   13 E6 84 A8 3B 
descrambled 7E   [payload]   7E 55 55 55 55 
            --   ---------   -- -----------
            HDLC  payload  HDLC  postamble

Effortless!
 

Descrambling

But before this will start working one has to realize that the preamble bits are also scrambled. In other words, the descrambler needs to be primed if one wants to start descrambling at the payload.
The actual AX5051 / AX5042 scrambling is this polynomial: 1+X12+X17.
AX5051-descrambler
Priming needs to be done for 17 bits at most, So the last three bytes of the preamble could be send through the descrambling algorithm and discarded before descrambling HDLC+payload. As the preamble is always constant, the priming value can also be determine one time, which I did.
The magic number is scramshift = 0xF185D3AC;

static void descramb(uint8_t* buff, uint16_t len) {
	uint8_t ibit, obit;
	uint8_t bit;
	uint8_t inpbyte, outbyte;
	uint32_t scramshift;

	//scramshift = 0xFFFFFFFF;
	scramshift = 0xF185D3AC; //descrambler primed at end of preanble
	while (len--) {
		inpbyte = *buff;
		for (bit = 0; bit < 8; ++bit) {
			// RFM69 receives MSBit first into bytes:
			ibit = (inpbyte & 0x80) >> 7;
			obit = ibit ^ (count1bits(scramshift & SCRAMPOLY) & 0x01);
			scramshift = scramshift << 1 | ibit;
			inpbyte <<= 1;
			outbyte = outbyte << 1 | obit;
		}
		*buff++ = outbyte ^ 0xFF;
	}
}

Code

The software is developed on a LPC824. It can be used on the complete LPC8xx family as it fits the tiny LPC810. Hardware that can be used is for example a Jeelabs Tinker Pico LPC824 board.
The software can be found in my github embapps repository

Leave a Reply

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