Follow the links to one source for the various parts, but shop around. Prices and availability change from time to time.


If you're handy with electronics, you'll see a number of places where you can make a substitution for some of these parts, particularly the power supply and wiring.


Wiring the Circuit


The circuit may look a little complicated in the photo, but it's pretty easy to wire if we take it one step at a time.


Connecting the WiFly and Arduino


The Arduino Uno uses pins 0 and 1 for serial communication. These are labeled both with a number and with the letters TX (transmit) and RX (receive). The WiFly uses pins 2 (one down from the top left) and 3 (the next one down) for serial communication. Pin 2 is the transmit pin, while pin 3 is the receive pin.


Connect pin 0 on the Arduino to pin 2 on the WiFly, and pin 1 on the Arduino to pin 3 on the WiFly. This cross-connects the serial port so information sent form the WiFly is received by the Arduino and vice-versa.










Wiring the Switch


Connect pin 5 of the Arduino to one side of the push button switch, and also to one side of the 10KΩ resistor.


Connect the other side of the switch to the red power strip on the breadboard, which will eventually be wired to +5V. Connect the other side of the resistor to the blue power strip, which will be connected to ground.


This is a pretty simple switch circuit. It supplies +5V to pin 5 when the switch is pressed, and grounds pin 5 when the switch is not pressed. It doesn’t handle switch bounce, which can occur when the switch just starts to make contact, and the sensitive circuit flips between on and off as the connection is made and broken by the partially pushed switch. We'll deal with that in the software.





Connecting the LEDs


From top to bottom, the LEDs are connected to pins 2, 3 and 4 on the Arduino. Connect the long wire on the LED (the positive side) to the Arduino pin. The short pin of each LED is connected to ground—the blue bar on the power strip.


The LEDs shown have built-in resistors, which is very handy for circuits like this one. Use 330Ω resistors in series with the LEDs if you are using standard LEDs.











Connecting the Power Supply


The DFRobot Breadboard Power Supply provides both 5V and 3.3V regulated power from a variety of external sources. I'm using a USB cable, tapping power from a PowerBook. It's the same cable used to program the Arduino.


It's handy to have both 5V and 3.3V from the same power supply, since the Arduino needs 5V and the WiFly needs 3.3V. In the orientation shown, the power strip on the left is getting +5V on the red strip and ground on the blue strip. I also want 5V and ground on the power strip on the far right side of the breadboard, so those are connected to the top power strip bar, too. You can see the connections on the right power strip; two more wires are hidden from view under the power supply on the left power strip.


The power strip under the right side of the power supply, which is the second of the four power strips from the left, gets 3.3V. That's the one we'll wire to the WiFly.


Power for the WiFly


The WiFly itself uses 2 mm pin spacing, while breadboards use 0.1 inch spacing. The XBee Breakout board converts from one to the other. It is plugged in below the WiFly board, which then plugs into the breakout board. It's easy to misalign the pins, so plug the devices together carefully.


The WiFly wants +3.3V on pin 1 (the top left pin) and ground on pin 10 (the bottom left pin). The top yellow jumper and the bottom orange one provide power. You have to peek under the WiFly to see exactly where the pins connect; it's not obvious from the photo, which looks down from the top.


What about that other wire, the one connecting pin 8 to +3.3V? That tells the WiFly to set up an Ad Hoc network. It becomes it's own little hotspot, completely separate from any other WiFi network that is around. We'll see how to connect to the network later.



Power for the Arduino


Finally, connect the Arduino pin labeled 5V to the red power strip and the pin labeled GND to the blue power strip, supplying 5V to the Arduino.















Arduino Software


The Arduino is programmed in a variant of C. Here's the software we'll load onto the Arduino:


static byte pin5 = LOW;


void setup () {

    Serial.begin(9600);

    pinMode(2, OUTPUT);

    pinMode(3, OUTPUT);

    pinMode(4, OUTPUT);

    pinMode(5, INPUT);

}


void loop () {

  if (Serial.available()) {

    byte b = Serial.read();

    if (b >= '0' && b <= '7') {

      if (b & 0x01)

        digitalWrite(2, HIGH);

      else

        digitalWrite(2, LOW);

      if (b & 0x02)

        digitalWrite(3, HIGH);

      else

        digitalWrite(3, LOW);

      if (b & 0x04)

        digitalWrite(4, HIGH);

      else

        digitalWrite(4, LOW);

    }

  }

 

  if (digitalRead(5) != pin5) {

    pin5 = digitalRead(5);

    if (pin5 == HIGH)

      Serial.write("*");

  }

}


That doesn't seem too bad. It at least has the advantage of being short. Let's break it apart and see how it works.


Our program will need to track the state of pin 5 to see if the button is being pressed. It will do that frequently. All the hardware can tell us is if the button is currently down or not. We only want to tell the iPad the button is pressed when the state changes from unpressed to pressed, though, not every time the button is found in a pressed state. That means we need some way to keep track of whether the button was pressed the last time it was scanned. We'll use a global variable called pin5 to track the state of the button, setting it to the predefined constants HIGH or LOW as appropriate.


static byte pin5 = LOW;


The Arduino needs to initialize the serial connection and set the electronics for the digital I/O pins to either read a 5V signal or set a pin high or low. All of this is done in the setup function.


void setup () {

    Serial.begin(9600);

    pinMode(2, OUTPUT);

    pinMode(3, OUTPUT);

    pinMode(4, OUTPUT);

    pinMode(5, INPUT);

}


The first line initializes the serial connection to 9,600 BAUD, Next the three output pins are set to the OUTPUT state, and pin 5 is set to INPUT.


The specialized loop subroutine corresponds to the techBASIC nullEvent subroutine. Both are called repeatedly, and are used for periodic tasks.


The first task for the loop subroutine is to see if the iPad has sent any characters back to the Arduino. If so, Serial.available() will return true and Serial.read() will return the next byte from the serial port. We're expecting a character from '0' to '7' indicating the current counter value. We test the various bits in that character, setting pins 2, 3 and 4 HIGH or LOW as appropriate. Setting a pin HIGH will turn on the LED connected to that pin, while setting it to LOW turns the LED off.


void loop () {

  if (Serial.available()) {

    byte b = Serial.read();

    if (b >= '0' && b <= '7') {

      if (b & 0x01)

        digitalWrite(2, HIGH);

      else

        digitalWrite(2, LOW);

      if (b & 0x02)

        digitalWrite(3, HIGH);

      else

        digitalWrite(3, LOW);

      if (b & 0x04)

        digitalWrite(4, HIGH);

      else

        digitalWrite(4, LOW);

    }

  }


The last task for the loop subroutine is to check the status of the push button. The digitalRead(5) call returns HIGH or LOW, telling us if the push button is pressed or not. If that's different from the value in the variable pin5, the state of the switch has changed. The program records the new value in the pin5 variable so it knows when the state changes again. If the new state is HIGH, the button was just pressed. In that case, it sends an asterisk character to the iPad using the Serial.write("*") call.


  if (digitalRead(5) != pin5) {

    pin5 = digitalRead(5);

    if (pin5 == HIGH)

      Serial.write("*");

  }

}


Loading the software onto the Arduino is covered in a lot of places, so we won't go into that in this blog. See the Arduino getting started guide or Building iPhone and iPad Electronics Projects for details.


iOS Software


If you're new to techBASIC but have some experience with Objective C, the length of the next piece of software will come as a bit of a surprise. The software on the iPad is even shorter than the software on the Arduino. Here's the complete listing:


Comm.openTCPIP(1, "169.254.1.1", 2000)

PRINT #1, "0"

count% = 0


DIM t AS DOUBLE

t = System.ticks


SUB nullEvent (time AS DOUBLE)

IF NOT EOF(1) THEN

 GET #1,,b~

 IF CHR(b~) = "*" THEN

   IF time - t > 0.5 THEN

     t = time


     count% = count% + 1

     IF count% > 7 THEN

       count% = 0

     END IF


     PRINT #1, count%;

     PRINT count%

   END IF

 END IF

END IF

END SUB


The program starts by opening a TCP/IP connection to 169.254.1.1, port 2000. The specific IP address may change; we'll get to how you find the correct IP address in a moment. This command is really the only WiFi specific command in the program, though. Once the connection is open, standard BASIC I/O commands can be used to send and receive information as either strings or binary values.


Comm.openTCPIP(1, "169.254.1.1", 2000)


Once the connection is established, we write a '0' character to initialize the state of the LEDs on the Arduino, then set a global counter variable to 0. This is the variable we will use to track the number of button presses.


PRINT #1, "0"

count% = 0


I mentioned a while back that switch bounce would be handled in software. We're going to do that by only taking one button down indication every half-second. That gives the switch enough time to form a firm connection. To do that, we need a timer. System.ticks returns the current time as a double precision number. The time is in seconds from an arbitrary start point. The final two initialization lines record the starting time.


DIM t AS DOUBLE

t = System.ticks


Just as with the Arduino software, we need a subroutine that will be called frequently. This subroutine will check to see if the Arduino has sent anything new. If so, and if the character is an asterisk, the program will increment the counter and send back the current value.


The nullEvent subroutine starts by checking to see if the TCP/IP stream is signaling an end of file condition. If so, there is nothing available to read, and the subroutine exits.


SUB nullEvent (time AS DOUBLE)

IF NOT EOF(1) THEN


There is a character available, so the next line reads it. If the character is an asterisk, we'll process it. If not, the subroutine has nothing to do, and exits.


 GET #1,,b~

 IF CHR(b~) = "*" THEN


Of course, this may be a second character send because of switch bounce, so the program checks to make sure at least a half-second has elapsed since the last character was processed. If not, it exits. If a half-second has passed, the new time is recorded so we wait at least another half-second before processing another button press event.


   IF time - t > 0.5 THEN

     t = time


Finally we get the meat of the program. The counter is incremented. If it is larger than 7, the counter is rolled back to zero.


     count% = count% + 1

     IF count% > 7 THEN

       count% = 0

     END IF


The resulting value is sent both to the WiFly, which will pass it on to the Arduino, and to the techBASIC console so we can visually check to make sure the two devices agree on the count. After closing a few open IF statements and ending the subroutine, the program is complete.


     PRINT #1, count%;

     PRINT count%

   END IF

 END IF

END IF

END SUB


Installing and entering programs in techBASIC is covered in many places, including the techBASIC Quick Start Guides and Building iPhone and iPad Electronics Projects, so we won't go into it here.


Establishing the WiFi Connection


With the circuit built, the software loaded onto the Arduino and the software entered in techBASIC, it's time to give our program try. Push the blue button on the power supply to turn on the circuit. Three LEDs will begin blinking on the WiFly.


Now go to your iPhone or iPad and go into the Settings app. Tap Wi-Fi, right at the top. After a moment, you will see a network list. It may take a second or two, but eventually a hotspot called WiFly-GSX-xx will show up. The last two letters are a hex value that will change each time you use the device; they are also not terribly important. That's your WiFly network; tap it to select that device.

 

Description


They all have WiFi. It must have iOS 5 or later to run techBASIC.


techBASIC is used for the iOS program. You could use Objective C, but wait until you see the program—it's a lot shorter and easier to follow in techBASIC.


More formally, the RN-XV WiFly Module with Wire Antenna, or WRL-10822. You can use other mountings or antennas if you like.


This converts the 20-pin 0.2 mm spacing of the standard XBee device (and the WiFly, which has the same footprint) to the 0.1” pin spacing used on breadboards. It’s a handy way to prototype an application. These are available from several sources, including SparkFun, where the part number is BOB-08276.


You will need two 1 x 10 headers with a 2 mm spacing for the XBee Breakout board. These are an unusual spacing, so plan ahead—you can’t pick these up at most local electronics stores.


You will also need two 1 x 10 headers with 0.1” spacing for the XBee Breakout board. These are the common headers you can find almost anywhere. This specific part is from SparkFun, and is a 1 x 40 header you can clip apart to any desired length.


I used this versatile power supply, which can grab power from a USB port or from a standard DC power supply with a 2.1 central positive jack. You can use any power supply that provides a steady 3.3 volts and 5 volts, though, from a battery to a home-built regulated power supply.


You’ll also need a breadboard and some jumper wires for connecting everything.


You can use any Arduino that has serial communications; the Arduino Uno is simply the most common and widely available of these.


I used three resistorized LEDs. These are LEDs that have a current limiting resistor built in. You can also use standard LEDs with a 330Ω resistor in series with the LED.


Any pushbutton switch that returns to open when released will work. The one shown is Radio Shack part 275-1547.


This is used to wire the switch to pin 5 of the Arduino.

Tap the blue disclosure button to the right of the WiFly-GSX entry. A panel will open that looks like the rightmost view in the figure above. The IP Address and Subnet Mask will probably be blank when you first see them. Give it a moment and the WiFly IP Address will show up. You need to wait for it for two reasons. First, the connection isn't really established until the IP Address shows up, and second, you need to make sure the first two numbers in the IP address are 169.254. If they are not, write them down, go back to the techBASIC program, and change the first line:


Comm.openTCPIP(1, "169.254.1.1", 2000)


to match the IP Address shown in the Settings app. Do not change the last two numbers in the IP address, which should always be 1.1, or the port number, which should be 2000. Those are fixed; the WiFly device is at 1.1 on it's own little network, and wants to talk with the program on port 2000.


With the connection established, go back to the techBASIC program and run it. The WiFly sends a few characters initially, including an Asterisk, so the Arduino will pop up with a 1 right away. Press the button and make sure everything works as expected.


Other Ways to Connect


This project shows a great way to connect to an Arduino—or any other serial device, for that matter—using techBASIC and a WiFly WiFi to serial bridge. There are lots of other ways to connect to the real world using an iPhone or iPad.


One is through Bluetooth LE. There are Bluetooth LE to serial bridges that work with the iPhone, too. One is the RedBear Labs BLE Shield. Here's a photo of a project that uses an RedBear Labs BLE Shield to hack a radio control truck so it can be controlled by tilting an iPhone.

Another way to connect devices is with a HiJack A-D converter. This little device plugs into the headphone port of your iPhone or iPad. It won't control an Arduino, but it might work for a specific project you have in mind. Here's a moisture meter built with off-the-shelf-parts using HiJack.

Finally, you may not need to connect to anything external to the device. There are lots of sensors built right into the iPhone and iPad. There's an accelerometer, magnetometer, and gyroscope right in most iPhones and all iPads, and these can be combined with GPS to give location, altitude, the direction you are pointed and the direction of travel. Here's a metal detector implemented with the magnetometer. It shows the signal as the iPhone was passed over a Mac keyboard, which has an aluminum case.

These projects and more, like controlling servos and tracking the flight of a model rocket, are covered in the O'Reilly book Building iPhone and iPad Electronics Projects. Click on the book cover to go to the O’Reilly site to get your copy.

Cool Things to do with an Arduino


Now that you have a connection, what are you going to do with it? After all, we didn't learn how to connect an iPhone to an Arduino to light a few LEDs when a button was pushed! This was just a means to an end. Click on the book covers to go to the O’Reilly web site to get your copies.


Perhaps the definitive book on what to do with an Arduino and how to do it is the Arduino Cookbook. It covers everything from basic Arduino programming to advanced input and output techniques to detect light, vibration, temperature, reading RFID tags, or even GPS. Different output devices or shown, too, including various LED displays, servos or relays. Relays can be used to control larger voltages, so you can control appliances.











iOS Sensor Apps with Arduino goes into some detail about how to connect to sensors that are considerably more sophisticated than a push button switch. In addition to learning some great general techniques, you will see specifically how to connect to an ultrasonic range finder or an XBee network.











Or perhaps you would like to do a little environmental monitoring, checking water quality, electric fields or radiation levels. You can find out how to do this and more in Environmental Monitoring with Arduino.












If you have a specific project in mind, don't forget the obvious. Search the web for similar projects. The Arduino is very popular; it's likely you will find a project similar to what you have in mind.