Code to read LightWaveRF message

The following Arduino sketch seems to reliably read 10 byte values from LightWaveRF remote control. It is a bit less reliable reading magnetic switch open and closes for some reason. (The messages from the switches are also 10 bytes – I must have miscounted before when I said they were 8 bytes). I am using the RF 434Mhz receiver from Cool Components.


int rxpin = 2;

boolean gotMessage = false; // true when full message received
const int msgLen = 10; // the expected length of the message
byte msg[msgLen]; // the message received

unsigned int dur; // duration of pulse in 50 microsecond units
byte b; // The current byte
int numBits = 0; // number of bits in the current byte
unsigned long prev; // time of previous pulse
boolean pStarted = false; // packet started
boolean bStarted = false; // byte started
int numBytes = 0; // number of bytes received 
  
void processBits() {
  byte v = digitalRead(rxpin); // the current value
  unsigned long curr = micros(); // the current time in microseconds
  
  // Calculate pulse duration
  dur = (curr-prev)/50;
  prev = curr;
  
  // See if pulse corresponds to expected bit length
  if (dur < 6) {
    // inter 1 bit gap - do nothing
  } else if (dur < 11) {
    // potential 1 bit
    if (!v) { // value now zero as 1 pulse ended
      // 1 bit
      if (!pStarted) {
        // Start of message
        pStarted = true;
        bStarted = false;
        numBytes = 0;
      } else if (!bStarted) {
        // byte started
        bStarted = true;
        numBits = 0;
        b = 0;
      } else {
        // a valid 1 bit
        b = (b << 1) | 1;
        if (++numBits == 8) { // Test for complete byte
          if (numBytes == 0 && b != 0xf6) { // Check first byte of message
            // Does not start with f6, could have missed first bit
            if (b == 0xdb) {
              // simulate getting the correct f6 byte
              bStarted = true;
              msg[numBytes++] = 0xf6;
              b = 0;
              numBits = 0;
            } else {
              // not a valid packet after all
              pStarted = false;
            }
          } else {
            // Add the byte to the message
            bStarted = false;
            msg[numBytes++] = b;
          }
        }
      }
    } else {
      // Too short for a zero bit
      pStarted = false;
    }
  } else if (dur > 20 && dur < 28) {
    // potential 0 bit
    if (v) {
      // 0 bit
      if (!bStarted) {
        // Zero bit where byte start bit expected
        pStarted = false;
      } else if (pStarted) {
        // Valid 0 bit
        b = (b << 1);
        if (++numBits == 8) {
          if (numBytes == 0 && b != 0xf6) {
            // Not a valid messae after all
            pStarted = false;
          } else {
            // Add the byte to the message
            msg[numBytes++] = b;
            bStarted = false;
          }
        }
      }
    } else {
      // Too long for a 1 bit
      pStarted = false;
    }
  } else {
     // Not a valid length for a bit
     pStarted = false;
  }
  
  // See if we have the whole message
  if (numBytes == msgLen) {
    gotMessage = true;
    pStarted = false;
  }
}

void setup() {
  attachInterrupt(0,processBits,CHANGE);
  Serial.begin(57600);
}

void loop() {
  if (gotMessage) {
    printMsg(msg);
    gotMessage = false;
  }
}

void printMsg(byte *msg) {
  for(int i=0;i<msgLen;i++) {
    Serial.print(msg[i],HEX);
    Serial.print(" ");
  }
  Serial.println();
}

Advertisements
This entry was posted in Electronics, Home automation. Bookmark the permalink.

3 Responses to Code to read LightWaveRF message

  1. Jonathan Cr says:

    Hello

  2. Jonathan Crossley says:

    Hello Lawrie,
    Have you managed to decipher the LightwaveRF protocol or just this one door switch?

    • Geek Grandad says:

      I have detecting the codes for both door switches and remote control buttons working, and I can emulate the remote control buttons and turn sockets on and off. I have not tried lights or other devices yet. I posted a link, in a previous post, that has partially decoded the protocol. I don’t need to decode the protocol for what I am currently doing as there is a unique code for each switch and for each button on a remote control, and that is all I need. To emulate dimmer switches I would need to know how the level is encoded, but I think that will be easy to do.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s