Introduction: Make an Easy Button Wireless

Ah, the ubiquitous Staples "Easy Button."  There are other big-dome buttons, but the Staples button has the distinction of not needing a panel to be mounted in.  It just has a nice flat base.  So why not free it entirely from any panel, desk, or other attachment to the outside world entirely?

The XBee node -- a popular implementation of the Zigbee protocol of 802.15.4 wireless devices -- is not by any means the cheapest way to create a wireless link to an Arduino-based (or similar) project, but it certainly seems the simplest.

And thus this Instructable -- a rather long telling of a rather simple project.

Step 1: Take It Apart

The Easy Button is designed to be hand-assembled -- and taken apart.  There are no snap-fit, no epoxies, nothing but screws, solder, and a bit of hot glue.

Pry out the four rubber feet on the bottom and remove the four screws there.  Pull the dome and surround off.  Unscrew the two screws holding the circuit board -- keep the screws in order; the screws holding the board are the long ones.  Pull out the spring plate.  Unscrew the last four screws and remove the last big chunk of plastic.

For this project, we need to tear down a little further.  De-solder all the components on the circuit board.  Desolder and discard the wiring harness.  Work the speaker free gently with a screwdriver, cutting some of the glue first with a hobby knife if necessary.

And now we come to the first picture (seriously, if you can't take apart a plastic toy without pictures, you probably shouldn't be trying to wire up an XBee node.)  To get a nice space for the parts I wanted I needed to remove the lump of plastic in the center of where the speaker sat.  My Dremel made short work of that.

Step 2: Fit the Components

My first iteration, I wasted an XBee Explorer from SparkFun on this.  Since the USB port was buried inside the button and I was bypassing the power regulator anyhow, the iteration here uses a basic XBee breakout board.  Oh, and although the XBee module will function happily with the unregulated nominal 3V of a pair of AAA batteries, for this iteration I've also chosen to add a buck/boost converter from SparkFun that puts out a nice regulated 3.3 volts.

You don't need either, of course.  But using a breakout, at least, makes it easier to pull out the XBee for reprogramming or upgrade.

Step 3: Wire It Up

Actually, you solder the leads to the breakout boards first.  I use a pair of clamps; a PC board vice to hold the board, and a third hand jig to hold the wire.  I seemed to have lost my 40-60 solder right as I started this project, and I needed all the help I could get to make nice connections with the silver-bearing lead-free solder I had left.

It is hard to see, but the 3.3V from the regulator goes to pin 1 of the XBee, and the grounds (pin 10 of the XBee and the shared ground from the 3.3v step-up) are brought together along with the 3V input of the regulator.  Lastly, there is a black "signal" wire on DO0 (pin 20 on the XBee).  This is the pin I'm choosing to use for my button signal.  I'll explain as soon as we get done soldering!

We are using the original battery compartment for this (makes it easy to change the batteries.)  The large lugs on the battery compartment are the closest thing to a proper bus we have, so all the ground leads are brought to this one spot and soldered together there.

The second picture is misleading -- it is from the first time I did this (thus the different colors of wire). 

Oh, and late in the day I decided I really wanted an electrolytic capacitor to store up the not-insignificant juice the XBee Pro would demand when transmitting.  It is spliced on to the leads of the step-up because there was really no better place to fit it.



Attach the circuit boards to the plastic with double-stick tape, and re-attach the top part of the inner button, pulling the leads through the small gap right by the battery terminals.

Step 4: Silencing

My applications were all theatrical...meaning the nice click-clack sound, and the "That was easy!" that plays out of the sound chip, were not wanted.

The membrane switch itself doesn't give that nice bounce.  The way the button works, the top dome rides on four plastic posts that keeps it aligned, and it presses down on a sheet of spring steel.  Two "notches" in the spring steel are bent the opposite way, and as the button descends they are forced to snap through to the other direction.  Harder to explain than it is to see.  Anyhow; to silence the clicker but keep that nice button feel you take a pair of pliers and straighten out the notches.

Killing the chip was just part of the process of cleaning the wiring.  After de-soldering everything, I cut through the traces around the chip with a hobby knife.  Your circuit board may look different but the principle is the same.  Take out the handy VOM or continuity tester, and figure out which pads are connected when you press the button.

Because of the sliding posts from the button itself, there is not really a lot of space in here.  So the neatest way of making sure no stray wire fouled up the button, I put a jumper on the remaining scraps of the circuit board so the pads that connected to the button could be brought out to one edge of the circuit board.

Step 5: Why Are We Doing This?

Also known as; "Wait, wait; you need to do this step first!"



So, meet the XBee.  It is a nicely complicated little digital transceiver.  It doesn't just send a signal out into the airwaves and hope it gets picked up without interference.  Instead it connects with other nodes, checks the transmission path, reads off signal strength, sends a digitally encoded message multiple times asking for acknowledgment from the receiver...

Anyhow.  The XBee is designed for secure, low-BAUD, extremely low power usage digital transmission.  Out of the box they act as a nearly-transparent serial connection.  Connect one to the serial port on one computer, connect another to a second computer, and what you type into the terminal window will show up with almost no delay on the other.  But it has a little trick (on the Series 1 chips at least) that makes them even easier to use for a job like this; I/O Line Passing.

What this means, is, if two XBees are set up correctly, when you change the state on one of the pins on the transmitter, the same pin (or the matching pin for the analog/PWM pins) changes state identically after it gets the radio message.

Which allows something like this project; all we are doing is pulling one pin low.  The corresponding pin on the matching device will also go low, which is the same as a button press to an Arduino or similar.  Or it The can directly drive a small LED, or (with the right power transistor) a relay or a larger load.

(Pulled down?  Well...the XBee has internal pull-up resistors.  Which seem to be turned on in the factory default because I've had no trouble doing it this way.  When I've gotten more sleep I'm going to look into that closer.)

((The output can be set to default HIGH or default LOW, so you really have a lot of flexibility in how you set up this line passing.  And that's not even getting into the analog passing, which gives you a choice of sample rate and number of samples to average before transmission, before summing the ADC input of one into a PWM output of the other.  This is clean enough you can actually connect a potentiometer to one XBee and directly control a servo on the other.))

And that's what makes these chips so attractive for projects like this.  You don't need a CPU to control it.  You don't need the voltage regulator.  You don't even need a breakout board (if you are comfortable with soldering to fine-pitched legs.)  All you need is the sensor, the XBee, and a power source.  And since these are designed for low-power operation (with multiple sleep modes, even), they can last for a very long time in some remote location passing along the output from a sensor to the rest of the networked devices.

You don't need anything but the XBee and a battery...once it is set up, that is.  Because out of the box it only does serial data transmission.  And unless you really want to play with remote command mode, it is necessary to find a way to connect it to the computer of your choice while you program in the settings you want.

Step 6: Programming

The simplest way to connect to the XBee is via a serial-to-USB converter.  The dead simplest is a USB XBee Explorer such as carried by SparkFun, Adafruit, and the usual suspects.  The next simplest is an FTDI breakout, such as Adafruit's "FTDI Friend."  I've done it both ways.  For all those with an Arduino lying around, you can turn that into a serial-to-USB converter pretty easily as well (up until the Leonardo, that is -- no more pulling the chip to allow access to the FTDI, because there IS no more FTDI on the Leonardo!)  You can, however, use the serial ports, or software serial, and send AT commands from an Arduino.  I just happen to like doing it in a terminal on my laptop.

You can talk to one using an ordinary terminal program, but this is inconvenient on OS-X because the XBee doesn't send back the right new line command and all the replies get jumbled together.  Fortunately Tom Igoe has stepped in with a simple terminal program written in Processing (and various people have expanded it since).  I am using a modified version of Tom's original program, which I entered by hand out of the text in his book "Making Things Talk."

Here's the current version of the code I am using:


import processing.serial.*;
Serial myPort;
String portnum;
String outString = "";
String inString = "";
int receivedLines = 0;
int bufferedLines = 8;

void setup()
{
  size(400, 300);
  PFont myFont = createFont(PFont.list()[3], 14);
  textFont(myFont);
  println(Serial.list());
  portnum = Serial.list()[3];
  myPort = new Serial(this, portnum, 9600);
}

void draw()
{
  background(0);
  text("Serial port:  " + portnum, 10, 20);
  text("typed: " + outString, 10, 40);
  text("received: " + inString, 10, 80);
}

void keyPressed()
{
  switch (key)
  {
    case '\n':
    myPort.write(outString + "\r");
    outString = "";
    break;
   
    case 8:
    outString = outString.substring(0, outString.length() -1);
    break;
   
    case 65535:
    break;
   
    case '+':
    myPort.write(key);
    outString += key;
    break;
   
    default:
    outString += key;
    break;

  }
  if (outString == "+++")
  {
    delay(2000);
    outString = "/n";
  }
}

void serialEvent(Serial myPort)
{
//  inString = "Serial Event Recieved!";
//  delay(2000);
  int inByte = myPort.read();
  inString += char(inByte);
  if (inByte == '\r')
  {
   inString += '\n';
    receivedLines ++;
    if (receivedLines > bufferedLines)
    {
      deleteFirstLine();
    }
  }
}

void deleteFirstLine()
{
  int firstChar = inString.indexOf('\n');
  inString = inString.substring(firstChar + 1);
}



Short form here.  You are using AT commands, which start with an attention code (+++, no carriage return) to get the chip's attention, then a series of commands each suffixed by "AT."  They are all documented in the manual for the XBee, and if you don't want to go that far, the basic commands for setting up a line passing mode are copied in several places on the web -- here, for instance.

As I recall, the only things I had to set on the transmitter end were:

+++    //gets the node's attention, it will reply with "OK"
ATMY2   //this is the node's self-identity
ATDL3   //this is the low byte of the address the node wants to talk to
ATID5555  //this is the PAN ID; the ID for the network both devices are on
ATD03  //this sets up pin 20 -- Digital I/O 0, as a digital input
ATICFF // monitors all the I/O pins and sends a transmission when any of them change.  This is a bitfield, if you don't want them all.
ATWR  // don't forget this command!  It writes the settings into memory
ATAC // this command causes the node to start using the new settings (and close command mode).


You can also force sample at intervals using the IT and IR commands, as well as -- by using the right pin -- have the node sleep when there is no input present.

My recieiver needed to have the reciprocal IDs, and be set up for pin output:

+++
ATRE  // reset to factory default -- let's be safe here!
ATMY3
ATDL2
ATID5555
ATD05 // now pin 20 is set to change state depending on data recieved from the transmitter
ATWR
ATAC


As you may have noticed, there is nothing that forces the transmission to be one-way only.  Nodes will happily communicate bidirectionally with the serial lines (which haven't been affected by this line passing mode, let me note!) and they will happily echo I/O lines in both directions as well.



I highly recommend getting the XBee nodes talking on the breadboard before you start screwing your button back together.

Oh; and the other end?  Detecting a "pulled LOW" is as easy as running a wire from appropriate I/O pin on the XBee to an open I/O pin on an Arduino and writing;

const int xbeePin = 8;
const int ledPin = 13;

void setup()
{
  pinMode(xbeePin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  if (digitalRead(xbeePin) == LOW)
  {
     digitalWrite(ledPin, HIGH);
  }
  else
  {
     digitalWrite(ledPin, LOW);
  }
}


(The above code SHOULD work but I typed it by eye right here in the Instructable.  I've gotten far to used to having the Arduino -- or Processing -- IDE check my syntax for me!)

The first use I put my Easy Button to is to connect the receiver XBee to an Arduino I already had set up to spit out a MIDI note message whenever it saw the appropriate trigger signal.  We almost used it as game show-type buzzer for the musical "Lucky Duck."  A little later I connected the MIDI cable to our lighting console and was able to run light cues from outside of the light booth on one show where the tech staff was short-handed.

The horrible mess in the second picture is me using the button to change programs on the BlinkM I am modifying (aka connected it to my Adafruit ISP and wrote new software within the Arduino IDE).  The latter may be a bit wasteful of a $20 radio, but it does show the flexibility of a self-contained wireless button.