The Blog of Daniel

Just my place to write without any delusions of self-importance.

My W800RF32A clone

Years after x10.com fell into a black hole, I am still using x10 appliance modules controlled by my open source x10bot project.  The version I'm using is not the same as the last version I released though.  I added support for the W800RF32A RF Receiver by WGL Designs.  Unfortunately, even these things will eventually give up the blue smoke.

Since the serial version of the device has been discontinued and the USB version is out of my current budget range, I decided to make my own using a knockoff Arduino Nano and a 310 mhz rf receiver.  Total cost was about $5.

/****************************************************************************/
/* w800 emulator, v1.0.  */
/* Daniel Stasinski [email protected] June 2018 */
/* */
/* This library is free software: you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation, either version 3 of the License, or */
/* (at your option) any later version.  */
/* */
/* This library is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU */
/* General Public License for more details.  */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this library.  If not, see <http://www.gnu.org/licenses/>.  */
/* */
/* Original code by: Thomas Mittet [email protected] October 2010.  */
/* */
/* RF Timings by: */
/* http://brohogan.blogspot.com/2010/10/receiving-x10-rf-transmissions.html */
/* */
/****************************************************************************/

#include <inttypes.h>

// RF initial start burst min length
#define X10_RF_SB_MIN 9450

// RF start burst max length
#define X10_RF_SB_MAX 17550

// RF repeat start burst min length
// If you get choppy dimming, lower this threshold
#define X10_RF_RSB_MIN 7000

// RF bit 0 min length
#define X10_RF_BIT0_MIN 787

// RF bit 0 max length
#define X10_RF_BIT0_MAX 1463

// RF bit 1 min length
#define X10_RF_BIT1_MIN 1575

// RF bit 1 max length
#define X10_RF_BIT1_MAX 2925

// When repeated start burst is detected within this millisecond threshold
// of the last command received, it is assumed that the following command
// is the same and that it does not need to be parsed
#define X10_RF_REPEAT_THRESHOLD 500

#define RECEIVEINT 0
#define RECEIVEPIN 2

uint32_t riseUs, receiveEnded;
int8_t receivedCount;
uint32_t receiveBuffer;
unsigned char writeBuffer[4];
unsigned char reversebits(uint8_t value) {   int bit = 0x80;   unsigned char result = 1;
  while (bit) {     result >>= 1;     if (value & bit)       result += 0x80;     bit >>= 1;   }   return result; }
void receive() {   uint16_t lengthUs = micros() - riseUs;
  riseUs = micros();   if (lengthUs >= X10_RF_RSB_MIN && lengthUs <= X10_RF_SB_MAX) {     if (receiveEnded && millis() > receiveEnded && millis() - receiveEnded < X10_RF_REPEAT_THRESHOLD) {       receiveEnded = millis();       Serial.write(writeBuffer, 4);     } else {       receiveEnded = 0;       receiveBuffer = 0;       if (lengthUs >= X10_RF_SB_MIN)         receivedCount = 1;     }   } else if (receivedCount) {     if (lengthUs >= X10_RF_BIT1_MIN && lengthUs <= X10_RF_BIT1_MAX) {       receiveBuffer += 1LU << receivedCount - 1;     } else if (lengthUs < X10_RF_BIT0_MIN || lengthUs > X10_RF_BIT0_MAX) {       receivedCount = -1;     }     if (receivedCount == 32) {       receivedCount = -1;       // reverse all of the bits in each byte to conform to w800rf32 protocol       writeBuffer[0] = reversebits(receiveBuffer & 0xFF);       writeBuffer[1] = reversebits((receiveBuffer >> 8) & 0xFF);       writeBuffer[2] = reversebits((receiveBuffer >> 16) & 0xFF);       writeBuffer[3] = reversebits((receiveBuffer >> 24) & 0xFF);       Serial.write(writeBuffer, 4);     }     receivedCount++;   } }
void setup() {   Serial.begin(9600);   pinMode(RECEIVEPIN, INPUT);   attachInterrupt(RECEIVEINT, receive, RISING); }
void loop() { }
More Posts by Daniel