Skip to content

Instantly share code, notes, and snippets.

@jamesbulpin
Created October 9, 2016 15:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesbulpin/8cd09e74a4187cbd02bb45a35e16ce89 to your computer and use it in GitHub Desktop.
Save jamesbulpin/8cd09e74a4187cbd02bb45a35e16ce89 to your computer and use it in GitHub Desktop.
Arduino firmware to decode LightwaveRF 433.92MHz messages received via a simple receiver module.
#define BAUD_RATE 57600
// Receiver state
bool lastValue = LOW;
unsigned long last = -1;
const unsigned int upperThreshold = 70; //upper threshold value
const unsigned int lowerThreshold = 50; //lower threshold value
// Decoder state
#define MAX_REPS 64
#define MESSAGE_LENGTH 10
int repNumber = 0;
int decodeByte = -1;
int decodeBit = 0;
int decodeStartBits = 0;
unsigned char decodedBytes[MESSAGE_LENGTH];
unsigned char decodedNibbles[MAX_REPS][MESSAGE_LENGTH/2];
static unsigned char nibbles[] = {0xF6,0xEE,0xED,0xEB,0xDE,0xDD,0xDB,0xBE,0xBD,0xBB,0xB7,0x7E,0x7D,0x7B,0x77,0x6F};
void resetDecoder() {
decodeByte = -1;
decodeBit = 0;
decodeStartBits = 0;
for (int i = 0; i < MESSAGE_LENGTH; i++) decodedBytes[i] = 0;
}
// Decoder
void processBit(unsigned char b) {
if (decodeStartBits < 1) {
// Waiting for at least one more message start bit
if (b == 1) {
decodeStartBits++;
if (decodeStartBits == 1) {
decodeByte = -1;
decodeBit = 0;
}
}
else {
resetDecoder();
return;
}
}
else if (decodeBit == 0) {
// Waiting for a byte start bit
if (b == 1) {
decodeBit = 0x80;
decodeByte++;
//Serial.print(decodeByte);
}
else {
resetDecoder();
return;
}
}
else {
if (b < 2) {
decodedBytes[decodeByte] |= (b)?decodeBit:0;
decodeBit >>= 1;
if (decodeBit == 0) {
// Final bit of the byte. Check it's a legit byte.
unsigned char n = 255;
for (unsigned char i = 0; i < 16; i++) {
if (decodedBytes[decodeByte] == nibbles[i]) {
if (decodeByte&1) {
decodedNibbles[repNumber][decodeByte/2] |= i;
}
else {
decodedNibbles[repNumber][decodeByte/2] = i << 4;
}
n = i;
break;
}
}
if (n == 255) {
// Invalid nibble
resetDecoder();
return;
}
if (decodeByte == (MESSAGE_LENGTH - 1)) {
// Got all ten
repNumber++;
if (repNumber == MAX_REPS) {
repNumber--;
}
resetDecoder();
return;
}
}
}
else {
resetDecoder();
return;
}
}
}
void rx_complete() {
for (int r = 0; r < repNumber; r++) {
// Check if this is a new code in this batch
int isnew = 1;
for (int x = 0; x < r; x++) {
if ((decodedNibbles[r][0] == decodedNibbles[x][0]) && (decodedNibbles[r][1] == decodedNibbles[x][1]) && (decodedNibbles[r][2] == decodedNibbles[x][2]) && (decodedNibbles[r][3] == decodedNibbles[x][3]) && (decodedNibbles[r][4] == decodedNibbles[x][4])) {
isnew = 0;
break;
}
}
if (isnew) { // LWRF433/<unitID>/<channel> = <cmd 0/1>/<level>
Serial.print("LWRF433/");
if (decodedNibbles[r][2] < 0x10) Serial.print("0");
Serial.print(decodedNibbles[r][2], HEX);
if (decodedNibbles[r][3] < 0x10) Serial.print("0");
Serial.print(decodedNibbles[r][3], HEX);
if (decodedNibbles[r][4] < 0x10) Serial.print("0");
Serial.print(decodedNibbles[r][4], HEX);
Serial.print("/");
Serial.print(decodedNibbles[r][1] >> 4);
Serial.print(" ");
Serial.print(decodedNibbles[r][1] && 0x0f);
Serial.print("/0x");
if (decodedNibbles[r][0] < 0x10) Serial.print("0");
Serial.print(decodedNibbles[r][0], HEX);
Serial.println();
}
}
resetDecoder();
repNumber = 0;
}
void setup() {
resetDecoder();
pinMode(13, OUTPUT);
Serial.setTimeout(2000);
Serial.begin(BAUD_RATE);
Serial.println("LWRF433 running");
}
void loop() {
bool value;
unsigned int data=analogRead(A0); //listen for data on Analog pin 0
if (data>upperThreshold) {
value = 0;
digitalWrite(13, LOW); //If a LOW signal is received, turn LED OFF
}
if(data<lowerThreshold){
value = 1;
digitalWrite(13, HIGH); //If a HIGH signal is received, turn LED ON
}
unsigned long ts = micros();
if (value != lastValue) {
unsigned long diff = 0;
if (ts < last) {
diff = 0; // Throw away this one bit every 70 hours.
}
else {
diff = (ts - last);
}
if (lastValue == 1) {
if (diff < 800) {
processBit(1);
}
else if (diff < 2000) {
processBit(1);
processBit(0);
}
else {
processBit(2);
}
}
last = ts;
lastValue = value;
}
// Has the transmission ended?
if (((ts - last) > 25000) && (repNumber > 0)) {
rx_complete();
}
while (Serial.available() > 0) {
unsigned char rcv = Serial.read();
// Not doing anything with this yet
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment