Arduino Android Blueprints Sample Chapter
Arduino Android Blueprints Sample Chapter
ee
Sa
pl
His main interests are in mobile development, specifically, Android and iOS, open source
healthcare projects, user interface design, mobile user experience, and
project management.
I would like to thank Angelika Biernacka-Buttigieg, my wife, for her
unconditional support and patience throughout the creation of this book.
My parents, Joseph Buttigieg and Anne Buttigieg, for their support for this
book project.
Christopher Svanefalk for his amazing insight and patience with code
reviews and support.
Don Coleman, for his invaluable help in Chapter 8, Control an Arduino
Board via NFC. We recommend his expertise on near field communication
technologies.
Chapter 6, Android Phone Sensor, explains how to turn things around, and use the
sensors from our phone to control the Arduino board. Applying this, we will use the
gyroscope of the phone to control the angle of a servomotor.
Chapter 7, Voice-activated Arduino, teaches us how to use the powerful Android speech
API to control an Arduino board via Bluetooth.
Chapter 8, Control an Arduino Board via NFC, shows how to use the NFC chip present
in many Android phones to activate a relay connected to an Arduino board.
Chapter 9, Bluetooth Low Energy Mobile Robot, uses everything we learned so far in the
book to build a mobile robot based on the Arduino. The robot will be controlled via
Wi-Fi from an Android application.
Chapter 10, Pulse Rate Sensor, is dedicated to a medical application that measures the
heart rate. We will connect a heart rate sensor to Arduino and monitor the measurements
via Bluetooth Low Energy.
We will also use a photocell in series with a 10K Ohm resistor to measure
the ambient light level. The photocell is basically a resistor that will change its
resistance depending on the incoming light on the cell. It will be connected to
the Arduino analog input to measure the ambient light level.
Finally, you will need a breadboard and some jumper wires to make the
different connections.
The following is a list of all hardware parts you will need for this project,
along with links to find these parts on the Web:
On the software side, you will need the Arduino IDE as usual, and the Arduino
aREST library, which is found at https://github.com/marcoschwartz/aREST/.
The photocell make measurements from the DHT11 sensor, you will need the DHT
library found at https://github.com/adafruit/DHT-sensor-library.
For the BLE chip, you will also need the nRF8001 Arduino library found at
https://github.com/adafruit/Adafruit_nRF8001.
To install a given library, simply extract the folder in your Arduino /libraries
folder (or create this folder if it doesn't exist yet).
[ 58 ]
Chapter 3
Hardware configuration
We will now build the hardware for this project. To help you out, here is a
schematic of the project:
[ 59 ]
5. Then, connect the REQ pin to Arduino pin 10. Finally, connect the RDY
pin to Arduino pin 2, and the RST pin to Arduino pin 9.
For the DHT sensor, this is the function of each pin on the sensor:
6. You need to first connect the power supply: the VCC pin goes to the red
power rail on the breadboard, and the GND pin goes to the blue power rail.
7. You also need to connect the DATA pin to pin number 7 of the
Arduino board.
8. Finally, place the 4.7K Ohm resistor between the VCC and the DATA
pin of the sensor.
9. For the photocell, connect the 10K Ohm resistor in series with the photocell.
This means that one pin of the photocell should be in contact (on the same
row on the breadboard) with one pin of the resistor.
10. Then, connect the other pin of the resistor to the blue power rail, and the
other pin of the photocell to the red power rail of the breadboard.
[ 60 ]
Chapter 3
11. Finally, connect the common pin between the photocell and resistor to the
analog pin A0 of the Arduino board.
This is an image of the completely assembled project:
[ 61 ]
Let's now look at this sketch in more detail. It starts by including the DHT11 library:
#include "DHT.h"
We also declare that the sensor is attached to pin number 7, and that the DHT sensor
we are using is a DHT11 sensor by declaring constants:
#define DHTPIN 7
#define DHTTYPE DHT11
[ 62 ]
Chapter 3
In the setup() function of the sketch, we will start the serial communications:
Serial.begin(9600);
In the loop() function of the sketch, we will perform the temperature and humidity
measurements from the sensor:
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
We will also read out from the photocell, and convert this reading to a percentage of
illumination. To do so, we must know that the analog input of the Arduino returns a
value going from 0 to 1,023 (10 bits). Therefore, we need to divide the reading from
the input by 1,023. Then, to get a result in percent, we will multiply this value by 100:
float sensor_reading = analogRead(A0);
float light = sensor_reading/1024*100;
When the measurements are done, we print out the value of each of them on the
serial port so that we can visualize the data. This is for example the code that prints
out the temperature:
Serial.print("Temperature: ");
Serial.print((int)temperature);
Serial.println(" C");
Note that all the code for this chapter can be found inside the GitHub
repository of the book at https://github.com/marcoschwartz/
arduino-android-blueprints.
[ 63 ]
It's now time to test this simple Arduino sketch to check if our sensors are working.
Upload the sketch to the Arduino board, and open the serial monitor (making sure
the serial speed is set to 9,600). You should get a similar result inside the serial
monitor, depending on your surroundings:
Temperature: 26 C
Humidity: 35%
Light: 75.42%
[ 64 ]
Chapter 3
// Variables to be exposed to the API
int temperature;
int humidity;
int light;
void setup(void)
{
// Start Serial
Serial.begin(9600);
// Start BLE
BTLEserial.begin();
// Give name and ID to device
rest.set_id("001");
rest.set_name("weather_station");
// Expose variables to API
rest.variable("temperature",&temperature);
rest.variable("humidity",&humidity);
rest.variable("light",&light);
// Init DHT
dht.begin();
// Welcome message
Serial.println("Weather station started");
}
void loop() {
// Measure from DHT
float t = dht.readTemperature();
float h = dht.readHumidity();
temperature = (int)t;
humidity = (int)h;
// Measure light level
float sensor_reading = analogRead(A0);
light = (int)(sensor_reading/1024*100);
// Tell the nRF8001 to do whatever it should be working on.
BTLEserial.pollACI();
[ 65 ]
Now, let's look at this sketch in more detail. Some of the parts are similar to
the sketch we saw earlier to test the sensor; we will not detail these parts again.
It starts by declaring that we want to use the lightweight mode of the aREST library:
#define LIGHTWEIGHT 1
Then, we will define that we want to use the library for the Bluetooth chip,
the aREST library, and the library for the DHT sensor:
#include
#include
#include
#include
<SPI.h>
"Adafruit_BLE_UART.h"
<aREST.h>
"DHT.h"
After this, we will define the pins on which we connected the BLE module:
#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 2
#define ADAFRUITBLE_RST 9
Just before the setup() function of the sketch, we will declare the following three
variables that contain the measurements coming from the sensor:
int temperature;
int humidity;
int light;
Then, in the setup() function of the sketch, we will initialize the BLE module:
BTLEserial.begin();
[ 66 ]
Chapter 3
We also have to expose the different measurement variables to the aREST API so that
they can be accessed by the Android app:
rest.variable("temperature",&temperature);
rest.variable("humidity",&humidity);
rest.variable("light",&light);
In the loop() function of the sketch, we will poll the status of the BLE module:
BTLEserial.pollACI();
We will also get the state of the module and store it in a variable:
aci_evt_opcode_t status = BTLEserial.getState();
If this status indicates that the Bluetooth module is connected to another device,
we will process the incoming request with the aREST library:
if (status == ACI_EVT_CONNECTED) {
rest.handle(BTLEserial);
}
Note that all the code for this chapter can be found inside the GitHub
repository of the book at https://github.com/marcoschwartz/
arduino-android-blueprints.
It's now time to upload the sketch to your Arduino board. When this is done, you
can move on to the development of the Android app to control the Arduino board
via the BLE sketch.
[ 67 ]
We will first start off by drawing a paper prototype of how our application will
work and the basic user flow, as shown in the following image. This will
help us understand how the application will work as well as facilitating our
development process.
Upon analyzing the preceding image, we can see that this design will require two
TextView objects. The upper TextView object will show all the Bluetooth callbacks,
state changes, and characteristics written to the BLE module, while the lower
TextView object will show the output from the temperature, light, and humidity
sensor depending on which button was tapped.
The TextView objects will give them the following IDs:
connectionStatusView
dataOutputTextView
In the lower part of the layout, we will have three buttons reflecting the three
parameters that we will be requesting, that is, temperature, light, and humidity.
We will name the buttons as follows:
Text: Temperature
ID: temperatureButton
[ 68 ]
Chapter 3
Text: Humidity
ID: humidityButton
Text: Light
ID: lightButton
On a Mac, navigate to Android Studio > Preferences > Editor > Auto-Import
With all the necessary settings in place, we will first start off by creating a new
project, where we will choose the following within the New Project setup:
Minimum SDK: 18
Domain: arduinoandroid.com
[ 69 ]
Once imported, we will open MainActivity.java, select all the code below the
import statement and copy it. When all the code has been copied, we will open our
current project (Android Bluetooth Weather Station), go into MainActivity.java,
delete all the code below the import statement, and paste the code.
In case you get stuck at this stage of the project, our code will be available in the
repository in two stages, the version with all the necessary code that needs to be
modified and the completed project. These are all available in the GitHub repository
at https://github.com/marcoschwartz/arduino-android-blueprints.
Once the code is in our project, we will proceed by changing references to the
UI elements to reflect our latest additions to the Android layout file in the
onCreate() method:
dataOutput = (TextView) findViewById(R.id.dataOutputTextView);
connectionOutput = (TextView) findViewById(R.id.connectionStatusView);
adapter = BluetoothAdapter.getDefaultAdapter();
temperature = (Button) findViewById(R.id.temperatureButton);
light = (Button) findViewById(R.id.lightButton);
humidity = (Button) findViewById(R.id.humidityButton);
Chapter 3
writeLine("Sent: " + setLightMessage);
}
else {
writeLine("Couldn't write TX characteristic!");
}
}
});
humidity.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String setHumidityMessage = "/humidity /";
tx.setValue(setHumidityMessage.getBytes(Charset.
forName("UTF-8")));
if (gatt.writeCharacteristic(tx)) {
writeLine("Sent: " + setHumidityMessage);
}
else {
writeLine("Couldn't write TX characteristic!");
}
}
});
We will also modify the code that deals with writing remoteCharacteristics,
namely, the writeLine() method, and in addition, we will add another method
known as writeSensorData(), which will deal with the remote data arriving
from our different sensors:
private void writeLine(final CharSequence text) {
runOnUiThread(new Runnable() {
@Override
public void run() {
connectionOutput.setText("");
connectionOutput.append(text);
connectionOutput.append("\n");
}
});
}
//Implement the method below to output temperature/humidity/light
readings to dataOutputView
private void writeSensorData(final CharSequence text) {
runOnUiThread(new Runnable() {
@Override
public void run() {
[ 71 ]
Before we are able to move ahead with compiling the project, we need to work on the
onCharacteristicChanged method so that the data that is received from the sensor
data will be set to the dataOutput text view:
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
writeSensorData(characteristic.getStringValue(0));
}
At this point in time, the project will be unable to function as the necessary
permissions have not been implemented yet. User permissions are necessary as it
allows the application to access different capabilities of the device. In this case, we
will need to add the following two permissions within the AndroidManifest.xml
file, which you will find by navigating to app > src > main > AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_
ADMIN"/>
When we perform all these changes, we should expect the rudimentary user
interface to look as follows, with the sensor data showing up after tapping on
the different parameters:
[ 72 ]
Chapter 3
[ 73 ]
You should navigate using the project tree, followed by a right-click on app,
as shown in the following screenshot:
After you right-click on app, create a new image asset by going to New >
Image Asset, as shown in the following screenshot:
[ 74 ]
Chapter 3
You will then be shown an Asset Studio pop-up window, which will allow you
to choose your very own image file. For optimization purposes, we recommend
going for a .png file with a resolution of 144 pixels by 144 pixels. Android Studio
automatically does all the resizing and resource creation to adapt your graphic to
different screens, as shown in the following screenshot:
[ 75 ]
Once you choose the ic_launcher image file, which we have provided you with,
you will be shown a screen with the icon in different sizes. Click on Next, where
you will see the following screen:
The preceding screen warns you that previous files will be overwritten and shows
you the image launcher file in a number of different resolutions once again. Click on
Finish, then compile the app, launch it on your physical device, and you should see
something as pleasant as the following in your app tray and in the app's action bar:
[ 76 ]
Chapter 3
The whole block of code responsible for the Sensor Data Output TextView will
now look as follows:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/dataOutputTextView"
android:layout_gravity="center_vertical"
android:textSize="200dp"
android:gravity="center"
android:text="99" />
In this block of code, we have temporarily used the placeholder text 99 so that
we can approximate how it will look with the Android layout designer. With this
modification, the sensor data output is now big enough to be seen by the user,
thus enhancing the user experience.
[ 77 ]
4. Name the file buttonshape and type down shape as the Root element
followed by clicking on OK, as shown in the following screenshot:
[ 78 ]
Chapter 3
7. We will also add some flavor by adding the following line of code to the
button and TextView modules within the activity_main_screen.xml file:
android:textColor="#4A90E2"
In the preceding code, #4A90E2 refers to the hex code of the main color used in the
app icon so that we maintain some consistency with the main user interface.
[ 79 ]
It's important to note that different Android devices have different dimensions. So,
for your specific Android device, you might need to do further optimizations within
the Android layout files to improve the interface.
How to go further
A large number of improvements could be done towards improving the user
interface process within the Android app. Currently, service discovery is refreshed
only by physically rotating the device, as the onResume() method is called upon
rotation of the device. This could easily be improved by adding a refresh icon in the
action bar and connecting this icon to the code, so that this method is called when the
icon is tapped.
[ 80 ]
Chapter 3
You can even expand the app further with real-time monitoring, statistics, and trends.
Summary
In this chapter, we built a simple weather station using Arduino and Android. We
attached several sensors to our Arduino board, along with a Bluetooth Low Energy
module. We also built the corresponding Android app so that we can access all the
data measured by the Arduino board just by tapping on a button of the phone.
In the next chapter, we will use a different technology to interact with an Arduino
board via Android: Wi-Fi. We will build a smart power switch, to control an electrical
device remotely, and also to measure the device power consumption via Wi-Fi.
[ 81 ]
www.PacktPub.com
Stay Connected: