4 easy steps to create a mobile app for controlling the RFduino

Patrik Dai JavadBlogs, Tutorials

Tweet about this on TwitterShare on FacebookShare on LinkedInShare on Google+

rfduino-chipThe RFduino is a small-sized Arduino-compatible device with an on-board Bluetooth Low Energy (BLE) radio that became available earlier this year. At Evothings we have looked into the RFduino by making a simple mobile javascript app for Android and iOS devices, an IoT example where we control LEDs attached to the micro-controller over BLE. This example could be easily modified, as a template starting point for other IoT applications. For this tutorial, we assume that you are already familiar with the Arduino in general.

One of the really interesting things with the RFduino micro-controller is the small form factor and ease of use with various stackable shields in a modular concept. For our simple example, we will use the RGB LED Key button shield and a coin cell battery shield to provide power. A USB shield is needed for programming the RFduino from within the Arduino IDE. There are also a number of other shields available – a Relay shield, Prototype shield, Servo Shield and others.

So what actually is the RFduino?

The RFduino is a small Arduino compatible board by RF Digital that integrates an RF module, a few connectors (headers) and a built-in antenna. Inside the RFduino, you’ll find the nRF51822 BLE chipset by Nordic Semiconductor. The nRF51822 is a SoC (System-On-Chip) for ultra-low power BLE applications with a ARM Cortex M0 micro-controller, memory (Flash and RAM), the BLE radio itself and some other functional blocks (e.g. GPIOs, timers, temperature sensor etc). The RFduino team have made their SDK compatible with the Arduino platform and have also added value by adapting to a modular concept where several shields are available for use, yet retain a compact form-factor. We believe that for rapid and easy prototyping, the RFduino device and its peripherals should be very interesting for a wide range of uses within IoT.

In creating a basic example mobile app in Evothings Studio that connects to RFduino over BLE we focused on accessibility and ease of control and were inspired by the classic Bluetooth Low Energy LED blinking app for Arduino, a perfect template for the RFduino with the RGB LED Key button shield as it provides three-diode LED with red, green and blue, along with pushbuttons for user input, excellent for future examples such as a doorbell or even a voting app to help make very important decisions.

Our simple setup is depicted below.

rfduino-example-setup

Step 1 – Installing the RFduino development kit

To get started with the RFduino you must download two different packages.

Since the RFduino has an ARM based micro-controller it is important to have the correct version of the Arduino IDE (version 1.5.x) available to provide a compiler supporting the CPU. Once installed; you will also need to download the RFduino library from their website:

http://www.rfduino.com/download-rfduino-library/

The RFduino team have provided an excellent “quick start” guide for installing the RFduino SDK on various desktop platforms – simply follow this guide and then restart the Arduino IDE so that the new SDK can be detected. On successful installation, the RFduino should appear under the Tool/Boards menu in the Arduino IDE.

Step 2 – Preparing the RFduino code

Create an empty sketch in the Arduino IDE for our LED On – Off example – it should look something like this:

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}

In order to use the features of the RFduino SDK – we first need to include the header file

#include <RFduinoBLE.h>

Since we will be using the RGB LED Key button shield, we need to define some GPIO references that we will interact with to turn on the various colors, we do this by creating some global constants (using #define) just before the setup() function.

// Define input/output pins.
// Input pins for buttons, and output pins for LED RGB On-Off control
// GPIO2 on the RFduino RGB shield is the Red LED
// GPIO3 on the RFduino RGB shield is the Green LED
// GPIO4 on the RFduino RGB shield is the Blue LED

#define RED_LED_PIN   2
#define GREEN_LED_PIN 3
#define BLUE_LED_PIN  4

Inside our setup() function, we then need to configure these GPIO devices for use and then give a little light show to the user to verify everything is working correctly. At the same time; we can also configure the Serial port that will allow us to provide debugging information over the Serial Monitor:

// Enable outputs.
pinMode(RED_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(BLUE_LED_PIN, OUTPUT);

// Enable serial debug, type cntrl-M at runtime.
Serial.begin(9600);
Serial.println("RFduino example started");
Serial.println("Serial rate set to 9600 baud");

// Turn Off all LEDs initially
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(BLUE_LED_PIN, LOW);

// Indicate RGB LED is operational to user.
digitalWrite(RED_LED_PIN, HIGH);    // red
delay (500);
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, HIGH);  // green
delay (500);
digitalWrite(RED_LED_PIN, LOW);
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(BLUE_LED_PIN, HIGH);   // blue
delay (500);
digitalWrite(RED_LED_PIN, LOW);     // lights out
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(BLUE_LED_PIN, LOW);

At this point; we can verify we are making progress by simply uploading the sketch to the RFduino from within the Arduino IDE – if successful, the LED should blink red, green and blue and then turn off completely after uploading.

The next step is to configure the BLE properties by add the following code to the end of the setup() function:

// configure the RFduino BLE properties
RFduinoBLE.advertisementData = "ledbtn";
RFduinoBLE.advertisementInterval = 500;
RFduinoBLE.deviceName = "RFduino";
RFduinoBLE.txPowerLevel = -20;
Serial.println("RFduino BLE Advertising interval is 500ms");
Serial.println("RFduino BLE DeviceName: RFduino");
Serial.println("RFduino BLE Tx Power Level: -20dBm");

// start the BLE stack
RFduinoBLE.begin();
Serial.println("RFduino BLE stack started");

In this code we have set the device name to “RFduino”, defined some advertisement data at an interval of 500ms and set the transmission power level to -20dBm (to conserve power). Once everything is configured is to start the BLE stack by calling the RFduinoBLE.begin() function.

A final step before we start dealing with the handling of BLE events is to turn the device into lower power mode while it is operating as we simply only need to wait for event notifications and not perform any other tasks, we do this by adding the following line to the loop() function.

void loop()
{
	// switch to lower power mode
	RFduino_ULPDelay(INFINITE);
}

When it comes to processing BLE events, the RFduino is a little different than other BLE devices and shields available on the Arduino platform – instead of having to poll for events they have implemented an elegant callback system that is very easy to understand and implement. As a developer simply define a function with the template RFduinoBLE_onXXXXX() where XXXX is a specific event action to be notified of when something occurs.

We can provide the following function when the RFduino starts advertising over BLE and turn all LED’s off:

void RFduinoBLE_onAdvertisement()
{
	Serial.println("RFduino is doing BLE advertising ...");
	digitalWrite(RED_LED_PIN, LOW);
	digitalWrite(GREEN_LED_PIN, LOW);
	digitalWrite(BLUE_LED_PIN, LOW);
}

Similarly if we want to know when a device connects to the RFduino and give a form of visual indicator (turn the green LED on):

void RFduinoBLE_onConnect()
{
	Serial.println("RFduino BLE connection successful");
	digitalWrite(RED_LED_PIN, LOW);
	digitalWrite(GREEN_LED_PIN, HIGH);
	digitalWrite(BLUE_LED_PIN, LOW);
}

It will also be nice to be informed when the device disconnects and turn off the LED’s again:

void RFduinoBLE_onDisconnect()
{
	Serial.println("RFduino BLE disconnected");
	digitalWrite(RED_LED_PIN, LOW);
	digitalWrite(GREEN_LED_PIN, LOW);
	digitalWrite(BLUE_LED_PIN, LOW);
}

While these are all nice house-keeping operations, it is nice to have the granularity to see what is going on behind the scenes – for our example, we are more interest to be informed when some information is actually received over BLE so we can act and do something on the RFduino device – in this case we add the following function:

void RFduinoBLE_onReceive(char *data, int len)
{
	// If the first byte is 0x01 / on / true
	Serial.println("Received data over BLE");
	if (data[0])
	{
		digitalWrite(BLUE_LED_PIN, HIGH);
		Serial.println("Turn RFduino Blue LED On");
	}
	else
	{
		digitalWrite(BLUE_LED_PIN, LOW);
		Serial.println("Turn RFduino Blue LED Off");
	}
}

The above code takes the first byte of input from the BLE serial stream and depending on the value received, it turns the blue LED on or off on the shield. While the above code is all that is needed for our example we also included additional code to deal with key buttons and the built-in temperature sensor. You can download the entire code from GitHub here:

https://github.com/evothings/evothings-examples/tree/master/examples/rfduino-led-onoff/rfduino-led-onoff

Step 3 – Evothings app for Android and iOS

Here we will use Evothings Studio and create a mobile app for Android and iOS devices using HTML5 and JavaScript. The simple app has a button that allows us to connect to our RFduino device over BLE, and two buttons to turn on or off an LED – after successful connection the user can control the blue LED from the app as illustrated below.

rfduino-example-screenshot

There are a few main components in the Evothings App which are briefly explained below. The complete code can be downloaded from GitHub. The first part configures the appearance of the app. For example the title is set to “RFduinoLED On/Off” and the background screen color is set to white by background-color: rgb(255,255,255). Also two types of buttons are defined, one that will be used for for connection to the RFduino, and the other type for toggling the Blue LED On and Off.

<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=1">
	<title>RFduinoLED On/Off
	<link href="libs/bootstrap-3.0.2/css/bootstrap.min.css" rel="stylesheet" media="screen">
	<style>
	html, body {
		margin: 10px 10px;
		background-color: rgb(255,255,255);
	}
	div {
		margin: 10px 0px;
	}
	button {
		margin: 5px 0px;
	}
	.lead {
		font-weight: bold;
	}
	.btn-blueled {
		color: rgb(255,255,255);
		background-color: rgb(0,0,255);
		border-color: rgb(0,0,255);
	}
	.btn-connect {
		color: rgb(255,255,255);
		background-color: rgb(0,150,0);
		border-color: rgb(0,150,0);
	}
	</style>
</head>

Next the functions of the key buttons of the Evothings App are defined in HTML. As can be seen in the code below the btn-connect will call app.connect and the two buttons of type btn-blueled will be used to call app.ledOn respective app.ledOff.

<div class="form-group">
	<button type="button" class="btn btn-lg btn-connect"
		onclick="app.connect()">Connect</button>
	<button type="button" class="btn btn-lg btn-blueled"
		onclick="app.ledOn()">Blue Led On</button>
	<button type="button" class="btn btn-lg btn-blueled"
		onclick="app.ledOff()">Blue Led Off</button>
</div>

Another of the main components is the JavaScript code related to the BLE connection establishment and the data sent from the app to the RFduino to turn the Blue LED On or Off.

Below the two functions app.ledOn and app.ledOff are defined. The code for connection establishment first checks if there is already an on-going BLE connection, if so the link is first disconnected, and after 0.5s a connection is initiated. We also added some status information in the code (connecting …, connected) and error handling for convenience.

// Application object.
var app = {};

// Connected device.
app.device = null;

// Turn on LED.
app.ledOn = function()
{
	app.device && app.device.writeDataArray(new Uint8Array([1]));
};

// Turn off LED.
app.ledOff = function()
{
	app.device && app.device.writeDataArray(new Uint8Array([0]));
};

app.showMessage = function(info)
{
	document.getElementById("info").innerHTML = info;
};

// Called when BLE and other native functions are available.
app.onDeviceReady = function()
{
	app.showMessage("Touch green button to connect");
};

app.connect = function()
{
	console.log("close");
	rfduinoble.close();

	// Wait 500 ms for close to complete before connecting.
	setTimeout(function()
	{
		console.log("connecting");
		app.showMessage("Connecting...");
		rfduinoble.connect(
			function(device)
			{
				console.log("connected");
				app.showMessage("Connected");
				app.device = device;
			},
			function(errorCode)
			{
				app.showMessage("Connect error: " + errorCode);
			});
	},
	500);
};

// When the app is fully loaded the "deviceready" event is triggered.
document.addEventListener("deviceready", app.onDeviceReady, false);

The code above is mainly for explanatory purposes and should be self explanatory, also you could check the JavaScript files and the RFduino libraries if you want to learn more on the details. Download the complete code from GitHub for Evothings Studio here:

https://github.com/evothings/evothings-examples/tree/master/examples/rfduino-led-onoff/app

Before running the example from Evothings Workbench you need to build the examples to copy the required library files and UI files into the folder of the app. This is done using the “build.rb” Ruby script in the repository. You can also copy the files needed manually from the “resources” folder. More information is available in the README file.

Step 4 – Test your new app with RFduino

Once everything is prepared, it should be pretty straight forward to successfully execute the LED On – Off example and as a next step also to include your specific ideas into the code. In case you have questions, or run into problems of any sort, don’t hesitate to let us know via the Evothings forum: http://forum.evothings.com

We have noticed that for some Android devices there is a limitation related to the green Connect button in the app. If the app does not connect to the RFduino, try pressing Connect twice. Alternatively, try to first press Connect, wait a little, then press the On/Off buttons. This issue seems to be related to the Android BLE implementation.

Conclusions

Our impression of the RFduino is that it’s perfectly suited for getting started with BLE applications, while we have noticed some limitations related to BLE services: RFduino does not currently support BLE custom services or any of the Bluetooth SIG standardized services such as e.g. Battery Service (which would make sense for our application) in this incarnation of their micro-controller. Will be exciting to see how this products evolves and what functions will be included in future versions of this tiny Arduino-compatible device. If you want to know more about this small stack of fun, just take a trip to the RFduino forum.