Created
October 9, 2016 15:43
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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