Introduction: AlarmingTweet

About: I'm no expert, but I play one on the Internet...

This project will add tweeting capabilities to the GE 45142 Choice-Alert Wireless Control Center Alarm system. The alarm system allows you to connect up to 16 different sensors across 4 zones and with the addition of the Arduino powered AlarmingTweet you can enable it to keep you informed of it's status anytime anywhere.

Originally I was thinking about building a motion detecting sensor system from scratch for the Adafruit Make it Tweet contest, but after thinking about what I would need to assemble to build it I figured there must be an easier solution. I started looking around for pre-built home security sensors etc... when I stumbled upon the GE Choice-Alert Wireless alarm system. I figured why not let it do all the heavy lifting of monitoring the sensors then I only need to figure out a way to make it tweet. Since the LEDs indicate the status of the sensors and alerts all I really needed was a way to monitor them and then send the results to Twitter.

If this sounds interesting keep reading to find out how to build one yourself. Before we get started lets go over the material we will need:

1 x GE 45142 Choice-Alert Wireless Control Center with Door or Window Sensor Kit from Amazon, Lowes or Home Depot ($30 -$40) - Comes with a single magnetic sensor for doors/windows many other sensors can be added ($15-$25 each)
1 x Arduino UNO from Adafruit ($30)
1 x Arduino Ethernet Shield from Adafruit ($45)
1 x 9V regulated DC wall-power adapter from Adafruit ($7)
1 x Arduino Project Enclosure from Sparkfun ($12)
1 x Right Angle Male Header strip from Sparkfun ($2)
Length of Cat 5 cable
Heat shrink tubing

Happy building,
willnue





Step 1: Open the Control Center Case

Remove the 4 screws holding the Control Center case together then remove the 2 screws holding the circuit board onto the case. Be careful not to pull of the antenna or speaker wires.

We are interested in the LED leads protruding from the bottom of the circuit board.

Step 2: Prepare the Control Center

From my testing it appears the Control Center sends roughly 3.3 volts to each LED continuously on the anode and then sinks the current on the cathode when it wants to light up the LED. To read the state of the LED we will connect a wire to the anode and monitor it using an Analog pin on the Arduino. When the LED is not lit we will read about 3.3v and when it is lit we will read little < 0.5v or no voltage as the current sinks through the LED.

Once the case is opened we need to solder 7 wires onto the Control Center circuit board. 1 wire for each of the 6 LEDS and 1 for  ground. For the LEDs we are going to solder the wires onto the pin of each LED that is farthest away from the edge of the circuit board. Be careful not to bridge the connection between the two pins when soldering. For the ground we will need to flip the board over and solder it to the outer pin of the barrel jack.

Try to keep the wires as short as possible and route them along the edge of the board to the side with the antenna. After soldering, drill a hole through the back of the case and feed the cable through as shown.

It's helpful to write down which wire is connected to which LED.

Note: The white residue on the board was present from the factory.

Step 3: Connect the Arduino

Slide some heat shrink tubing over the cable then break off a row of 6 right angle headers and solder the 6 LED wires to them. Once soldered cover the wires with hot glue for insulation then add and shrink some additional tubing to cover. This will provide a good solid connecter for plugging into the Arduino. Be careful when shrinking over the hot glue as it will remelt if it gets too hot. Repeat the same process for the ground wire with a single header then slide the heat shrink tubing up the cable shrink everything together.

Since the Arduino project enclosure doesn't really allow for much to be added above and beyond the Ethernet shield we need to make a few modifications to it. We need to remove the 6 female header block from the analog pins and also clip off one of the GND pins. Once completed plug in the Control Center cable and stack the Ethernet shield on top.


Step 4: Close Up the Cases

Insert the Arduino and Ethernet shield into the enclosure and mark the location for the cable to exit on the top cover then cut out a space for the cable to run through when the lid closes. Once done add the lid to the enclosure. The Control center should now rest on top of the Arduino enclosure at roughly a 45 degree angle and still be solid to handle. If the cable isn't providing enough support you may want to hot glue the two together.

Step 5: Configure ThingTweet

Unfortunately since Twitter has switched to OAuth authentication getting an Arduino to send tweets directly to Twitter from an Ethernet shield has become much more difficult than in the past. For the time being it seems the easiest way to circumvent the issue is to use a proxy between the Arduino and Twitter. The good news is using a proxy allows for better control on the Twitter side and simplifies the code required on the Arduino quite a bit.

For my project I chose to use ThingTweet from ThingSpeak as the proxy between my Arduino and Twitter, mostly because I already had a ThingSpeak account and enjoy the service. Getting the Arduino to send it's first tweet took me only a few minutes to implement with ThingTweet. To get set up yourself check out the great Update Twitter with ThingTweet and Arduino + Ethernet Shield tutorial the ThingSpeak team created, which also includes a sample Arduino sketch.

Note: The code in the next step is based on ThingTweet, but it should be easily updated for any Twitter proxy.

Step 6: Upload the Arduino Code

Edit the the following sketch being sure to update it for your network settings as well as your ThingTweet API key. See the comments inline to get a better understand about what it going on.

I have also attached a copy of the .pde file you can download as well.

###### Start Sketch ######

// AlarmingTweet by willnue - www.nuewire.com
// Adds tweet capabilties to the GE 45142 Choice-Alert Wireless Control Center
// Requires Ethernet Shield for sending tweets

//ThingTweet code details
//-----------------------
/*
ThingTweet App to Update a Twitter Status

The ThingTweet sketch is designed for the Arduino + Ethernet Shield.
This sketch updates a Twitter status via the ThingTweet App
(http://community.thingspeak.com/documentation/apps/thingtweet/) using HTTP POST.
ThingTweet is a Twitter proxy web application that handles the OAuth.

Getting Started with ThingSpeak and ThingTweet:

* Sign Up for a New User Account for ThingSpeak - https://www.thingspeak.com/users/new
* Link your Twitter account to the ThingTweet App - Apps / ThingTweet
* Enter the ThingTweet API Key in this sketch under "ThingSpeak Settings"

Created: March 7, 2011 by Hans Scharler (http://www.iamshadowlord.com)
*/

//Libraries
//------------------------
#include <SPI.h>
#include <Ethernet.h>

//Ethernet shield Settings
//------------------------
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xB2, 0xAD, 0xEF, 0xEF }; // Must be unique on local network
byte ip[] = { 192, 168, 1, 5 }; // Must be unique on local network
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

//Define pins used
//-----------------------
#define pinPwr 5 //Analog pin for Power LED on control center
#define pinArm 4 //Analog pin for Armed LED on control center
#define pinZn1 0 //Analog pin for Zone 1 LED on control center
#define pinZn2 1 //Analog pin for Zone 2 LED on control center
#define pinZn3 2 //Analog pin for Zone 3 LED on control center
#define pinZn4 3 //Analog pin for Zone 4 LED on control center


//Global variables
//-----------------------
boolean prevPwr = false; // Last state of LED (ON = true, OFF = false)
boolean prevArm = false; // Last state of LED (ON = true, OFF = false)
boolean prevZn1 = false; // Last state of LED (ON = true, OFF = false)
boolean prevZn2 = false; // Last state of LED (ON = true, OFF = false)
boolean prevZn3 = false; // Last state of LED (ON = true, OFF = false)
boolean prevZn4 = false; // Last state of LED (ON = true, OFF = false)

String ledReport = ""; // string for storing LED status message
boolean pinAlerts[] = {false, false, false, false, false, false}; //Alert Status of pins
int i=0; //Counter

//Twitter options
//-----------------------
unsigned long tweetInterval = 300000; //Minimum to wait between sending tweets (in milliseconds) - 60000 per minute
unsigned long LastTweet = 0; //Variable to hold last tweet time (in milliseconds)
boolean sendTweet = true; //Flag for sending tweet
String tweetText = ""; //string for storing tweet


// ThingSpeak Settings
//-----------------------
byte server[] = { 184, 106, 153, 149 }; // IP Address for the ThingSpeak API
String thingtweetAPIKey = "YOUR API KEY HERE"; // Write API Key for a ThingSpeak Channel
Client client(server, 80);
long lastConnectionTime = 0;
boolean lastConnected = false;
int resetCounter = 0;

//Debug options
//-----------------------
boolean debugMode = true; //Enable to debug readings to serial console


void setup() {

Ethernet.begin(mac, ip, gateway, subnet); //Start up the Ethernet shield
delay(1000);

// Update Twitter via ThingTweet
if(!client.connected())
{
updateTwitterStatus("AlarmingTweet Started up!");
}

if (debugMode == true) {
Serial.begin (9600); //Open the serial port for debug output
tweetInterval = 60000; //Overide the tweet interval for testing
}
}


void loop() {

if (sendTweet == true){
if (millis() >= (LastTweet + tweetInterval)){ //Check to see if enough time has passed to send again

tweetText = "AlarmingTweet ALERT : ";
if (pinAlerts[0] == true){
tweetText += "Zone 1 / ";}
if (pinAlerts[1] == true){
tweetText += "Zone 2 / ";}
if (pinAlerts[2] == true){
tweetText += "Zone 3 / ";}
if (pinAlerts[3] == true){
tweetText += "Zone 4 / ";}
if (pinAlerts[4] == true){
tweetText += "ARM State / ";}
if (pinAlerts[5] == true){
tweetText += "ALARM State / ";}

// Update Twitter via ThingTweet
if(!client.connected())
{
updateTwitterStatus(tweetText);
if (debugMode == true) { // Print values out to the console
Serial.print("Tweeting : ");
Serial.println(tweetText);
Serial.println();
}
}

// Disconnect from ThingSpeak
if (!client.connected() && lastConnected)
{
if (debugMode == true) { // Print values out to the console
Serial.println();
Serial.println("...disconnected.");
Serial.println();
}
client.stop();
}

lastConnected = client.connected();

LastTweet = millis(); //Reset the time of the last tweet
for( i = 0; i < 6; i++) { //Clear the alert flags
pinAlerts[i] = false;
}
}
}

sendTweet = false; //Reset Tweet flag before checking LEDs

prevPwr = checkLED(pinPwr, prevPwr); //Check LED status
prevArm = checkLED(pinArm, prevArm); //Check LED status
prevZn1 = checkLED(pinZn1, prevZn1); //Check LED status
prevZn2 = checkLED(pinZn2, prevZn2); //Check LED status
prevZn3 = checkLED(pinZn3, prevZn3); //Check LED status
prevZn4 = checkLED(pinZn4, prevZn4); //Check LED status

// Print Update Response to Serial Monitor
if (client.available())
{
char c = client.read();
Serial.print(c);
}


delay(500); // General delay between loops
}


boolean checkLED(int ledPin, boolean prevVal){
boolean curVal = false; // Current state of LED (ON = true, OFF = false)
int ledReading = 1023; // variable to store reading from LED (set to 5v/1023 by default)

ledReading = analogRead(ledPin); // read the value of the LED
delay(10); // delay 10ms to let the ADC recover

if (ledReading < 100){ //Check the LED to see if it is ON (reading < 0.5v)
curVal = true;
}

if (prevVal != curVal){ //Check to see if the value changed from the previous reading
sendTweet = true; //Set the flag to send a tweet
pinAlerts[ledPin] = true; //Flag an Alert for this pin
}

if (debugMode == true) { // Print values out to the console
Serial.print("Pin ");
Serial.print(ledPin);
Serial.print(" : ");
Serial.print(ledReading);
Serial.print(", ");
if (prevVal == true)
Serial.print("ON");
else
Serial.print("OFF");
Serial.print("/");
if (curVal == true)
Serial.print("ON");
else
Serial.print("OFF");
Serial.print(", ");
if (sendTweet == true)
Serial.print("TWEET");
else
Serial.print("-----");
Serial.println();

Serial.print("Alerts : ");
for( i = 0; i < 6; i++) {
if (pinAlerts[i] == true)
Serial.print("Y");
else
Serial.print("N");
Serial.print(", ");
}
Serial.println();

//Un-comment below to check each LED individually
//sendTweet = false; //Reset Tweet flag individually for testing
}

return curVal; //Return the current reading
}

void updateTwitterStatus(String tsData)
{
if (client.connect() && tsData.length() > 0)
{
// Create HTTP POST Data
tsData = "api_key="+thingtweetAPIKey+"&status="+tsData;

if (debugMode == true) { // Print values out to the console
Serial.println("Connected to ThingTweet...");
Serial.println();
}

client.print("POST /apps/thingtweet/1/statuses/update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(tsData.length());
client.print("\n\n");

client.print(tsData);
}
else
{
if (debugMode == true) { // Print values out to the console
Serial.println("Connection Failed.");
Serial.println();
}
}
}

###### End Sketch ######






Adafruit Make It Tweet Challenge

Finalist in the
Adafruit Make It Tweet Challenge