After combining the sender, receiver and both Twitter sketches (and making some adjustments), I now present to you… the final result.
The following sketch
- checks for tweets with a specific hashtag every 40 seconds. When it finds one, it makes the doorbell ring and posts the screen name of the tweep as a new tweet;
- posts a tweet when someone pushes the doorbell button.
To avoid posting a duplicate tweet (which isn’t allowed by Twitter), the program appends a timestamp to each tweet.
(By the way… I’m well aware that the following code could use some serious optimization…)
#include <SPI.h>
#include <WiFi.h>
#include <TextFinder.h>
#include <Twitter_WiFi.h>
#include <string.h>
#define RF_RECV_PIN 2 // RF receiver component to digital pin 2
#define RF_SEND_PIN 3 // RF receiver component to digital pin 3
#define SHORT_DELAY_SEND 417
#define LONG_DELAY_SEND (3*SHORT_DELAY_SEND)
#define TOTAL_DELAY_SEND (SHORT_DELAY_SEND + LONG_DELAY_SEND)
#define SYNC_DELAY_SEND (38*SHORT_DELAY_SEND)
#define SHORT_DELAY 464
#define SHORT_DEV 200
#define SHORT_MIN (SHORT_DELAY - SHORT_DEV)
#define SHORT_MAX (SHORT_DELAY + SHORT_DEV)
#define LONG_DELAY 1480
#define LONG_DEV 300
#define LONG_MIN (LONG_DELAY - LONG_DEV)
#define LONG_MAX (LONG_DELAY + LONG_DEV)
#define SYNC_DELAY 19760
#define SYNC_DEV 1000
#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
/**********************
* WiFi variables
***/
char ssid[] = "";
char pass[] = "";
WiFiClient client;
/**********************
* RF variables
***/
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 = 0b010111110110001000001000; // The doorbell signal to look for: 0101 1111 0110 0010 0000 100
const byte nBits = 23; // Number of bits to detect (from left to right). The last (24th) bit is discarded
// because the low part of this bit is followed by the sync signal, which is also low.
volatile byte flags = 0;
/**********************
* Twitter variables
***/
char tweet[140] = "", oldTweet[140] = ""; // Tweet found
unsigned long checkTwitterTime; // Timestamp to determine when to check for new tweets
// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("");
/**********************
* RF functions
***/
void chime() { // Ding dong
unsigned long signal = 0b010111110110001000001000;
for (unsigned char i=0; i<30; i++) { // repeat signal 30 times
for (unsigned char k=0; k<24; k++) { unsigned long d = ((bitRead(signal, 23-k)) == 1 ? LONG_DELAY_SEND : SHORT_DELAY_SEND); digitalWrite(RF_SEND_PIN, HIGH); delayMicroseconds(d); digitalWrite(RF_SEND_PIN, LOW); delayMicroseconds(TOTAL_DELAY_SEND - d); } delayMicroseconds(SYNC_DELAY_SEND); } } void change() { // Interrupt handler for RF receiver pin unsigned long time = micros(); if (bitRead(flags,F_WAITING)) { // waiting for sync if (digitalRead(RF_RECV_PIN) == LOW) { // falling if (time > (rise_time + glitch_length)) { // no glitch
fall_time = time;
}
}
else { // Rising - digitalRead(RF_RECV_PIN) == HIGH
if (time > (fall_time + glitch_length)) { // no glitch
rise_time = time;
length_low = rise_time - fall_time;
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 if (digitalRead(RF_RECV_PIN) == LOW) { // falling if (time > (rise_time + glitch_length)) { // no glitch
fall_time = time;
length_high = fall_time - rise_time;
if ((length_high >= SHORT_MIN) && (length_high <= SHORT_MAX)) { // found short high = 0
bitCount++;
buffer = buffer << 1; } 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 } 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); } 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;
}
}
}
}
/**********************
* Twitter functions
***/
void tweetStatus(char* status) { // Sends tweet
char message[140];
String s = String(status) + " " + String(millis());
s.toCharArray(message,140);
Serial.print("Trying to tweet message: ");
Serial.println(message);
Serial.println("Connecting to Twitter...");
if (twitter.post(message)) {
int response = twitter.wait(&Serial);
if (response == 200) {
Serial.println("OK.");
}
else {
Serial.print("Failed to tweet. Code: ");
Serial.println(response);
}
} else {
Serial.println("Connection failed.");
}
}
void foundHashtag(char* user) { // Actions to perform when hashtag found
char message[140];
Serial.println("Chime!");
chime();
String s = "Ding dong! " + String(user) + " rang the doorbell. ";
s.toCharArray(message,140);
tweetStatus(message);
}
void checkTwitter() { // Search Twitter for hashtag
int i;
char user[140];
Serial.println("Checking for tweets...");
if (client.connect("doorbell.crutzen.eu", 80)) {
client.println("GET /index.php HTTP/1.1");
client.println("Host: doorbell.crutzen.eu");
client.println("User-Agent: Arduino/1.0");
client.println();
TextFinder finder(client);
while (client.connected()) {
if (client.available()) {
if ( (finder.getString("", "", tweet, 140) != 0) &&
(finder.getString("", "", user, 140) != 0) ) {
for (i = 0; i < 140; i++)
if(oldTweet[i] != tweet[i])
break;
if (i != 140) {
Serial.println(tweet);
foundHashtag(user);
for (i = 0; i < 140; i++)
oldTweet[i] = tweet[i];
break;
}
}
}
}
delay(1);
client.stop();
}
}
/**********************
* Arduino functions
***/
void setup() {
pinMode(RF_SEND_PIN, OUTPUT);
pinMode(RF_RECV_PIN, INPUT);
WiFi.begin(ssid, pass);
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
attachInterrupt(0, change, CHANGE);
Serial.begin(9600);
for(int i = 0; i < 140; i++) { oldTweet[i] = 0; tweet[i] = 0; } checkTwitterTime = millis(); //checkTwitter(); } void loop() { // Check Twitter if (millis() >= checkTwitterTime + 40000) {
checkTwitter();
checkTwitterTime = millis();
}
// Check doorbell
if (bitRead(flags, F_SIGNAL) == 1) {
Serial.println(buffer); // print found signal
if (bitRead(flags, F_RIGHT_SIGNAL) == 1) {
Serial.println("Tweeting...");
tweetStatus("Ding Dong - Someone at the door!");
}
bitClear(flags, F_SIGNAL);
bitClear(flags, F_RIGHT_SIGNAL);
buffer = 0;
bitCount = 0;
bitSet(flags, F_WAITING);
}
}
In conclusion
I hope that my explanations were clear enough. If not, feel free to ask!
Sources:
- Communication with wireless RF signals
- rayshobby.net: Interface with Remote Power Sockets
- davehouston.net: Capturing IR and RF Codes
- RWS-371-6 433.92MHz ASK RF ReceiverModule Data Sheet (pdf) (Bottom of page 3)
- Arduino Forum: “Re: Help me decode this 434mhz signal…?” (Create an account and log in to download the code from Riva’s post.)
- Using Twitter with Arduino

Geef een reactie