Getting going with iOS and Arduino using Bluetooth LE

Apple has included the ability to communicate via Bluetooth Low Energy (BLE) in recent iOS devices, including iPad 3 & 4, iPhone 4S & 5 and the 5th Gen iPod Touch. There is an increasing array of devices with which you can communicate (such as the TI Sensory Tag), but in this post I will be taking you through connecting and controlling an Arduino UNO board using a Red Bear Lab Bluetooth Low Energy Shield.

In this case we have a simple setup, four LEDs which we want to control from our iPhone. One LED will be used as a indicator when we are connected and the other three LEDs will light up based on the control of our iOS device.

To begin with the board and the LED need to be wired to the Arduino Shield. I am using a Sparkfun prototyping board to layout the LEDs.

IMGP0395

The BLE Shield is on top of an Arduino Uno. The four LEDs are connected to pins 4,5,6,7 with a 330ohm resistor inline to avoid them burning out. I am not an electrical engineer, so I always need to test my setup before I attempt to get the Bluetooth communication going. To do this I had a simple script to simply turn the LEDs on and off.

The script is below:

Initial Test Sketch (tests wiring):

#define LIGHT_1_PIN 4
#define LIGHT_2_PIN 5
#define LIGHT_3_PIN 6
#define LIGHT_4_PIN 7

void setup() {
pinMode(LIGHT_1_PIN, OUTPUT);
pinMode(LIGHT_2_PIN, OUTPUT);
pinMode(LIGHT_3_PIN, OUTPUT);
pinMode(LIGHT_4_PIN, OUTPUT);
}

void loop() {
digitalWrite(LIGHT_1_PIN, HIGH);
delay(1000);
digitalWrite(LIGHT_2_PIN, HIGH);
delay(1000);
digitalWrite(LIGHT_3_PIN, HIGH);
delay(1000);
digitalWrite(LIGHT_4_PIN, HIGH);

digitalWrite(LIGHT_1_PIN, LOW);
delay(1000);
digitalWrite(LIGHT_2_PIN, LOW);
delay(1000);
digitalWrite(LIGHT_3_PIN, LOW);
delay(1000);
digitalWrite(LIGHT_4_PIN, LOW);
delay(1000);
}

With the LEDs turning on and off we now need to implement the code to allow communication from the iOS device.

At the beginning of the file we need to import the SPI and BLE frameworks. The BLE framework and instructions to install it can be found on the Red Bear Labs GitHub Page

#include <SPI.h>
#include <ble.h>

Then in the config method of the BLE shield, I have copied this from the other BLE Shield examples:

SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(LSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV16);
SPI.begin();

ble_begin();

The BLE shield will be polled continuously to see if any messages are received.

The Arduino main loop is where the BLE control happens. The first part controls whether the first LED is illuminated based on the connection status:


if (ble_connected()) {
digitalWrite(LIGHT_1_PIN, HIGH);
} else {
digitalWrite(LIGHT_1_PIN, LOW);
}

We then give the BLE Shield a chance to process the connections.

ble_do_events();

Finally the we wait for a command from the iOS device and turn on the other three LEDs:

while(ble_available()) {

byte data0 = ble_read();
byte data1 = ble_read();

if (data0 == 0x01) {
if (data1 == 0x01) {
digitalWrite(LIGHT_2_PIN, HIGH);
} else {
digitalWrite(LIGHT_2_PIN, LOW);
}
} else if (data0 == 0x02) {
if (data1 == 0x01) {
digitalWrite(LIGHT_3_PIN, HIGH);
} else {
digitalWrite(LIGHT_3_PIN, LOW);
}
} else if (data0 == 0x03) {
if (data1 == 0x01) {
digitalWrite(LIGHT_4_PIN, HIGH);
} else {
digitalWrite(LIGHT_4_PIN, LOW);
}
}
}

Whenever a command is available this code will execute. We are sending through commands in two bytes. The first byte tells us which LED to control, the second byte whether we should turn the LED on or off. With that our Arduino is ready to go, the complete sketch is listed below:

#include <SPI.h>
#include <ble.h>

#define LIGHT_1_PIN 4
#define LIGHT_2_PIN 5
#define LIGHT_3_PIN 6
#define LIGHT_4_PIN 7

void setup() {
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(LSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV16);
SPI.begin();

ble_begin();

pinMode(LIGHT_1_PIN, OUTPUT);
pinMode(LIGHT_2_PIN, OUTPUT);
pinMode(LIGHT_3_PIN, OUTPUT);
pinMode(LIGHT_4_PIN, OUTPUT);
}

void loop() {

if (ble_connected()) {
digitalWrite(LIGHT_1_PIN, HIGH);
} else {
digitalWrite(LIGHT_1_PIN, LOW);
}

ble_do_events();

while(ble_available()) {

byte data0 = ble_read();
byte data1 = ble_read();

if (data0 == 0x01) {
if (data1 == 0x01) {
digitalWrite(LIGHT_2_PIN, HIGH);
} else {
digitalWrite(LIGHT_2_PIN, LOW);
}
} else if (data0 == 0x02) {
if (data1 == 0x01) {
digitalWrite(LIGHT_3_PIN, HIGH);
} else {
digitalWrite(LIGHT_3_PIN, LOW);
}
} else if (data0 == 0x03) {
if (data1 == 0x01) {
digitalWrite(LIGHT_4_PIN, HIGH);
} else {
digitalWrite(LIGHT_4_PIN, LOW);
}
}
}
}

On the iOS side we will use the BLE framework files to communicate with the BLE Shield. The complete project is available on GitHub.

photo

The project has a single screen with three UISwitch controls to control the BLE device. Each switch is hooked up to the UIViewController with an action called when the switch is changed:

- (IBAction) lightOneChanged:(id)sender;
- (IBAction) lightTwoChanged:(id)sender;
- (IBAction) lightThreeChanged:(id)sender;

When the view controller has been loaded the connection to the BLE board is attempted. Most of the BLE examples from Red Bear Labs have a connect/disconnect button but we will try to connect to the device as soon as the app is launched:

self.ble = [[BLE alloc] init];
[self.ble controlSetup:1]; //Note the number doesn't seem to do anything!
self.ble.delegate = self;

[self tryToConnectToBLESheild];

Two things have to happen before we can connect to the BLE shield, first waiting for the Bluetooth hardware on the iOS device to power up, then we wait for a BLE shield to connect. Once a connection to the BLEShield is made, the app calls connectPeripheral, causing the BLE shield to connect to us and being ready to accept commands.

- (void) tryToConnectToBLEShield {
//Check core bluetooth state
if (self.ble.CM.state != CBCentralManagerStatePoweredOn)
[self waitAndTryConnectingToBLE];

//Check if any periphrals
if (self.ble.peripherals.count == 0)
[self.ble findBLEPeripherals:2.0];
else
if (! self.ble.activePeripheral)
[self.ble connectPeripheral:[self.ble.peripherals objectAtIndex:0]];

[self waitAndTryConnectingToBLE];
}

- (void) waitAndTryConnectingToBLE {
if (self.ble.CM.state != CBCentralManagerStatePoweredOn)
[self performSelector:@selector(tryToConnectToBLESheild) withObject:nil afterDelay:0.25];
else
[self performSelector:@selector(tryToConnectToBLESheild) withObject:nil afterDelay:2.0];
}

The final part of the iOS code sends a command to the BLE shield turning the lights on and off as the switch is changed.

- (IBAction) lightOneChanged:(UISwitch *)sender {
//Turn on light one
UInt8 buf[2] = {0x01, 0x00};

if (sender.on)
buf[1] = 0x01;
else
buf[1] = 0x00;

NSData *data = [[NSData alloc] initWithBytes:buf length:2];
[self.ble write:data];
}

With that the iOS device can control the Arduino board.


Comments

3 responses to “Getting going with iOS and Arduino using Bluetooth LE”

  1. Gregor Trubitz

    Hi there,
    thanks for your great tutorial.

    While studying this tutorial and creating my own iOS app I was wondering about following question:
    How can I pair my iOS device with a Arduino device via pairing code (UUID 128bit)?
    meaning to check if user has rights to communicate with Arduino device

    I want to get in touch with some kind of security here.
    Let’s take into account that i.e. String is saved on Arduino device and check with entered code on iOS device.

    How can this be implemented / done?
    Any ideas?

    Your feedback is most appreciated.
    Thanks for your help.

    Regards.
    Gregor

  2. Glenn C

    I got this error message : ble.h not found.. I did download the files from github but couldnt figure it out. i tried using #include “ble.h” and but doesnt work. I download the file in my library. Which file should be included in the library when what needs to call eg. ble_shield or sort off? thanks..

  3. Hello the BLE.m not work with Xcode 7.1.
    please to update !!!

Leave a Reply

Your email address will not be published. Required fields are marked *