Skip to content

Instantly share code, notes, and snippets.

@theapi
Created November 26, 2013 22:52
Show Gist options
  • Save theapi/7667775 to your computer and use it in GitHub Desktop.
Save theapi/7667775 to your computer and use it in GitHub Desktop.
/* DoorbellReceiver.ino - Detects signal from wireless doorbell.
Modified sketch (unknown licence) from Riva, to be found at
http://forum.arduino.cc/index.php?topic=110662.msg1094167#msg1094167
DBAD Public Licence (http://www.dbad-license.org/)
crutzen.eu - July 2013
Modified by Peter Clarke https://github.com/theapi
Connect data pin of RF receiver to digital pin 2 of the Arduino.
The signal exists of 24 bits.
1 means: long ON followed by short OFF
0 means: short ON followed by long OFF
__ _____________ _____ __
| | | | | |
|_____________________| |_____| |____________|
| 19760us | 1480 | 464 | 464 | 1480 |
| | | | | |
|<--------Sync------->|<--------1------->|<--------0------->|
To detect the delay values for your device, use the DeurbelSniffer.ino sketch
and read the instructions at http://blog.crutzen.eu
*/
//#define SHORT_DELAY 225
//#define SHORT_DEV 25
//#define SHORT_MIN (SHORT_DELAY - SHORT_DEV)
//#define SHORT_MAX (SHORT_DELAY + SHORT_DEV)
#define SHORT_MIN 200
#define SHORT_MAX 350
//#define LONG_DELAY 326
//#define LONG_DEV 25
//#define LONG_MIN (LONG_DELAY - LONG_DEV)
//#define LONG_MAX (LONG_DELAY + LONG_DEV)
#define LONG_MIN 351
#define LONG_MAX 500
#define SYNC_DELAY 7064
#define SYNC_DEV 100
#define SYNC_MIN (SYNC_DELAY - SYNC_DEV)
#define SYNC_MAX (SYNC_DELAY + SYNC_DEV)
#define F_WAITING 1 // 1 = waiting for sync 0 = receiving data
#define F_SIGNAL 2 // 1 = a signal found 0 = no signal found
#define F_RIGHT_SIGNAL 3 // 1 = right signal found 0 = incorrect signal
#define RF_DATA_PIN 2
#define LED_PIN 13
#define DELAY_ON 1000
const unsigned long glitch_length = 150; // Anything below this value is a glitch and will be ignored.
unsigned long fall_time = 0; // Microsecond time when last falling edge occured.
unsigned long rise_time = 0; // Microsecond time when last rising edge occured.
unsigned long length_low = 0;
unsigned long length_high = 0;
unsigned long length_sync = 0;
unsigned long buffer = 0;
byte bitCount = 0;
const unsigned long signal = 0b1101111110110110111111011011011; // The doorbell signal to look for
const byte nBits = 32;
// Debounce vars
int ledState = HIGH; // the current state of the output pin
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 300; // the debounce time; increase if the output flickers
volatile byte flags = 0;
void change() {
unsigned long time = micros();
if (bitRead(flags,F_WAITING)) { // waiting for sync
if (digitalRead(RF_DATA_PIN) == LOW) { // falling
if (time > (rise_time + glitch_length)) { // no glitch
fall_time = time;
}
}
else { // Rising - digitalRead(2) == HIGH
if (time > (fall_time + glitch_length)) { // no glitch
rise_time = time;
length_low = rise_time - fall_time;
//Serial.println(length_low);
if ((length_low >= SYNC_MIN) && (length_low <= SYNC_MAX)) { // found sync, start receiving data
length_sync = length_low;
bitClear(flags, F_WAITING);
}
}
}
}
else { //receiving data
//debug = "Receiving data";
if (digitalRead(RF_DATA_PIN) == LOW) { // falling
if (time > (rise_time + glitch_length)) { // no glitch
fall_time = time;
length_high = fall_time - rise_time;
//Serial.println(length_high);
if ((length_high >= SHORT_MIN) && (length_high <= SHORT_MAX)) { // found short high = 0
bitCount++;
buffer = buffer << 1;
//Serial.println(0);
}
else if ((length_high >= LONG_MIN) && (length_high <= LONG_MAX)) { // found long high = 1
bitCount++;
buffer = buffer << 1;
bitSet(buffer,0); // set rightmost bit to 1
//Serial.println(1);
}
else { // found nothing - start waiting for sync again
bitClear(flags, F_SIGNAL);
bitClear(flags, F_RIGHT_SIGNAL);
buffer = 0;
bitCount = 0;
bitSet(flags, F_WAITING);
//debug = ".";
}
if (bitCount == nBits) {
bitSet(flags, F_SIGNAL);
if (buffer == signal) {
bitSet(flags, F_RIGHT_SIGNAL);
}
}
}
}
else { // Rising - digitalRead(2) == HIGH
if (time > (fall_time + glitch_length)) { // no glitch
rise_time = time;
}
}
}
}
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(RF_DATA_PIN, INPUT);
bitSet(flags, F_WAITING); // waiting for sync
bitClear(flags, F_SIGNAL); // no signal found yet
bitClear(flags, F_RIGHT_SIGNAL); // right signal not found yet
ledState = LOW;
attachInterrupt(0, change, CHANGE);
Serial.begin(9600);
}
void loop() {
if (bitRead(flags, F_SIGNAL) == 1) {
//Serial.println(buffer, BIN);
if (bitRead(flags, F_RIGHT_SIGNAL) == 1) {
// Serial.println(buffer, BIN);
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
ledState = !ledState;
Serial.println(buffer, BIN);
Serial.println(ledState);
}
digitalWrite(LED_PIN, ledState);
}
// reset the debouncing timer
lastDebounceTime = millis();
bitClear(flags, F_SIGNAL);
bitClear(flags, F_RIGHT_SIGNAL);
buffer = 0;
bitCount = 0;
bitSet(flags, F_WAITING);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment