Thursday, April 5, 2012

Arduino - Assembly and Testing

Okay, we have the basics down for how the interface should behave.  Before I continue, I've been asked why not just expose the current states in a web server on the device, so I'd like to take a moment to explain that.  First, there are some things that would be perfect to expose via web service.  Those kinds of states would be temperature or other environmental variables.  The problem with exposing the door sensor via web server is that it would then depend on how often you are probing the actual device via the web.

For example, if you check the device once every minute, you will find that you might not even see the doors "open".  (In the case of an intruder, I doubt they will leave the door open to attract attention while they are in the structure.  Perhaps when they leave, but by then, it could be too late to trigger camera captures or notifications - your valuables could be long-gone.)

Arduino Assembly

The Ethernet shield (W5100) couples with the Arduino Mega 2560 just perfectly.  I suggest that you put them together to run through a test run before soldering on the PoE module.  The shield fits on perfectly by just connecting them :



Once those are connected, go ahead and upload your code to the Arduino.  The next phase for testing is to create the diode board.  I grabbed a cheap prototype board from Radioshack, and just slapped things on there quickly (it might explain the "poor design" in the following photo) :


(Obviously, the diodes are on the other side of the board).  Note that I have soldered ethernet lines up as the switches.  To simplify the other ends of the switches, I use the twisted pairs on a switch basis, e.g. the white-green and green are for the front door, etc.  Those are then tied to a computer header connector (they are cheap, and you can get a male-male header pretty cheap, too - and they work great together!), and also via the diodes to an extra line for the interrupt pin.  Once all of that is soldered together, we connect things up :


We tie our little protoboard to the 5v and ground, and then the individual pins that we want to use as inputs and the interrupt pin.  I then crafted a cheap case (and later found out there are better cases for approximately the same costs, cases that were designed for the Arduino), cut some holes, and slapped it together to check the fit.


Once it's been put together, we take the covers back off, start preparing the configuration for the SD card.  If you are using the code from a previous post, you will create an INI file in the root of the SD card called "ALARM.CFG".  This file has three sections :
[global]

[doors]

[garage]

[network]

[notifications]
The "[global]" section might eventually contain more settings (and did at one point before the code was simplified), but as of now, the only "global" setting is that of the interrupt pin.  For example :

[global]
interruptpin=18
The "[doors]" contains a list of the door switches.  The format for this is a priority:pin - you'll understand the priority when we get to the "[notifications]" section, and the pin is the input on the Arduino that it will be tied to.  These are "open" or "closed" types of switches, so if you were adding window sensors, they'd go right here.  Examples :
[doors]
frontdoor=1:38
backdoor=1:36
gate=1:37
The "[garage]" section contains the garage door switches.  It has the format of priority:pin1,pin2 - again, priority will be discussed later on, but as the garage has four states ("open", "closing", "closed", "opening"), we needed to have two pins (the logic was discussed in the Code Design post).  An example of this :
[garage]
maingarage=1:40,41
The "[network]" contains our configuration for the W5100 card - the IP address we want to assign, gateway, mask, and the MAC address.  For example :
[network]
ipaddr=10.1.0.61
gateway=10.1.0.1
dns=10.1.0.1
mask=255.255.0.0
macaddr=41:4C:41:52:4D:01
The "[notifications]" section contains the places we send state changes for the doors - this happens via a simple network connection (I'll slap some code in here for the server-side, using C for you Linux gurus). The format for these entries in the configuration are priority:IP_address:[EncryptionKey:[port]]
[notifications]
internal network=1:10.1.0.2:11223344556677889900AABBCCDDEEFF
offsite network=1:209.59.216.248:FFEEDDCCBBAA00998877665544332211
Now, to talk about the priority. As an event happens, it has an associated priority with it - e.g. "1" in the above examples. As an event happens associated with a priority, only those notification destinations associated with that priority will be called. It makes it easy to break out various switches to different locations (you can, for example, define the same notification location twice by giving it a different name but the same components, and have two priorities going to the same location). If you don't specify a port, the default port is 3612. If you don't specify an encryption key, you will have a non-encrypted communication. To specify a port without encryption, simply place an entry of the format "Priority:IPaddress::Port" (e.g. no encryption key). The encryption is to prevent a snooper from easily grabbing and spoofing requests to the server. It is a simple encryption, because too much work might cause us to miss other events as they happen if the Arduino is working too hard. The process is a shared key on both ends, and an XOR between them.
void enc(char *src,char *key,int msg_len,int key_len) {
  int   current_pos_key,current_pos_msg;
  current_pos_msg = 0;
  while (current_pos_msg < msg_len) {
    current_pos_key = 0;
    while ((current_pos_key < key_len)
          && (current_pos_msg < msg_len)
          && (src[current_pos_msg + current_pos_key] != '\0')) {
      src[current_pos_msg + current_pos_key] ^= key[current_pos_key];
      current_pos_key++;
    }
    current_pos_msg += key_len;
  }
};
The above is the actual encryption function out of the Arduino code, and gives good idea of how to implement the function.  Call the function again with the same key on the data, and you will have the original message.  For the server-side, the encryption function is identical - we just need the same key configured somewhere with the server.

The entire simple server code is available via http://www.silverhawk.net/files/interrupt_alarm-server-side.c. The tests indeed show that good keys have encrypted communication and that things look great! (I actually tied in the notification server to Google Voice using a fork(), but that code is not available as I'm not sure how far I can go - I was getting door open notifications via SMS!)  Whahooo!  Next up - a bug!

2 comments:

  1. Power over Ethernet or PoE describes a standardized system to pass electrical power along with data on Ethernet cabling. This allows a single cable to provide both data connection and electrical power to such devices as network hubs or closed-circuit TV cameras.
    PEO Networking

    ReplyDelete
    Replies
    1. Yes. Ultimately, I found that some of the wires had broken, causing the sensors to "float". I've since put it back in, and then taken the module back out.

      Delete