Вы находитесь на странице: 1из 116

Getting

Started with Android Things for Raspberry Pi 3

Getting Started with Android Things for Raspberry Pi 3

Agus Kurniawan

1st Edition, 2017

Copyright © 2017 Agus Kurniawan


Table of Contents
Getting Started with Android Things for Raspberry Pi 3
Preface
1. Introduction to Raspberry Pi 3 and Android Things
1.1 Raspberry Pi 3
1.2 Getting Hardware
1.3 Android Things for Raspberry Pi 3
1.4 Unboxing
2. Deploying Android Things on Raspberry Pi 3
2.1 Android Things Image
2.2 Preparation
2.3 Flashing Android Things for Raspberry Pi 3
2.4 Attaching Micro SD card on Raspberry Pi 3
3. Running and Configuring Android Things
3.1 Put Them All!
3.2 Installing Android Studio
3.3 Connecting Raspberry Pi to a Network
3.3.1 Wired Network
3.3.2 Wireless Network
3.4 Android Things Console Through Serial Port
3.5 Rebooting
3.6 Shutdown
3.7 Reset WiFi Network Configuration
4. Android Things Hello World - LED Blinking
4.1 Getting Started
4.2 Wiring
4.3 Writing Program
4.3.1 Creating a Project
4.3.2 Writing Program
4.3.4 Building a Project
4.4 Deploying and Testing
4.5 Debugging
4.6 Troubleshooting
5. Raspberry Pi GPIO Programming
5.1 Introduction to GPIO
5.2 Accessing GPIO
5.3 Demo 1: LED and Pushbutton
5.3.1 Wiring
5.3.2 Creating a Project
5.3.3 Writing Codes
5.3.4 Configuring Remote Raspberry Pi
5.3.5 Testing
5.4 Demo 2: 7 Segment Display
5.4.1 Getting Started with 7 Segment Display
5.4.2 Deploying Hardware Wiring
5.4.3 Creating a Project
5.4.4 Writing Codes
5.4.5 Configuring Remote Raspberry Pi
5.4.6 Testing
6. Working with I2C/TWI Protocol
6.1 Getting Started
6.2 Demo 1: Sensor Device Based I2C
6.2.1 Sensor Device Base I2C
6.2.2 Writing Program
6.2.2.1 Creating a Project
6.2.2.2 Writing Codes
6.2.2.3 Configuring Remote Machine
6.2.3 Testing
6.3 Demo 2: Actuator Device Based I2C
6.3.1 Actuator Device
6.3.2 Writing Program
6.3.2.1 Creating a Project
6.3.2.2 Writing Codes
6.3.2.3 Configuring Remote Machine
6.3.3 Testing
7. Working with SPI Protocol
7.1 Getting Started
7.2 Demo: Hello SPI
7.2.1 Hardware Configuration
7.2.2 Writing Program
7.2.3 Testing
8. Working with UART
8.1 Getting Started
8.2 Demo: Hello UART
8.2.1 Configuring Android Things
8.2.2 Hardware Configuration
8.2.3 Writing Program
8.2.4 Testing
Source Code
Contact
Preface

This book was written to help anyone who wants to get started with Android Things for Raspberry Pi 3. It
describes all the basic elements of the Raspberry Pi 3 with step-by-step approach.

Agus Kurniawan

Berlin & Depok, July 2017


1. Introduction to Raspberry Pi 3 and Android Things

1.1 Raspberry Pi 3
The Raspberry Pi is a low cost, credit-card sized computer that plugs into a computer monitor or TV, and
uses a standard keyboard and mouse (source: https://www.raspberrypi.org/help/what-is-a-raspberry-pi/).

Built on the latest Broadcom 2837 ARMv8 64bit processor the new generation Raspberry Pi 3 Model B
is faster and more powerful than its predecessors. It has improved power management to support more
powerful external USB devices and further to customer feedback based development the new Raspberry
Pi 3 now comes with built-in wireless and Bluetooth connectivity.

The following is technical specification of Raspberry Pi 3 device:

Broadcom BCM2837 64bit ARMv8 Quad Core Processor powered Single Board Computer running
at 1.2GHz
1GB RAM
BCM43143 WiFi on board
Bluetooth Low Energy (BLE) on board
40pin extended GPIO
4 x USB2 ports
4 pole Stereo output and Composite video port
Full size HDMI
CSI camera port for connecting the Raspberry Pi camera
DSI display port for connecting the Raspberry Pi touch screen display
MicroSD port for loading your operating system and storing data
Upgraded switched Micro USB power source (now supports up to 2.4 Amps)
Same form factor as the Raspberry Pi 2 Model B, however the LEDs will change position

You can see Raspberry Pi 3 model B device on the Figure below.


1.2 Getting Hardware
How to get Raspberry Pi 3 device?

Officially you can buy it from the official distributor on https://www.raspberrypi.org/products/raspberry-


pi-3-model-b/ .

You also buy Raspberry Pi peripheral devices for instance, keyboard, mouse, HDMI cable, SD card, USB
hub, etc.

I tried to look for buying Raspberry Pi 3 device and found that there are another options to buy

The Pi Hut, http://thepihut.com


EXP-Tech, http://www.exp-tech.de/
Sparkfun, https://www.sparkfun.com
adafruit, https://www.adafruit.com
Ebay, http://www.ebay.com (personal transaction)

You also can buy this board at your local electronics stores.
1.3 Android Things for Raspberry Pi 3
This book will focus on Android Things development for Raspberry Pi 3. Currently, I use Android Things
with Developer Preview 4.1. We can use Windows, Linux and Mac to develop application for Android
Things.
1.4 Unboxing
After bought Raspberry Pi 3 from The Pi Hut (http://thepihut.com), I get the board as follows.
2. Deploying Android Things on Raspberry Pi 3

This chapter explains how to deploy Android Things for Raspberry Pi 3.


2.1 Android Things Image
Raspberry Pi provides some Operating Systems you can use and run on the top of Raspberry Pi. In this
book, we use Android Things on Raspberry Pi 3 board.

Let's start.
2.2 Preparation
If we are working with Raspberry Pi 3 board, we need MicroSD card to extract this OS image file. I use
MicroSD Card 16 GB.
2.3 Flashing Android Things for Raspberry Pi 3
You can download Android Things firmware for Raspberry Pi 3 on this site,
https://developer.android.com/things/preview/download.html. To flash the firmware, you can follow this
instruction as follows:

Linux, https://www.raspberrypi.org/documentation/installation/installing-images/linux.md
Mac, https://www.raspberrypi.org/documentation/installation/installing-images/mac.md
Windows, https://www.raspberrypi.org/documentation/installation/installing-images/windows.md

You can see my flashing process on macOS.


2.4 Attaching Micro SD card on Raspberry Pi 3
After done flashing Android Things on Micro SD card, plug out SD card from computer. Then, plug in it
into Raspberry Pi 3 board.

Now your Raspberry Pi 3 is ready to be deployed OS.


3. Running and Configuring Android Things

In this chapter we start to run Android Things on Raspberry Pi 3 board and then, configure it.
3.1 Put Them All!
Now you are ready to boot your Raspberry Pi. Please plug in all devices, for instance, mouse, keyboard,
power, and HDMI cable, into Raspberry Pi board.

Turn on the power for your Raspberry Pi. Android Things will boot for the first time. Please wait it until
Android Things starting completely.
You should see IP address of Android Things.
3.2 Installing Android Studio
To build application with targeting on Raspberry Pi 3 board, you should install Android Studio. You can
download it on https://developer.android.com/studio/.

You should install Android SDK API 24 or later.

You can see the form of Android Studio with opening a project in Figure below.
3.3 Connecting Raspberry Pi to a Network

3.3.1 Wired Network


Raspberry Pi can connect to LAN easily. Just plug UTP cable into Raspberry Pi 3 board. Android Things
for Raspberry Pi 3, by default, uses DHCP client to configure IP Address.

Your Android Things get Ip Address from DHCP Server automatically.

After obtained IP address for your Android Things, you can connect it from your computer, you can use
adb. Type this command.

$ adb connect <ip_address_android_things>


Now you can entry to Android Things shell through adb. Then, we test to execute a shell command in
Android Things. Type these command.

$ adb shell
rpi3:/ $ uname -a

You should see OS information from Android Things which is shown in Figure below.
Since Android Things is Linux, you can perform Linux shell on Android Things.
3.3.2 Wireless Network
Raspberry Pi 3 has built-in WiFi so we can connect Raspberry Pi board to a WiFi. To configure WiFi on
Android Things, you should connect Raspberry Pi to a network via Ethernet.

Firstly, your computer should be connected to Android Things via adb. Then, run adb in shell mode. After
that, we connect to existing WiFi using this command.

$ am startservice \
-n com.google.wifisetup/.WifiSetupService \
-a WifiSetupService.Connect \
-e ssid <ssid> \
-e passphrase <ssid_key>

Change <ssid> and <ssid_key> for your SSID and its key.

You can verify your connection on Android Things using this command.

$ ifconfig

You should see IP address of Android Things.


If you don't have IP address on Android Things, you can try again or reboot OS. You can reset WiFi
network and then reconfigure WiFi network. See section 3.7 for resetting WiFi settings.

You also configure WiFi via a serial port console. Please read section 3.4.
3.4 Android Things Console Through Serial Port
To debug Raspberry Pi using GPIO serial through computer, we need USB TTL device. There are a lot of
USB TTL device, for instance, USB to TTL Serial Cable - Debug / Console Cable for Raspberry Pi from
Adafruit, http://www.adafruit.com/products/954 .

Another device, you can buy USB to TTL on Cooking-Hacks, http://www.cooking-


hacks.com/index.php/usb-to-ttl-converter-cp210.html .

In this section, I used a Foca V2.1 FT232RL Tiny Breakout USB to Serial UART Interface from
iteadstudio. I bought it on https://www.itead.cc/foca.html.
How to implement?

It's easy. You can just connect Tx from USB TTL to Raspberry Pi UART0 (TXD) and USB TTL RX to
Raspberry Pi UART0 (RXD). Some USB TTL must change them. It means USB TTL TX should be
connected to Raspberry Pi UART0 (RXD) and USB TTL RX to Raspberry Pi UART0 (TXD). (Optional)
You can connect GND from USB TTL to GND of Raspberry Pi board.

You can see Raspberry Pi 3 pinout in Figure below.


Here is a sample of connected hardware.
Now your USB cable of USB TTL device is be connected to your computer. You can use any serial
application to execute.

In this book, I used PuTTY, http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html, and run it


on my Windows OS. For cross platforms, you can use CoolTerm. You can download it on
http://freeware.the-meiers.org. You can use another serial tool to communicate with Android Things OS.

You can see CoolTerm application on macOS in Figure below.


Select your serial port with baudrate 115200.
Select CR on Enter Key Emulation.
After configured, you can connect.

If you don't see anything, please press ENTER so you can see Android Things terminal. You can perform
shell commands on Android Things.
Using a serial tool, you can configure WiFi or perform Linux shell as usual.
3.5 Rebooting
If you want to reboot your Raspberry Pi, write this command from remote Command Prompt.

$ reboot
3.6 Shutdown
It's better to shutdown your Raspberry Pi If you don't use it. Please don't turn off the power directly.

Write this script to shutdown and turn off your Raspberry Pi

$ reboot -p

Now you can turn off your Raspberry Pi board.


3.7 Reset WiFi Network Configuration
You may get problems on WiFi network. You can reset your WiFi network on Android Things. You can
type this command on Terminal of Android Things either via serial console or network from Ethernet.

$ am startservice \
-n com.google.wifisetup/.WifiSetupService \
-a WifiSetupService.Reset

After that, you should reboot Android Things.


4. Android Things Hello World - LED Blinking

This chapter explains how to build application for Android Things in Raspberry Pi 3.
4.1 Getting Started
In this section, we learn how to get started with Android programming on Android Things. We build LED
blinking application. We use 3 LEDs to illustrate our case.
4.2 Wiring
In this section, we learn how to write data using GPIO on Raspberry Pi. We can use 3 LEDs to illustrate
our case.

Our LEDs are connected to GPIO pins: BCM17, BCM27, and BCM22. LED ground pin is connected to
GPIO GND.

The following is Raspberry Pi 3 GPIO layout.


The following is our demo wiring.
4.3 Writing Program
In this section, we develop program to access Raspberry Pi GPIO using Android Things.

4.3.1 Creating a Project


Firstly, open Android Studio application. Then, click Start a new Android Studio project.

Fill your project name, for instance, BlinkLED. You also can configure company domain and project path.
Click Next button to continue.
Select Minimum SDK. You should set minimum SDK API 24 for Android Things. Click Next button to
continue.
Select Empty Activity for project template. Click Next button to continue.
Now you modify activity name. If done, click Finish.
Now you can see your project on Android Studio.
4.3.2 Writing Program
We modify our codes on several files that are shown in Figure below.
Firstly, we modify build. gradle file (Module: app). Please add to Android Things SDK. Currently, this
book uses SDK 0.4.1 preview.

dependencies {
...

provided 'com.google.android.things:androidthings:0.4.1-devpreview'
}

On AndroidManifest.xml file, you should add the following

<intent-filter>
<action android:name="android.intent.action.M
<category android:name="android.intent.catego
<category android:name="android.intent.catego
</intent-filter>

We also add Android Things SDK under <application> tag.

<application
..... >
.......

<uses-library android:name="com.google.android.things"/>
</application>

Now we write a program on MainActivity. In this scenario, we turn on one LED and move one LED to
other LED. We use a thread with timer to turn on/off LED. Firstly, we add all required libraries on our
project.

import java.io.IOException;

import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.PeripheralManagerService;
import android.util.Log;
import android.os.Handler;

We also define variables for our project.

public class MainActivity extends AppCompatActivity {


private static final String TAG = "MainActivity";
private static final int INTERVAL_BETWEEN_BLINKS_MS = 1000;
private static final String LED1_PIN = "BCM17";
private static final String LED2_PIN = "BCM27";
private static final String LED3_PIN = "BCM22";
private Handler mHandler = new Handler();
private Gpio mLed1;
private Gpio mLed2;
private Gpio mLed3;
private int mState;

On onCreate() method, we initialize all GPIO pins. Then, we activate our timer that uses mBlinkRunnable
function.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

PeripheralManagerService service = new PeripheralManagerService();


try {
mLed1 = service.openGpio(LED1_PIN);
mLed1.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
mLed2 = service.openGpio(LED2_PIN);
mLed2.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

mLed3 = service.openGpio(LED3_PIN);
mLed3.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}

mState = 1;
mHandler.post(mBlinkRunnable);
}

We add onDestroy() to clear all resource usages included timer.

@Override
protected void onDestroy() {
super.onDestroy();

mHandler.removeCallbacks(mBlinkRunnable);

// Clean all resources


if (mLed1 != null) {
try {
mLed1.setValue(false);
mLed1.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
if (mLed2 != null) {
try {
mLed2.setValue(false);
mLed2.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
if (mLed3 != null) {
try {
mLed3.setValue(false);
mLed3.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
}
We implement our time in run() function from Runnable function. In this scenario, we turn on LED based
on current state, mState.

private Runnable mBlinkRunnable = new Runnable() {


@Override
public void run() {
if (mLed1 == null) return;
if (mLed2 == null) return;
if (mLed3 == null) return;

try {
mLed1.setValue(false);
mLed2.setValue(false);
mLed3.setValue(false);

switch(mState){
case 1:
mLed1.setValue(true);
break;
case 2:
mLed2.setValue(true);
break;
case 3:
mLed3.setValue(true);
break;
}
Log.i(TAG, "Turn on LED: " + mState);
mState++;
if(mState>3)
mState = 1;

mHandler.postDelayed(mBlinkRunnable, INTERVAL_BETWEEN_BLINKS_MS);
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
};

Save all files.

4.3.4 Building a Project


Now you can build your prpject. Please see the following figure which is signed by red arrows (Make)
for building a project.
4.4 Deploying and Testing
If your program doesn't get errors on compiling, then you can run this program. Click Run icon to deploy
and run the program.

You will be asked which Android Things device will be deployed. You should see your connected
Raspberry Pi 3 with installed Android Things.

If you don't have this option, you should connect your Raspberry Pi 3 with Android Things to your
computer via adb. Type this command.

$ adb connect <ip_address_android_things>


If succeed in deployment, you should see LEDs are blinking.

On Android Monitor from Android Studio, you can see messages from the program. It shows a message
about current lighting on LED.
4.5 Debugging
We can debug our program. Just set breakpoints on your code.

After that, you can run debug by click menu Debug.

The debugger will stop on your breakpoints.


4.6 Troubleshooting
If you have problems while running or debugging a program with error message
"android.os.ServiceSpecificException: I/O error", it means your GPIO pins are being used. You need
clear or remove your program from Android Things. You can type this command on adb.

$ adb shell pm clear com.book.agusk.blinkled

Suppose com.book.agusk.blinkled is application that will be removed from Android Things.

You can know a list of running application on Android Things using this command.

$ adb shell ps | grep u0_


5. Raspberry Pi GPIO Programming

This chapter explains how to work with GPIO on Raspberry Pi 3 with Android Things.
5.1 Introduction to GPIO
General-purpose input/output (GPIO) is a generic pin on an integrated circuit whose behavior, including
whether it is an input or output pin, can be controlled by the user at run time. GPIO pins have no special
purpose defined, and go unused by default.

To understand GPIO on Raspberry Pi 3 board, you can see it in Figure below.


5.2 Accessing GPIO
In this section, we will learn how to access Raspberry Pi GPIO using Gpio object. On previous chapter,
we already used it on LED Blinking demo. In general, you can read the documentation about Gpio on
https://developer.android.com/things/sdk/pio/gpio.html.

To illustrate how to use Raspberry Pi GPIO, we implement two demo:

LED and pushbutton


7-segment display

Let's start.
5.3 Demo 1: LED and Pushbutton
We build a simple demo to illustrate I/O on Raspberry Pi GPIO. W need a pushbutton and LED. If you
press pushbutton, LED will lighting. Otherwise, it will off.

5.3.1 Wiring
Connect your LED into GPIO BCM17 and pushbutton on GPIO BCM27. The following is our wiring.

5.3.2 Creating a Project


Create a project, call ButtonLED, on Android Studio. Please follow instructions on section 4.3.1 and
4.3.2.

5.3.3 Writing Codes


Firstly, we modify build. gradle (Module: app) and AndroidManifest.xml files. Please read section 4.3.2.

In this demo, we use user library, driver-button, so we load this library on build. gradle file (Module:
app).
dependencies {
.....

provided 'com.google.android.things:androidthings:0.4.1-devpreview'
compile 'com.google.android.things.contrib:driver-button:0.3'
}

Now we focus on MainActivity program. The idea of program is to detect if a button is pressed or not. If
pressed, we turn on a LED.

Firstly, we add all required libraries on our project.

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.PeripheralManagerService;
import com.google.android.things.contrib.driver.button.Button;

import java.io.IOException;

We also define variables for our project.

public class MainActivity extends AppCompatActivity {


private static final String TAG = "MainActivity";
private static final String LED_PIN = "BCM17";
private static final String BUTTON_PIN = "BCM27";
private Gpio mLed;
private Button mButton;

On onCreate() method, we initialize all GPIO pins. Then, we activate setOnButtonEventListener event to
listen button clicked event.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

PeripheralManagerService service = new PeripheralManagerService();


try {
mLed = service.openGpio(LED_PIN);
mLed.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
mButton = new Button(
BUTTON_PIN,
Button.LogicState.PRESSED_WHEN_HIGH);
mButton.setOnButtonEventListener(new Button.OnButtonEventListener()
@Override
public void onButtonEvent(Button button, boolean pressed) {

try {
mLed.setValue(pressed);
} catch (IOException e) {
Log.e(TAG, "Error closing Led", e);
}

}
});

} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}

We add onDestroy() to clear all resource usages.

@Override
protected void onDestroy(){
super.onDestroy();

// Clear all resources


if (mLed != null) {
try {
mLed.close();
} catch (IOException e) {
Log.e(TAG, "Error closing Led", e);
}
}
if (mButton != null) {
try {
mButton.close();
} catch (IOException e) {
Log.e(TAG, "Error closing Button driver", e);
}
}
}

Save this code.


5.3.4 Configuring Remote Raspberry Pi
We must connect Android Things on your computer. Please follow instructions on chapter 3 and 4.

5.3.5 Testing
Now you can deploy and execute program into Android Things on Raspberry Pi 3 board.

Press pushbutton to get a response from the program. After pressed, you should see the lighting LED.
5.4 Demo 2: 7 Segment Display

In this section, we're going to build an application to display a number from 0 to 9 on 7 segment display
device. This device will be connected to Raspberry Pi via GPIO and then we develop application to
illustrate how to write data to GPIO.

Let's start.

5.4.1 Getting Started with 7 Segment Display


To understand 7 segment display, I refer to a datasheet from SA56-11GWA and SC56-11GWA ,
http://www.kitronik.co.uk/pdf/7_segment_display_datasheet.pdf . The following is device schema.
The following is a sample physical of 7 segment display.
5.4.2 Deploying Hardware Wiring
The next step, we must connect our 7 segment to Raspberry Pi. For testing, I used 7-segment common
cathode model.

Here is pin configuration from 7 segment display to Raspberry Pi.

pin a ----> GPIO 18


pin b ----> GPIO 23
pin c ----> GPIO 24
pin dip ----> GPIO 25
pin d ----> GPIO 12
pin e ----> GPIO 16
pin f ----> GPIO 26
pin g ----> GPIO 13

Unlabeled pins are be connected to Raspberry Pi GND.

The following is a hardware implementation for connecting 7 segment display to Raspberry Pi.
5.4.3 Creating a Project
Create a project, call SevenSegment, on Android Studio. Please follow instructions on section 4.3.1 and
4.3.2.

5.4.4 Writing Codes


Firstly, we modify build. gradle (Module: app) and AndroidManifest.xml files. Please read section 4.3.2.

Now we focus on MainActivity program file. We declare all required libraries that will be used.

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import java.io.IOException;
import com.google.android.things.pio.Gpio;
import com.google.android.things.pio.PeripheralManagerService;
import android.util.Log;
import android.os.Handler;

Declare variables for all GPIO pins of 7-segment and timer.

public class MainActivity extends AppCompatActivity {


private static final String TAG = "MainActivity";
private static final int INTERVAL_BETWEEN_BLINKS_MS = 1000;
private static final String SEVEN_A_PIN = "BCM17";
private static final String SEVEN_B_PIN = "BCM27";
private static final String SEVEN_C_PIN = "BCM22";
private static final String SEVEN_D_PIN = "BCM23";
private static final String SEVEN_E_PIN = "BCM24";
private static final String SEVEN_F_PIN = "BCM25";
private static final String SEVEN_G_PIN = "BCM5";
private static final String SEVEN_DP_PIN = "BCM6";
private Handler mHandler = new Handler();
private Gpio mSevenA;
private Gpio mSevenB;
private Gpio mSevenC;
private Gpio mSevenD;
private Gpio mSevenE;
private Gpio mSevenF;
private Gpio mSevenG;
private Gpio mSevenDP;
private int mState;

On onCreate() method, we initialize all GPIO pins. Then, we activate timer, mSevenSegmentRunnable.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

PeripheralManagerService service = new PeripheralManagerService();


try {
mSevenA = service.openGpio(SEVEN_A_PIN);
mSevenA.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

mSevenB = service.openGpio(SEVEN_B_PIN);
mSevenB.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

mSevenC = service.openGpio(SEVEN_C_PIN);
mSevenC.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

mSevenD = service.openGpio(SEVEN_D_PIN);
mSevenD.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

mSevenE = service.openGpio(SEVEN_E_PIN);
mSevenE.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

mSevenF = service.openGpio(SEVEN_F_PIN);
mSevenF.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

mSevenG = service.openGpio(SEVEN_G_PIN);
mSevenG.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

mSevenDP = service.openGpio(SEVEN_DP_PIN);
mSevenDP.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);

} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
mState = 1;
mHandler.post(mSevenSegmentRunnable);
}

We add onDestroy() to clear all resource usages.

@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mSevenSegmentRunnable);

// Clean all resources


if (mSevenA != null) {
try {
mSevenA.setValue(false);
mSevenA.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
if (mSevenB != null) {
try {
mSevenB.setValue(false);
mSevenB.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
if (mSevenC != null) {
try {
mSevenC.setValue(false);
mSevenC.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
if (mSevenD != null) {
try {
mSevenD.setValue(false);
mSevenD.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
if (mSevenE != null) {
try {
mSevenE.setValue(false);
mSevenE.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
if (mSevenF != null) {
try {
mSevenF.setValue(false);
mSevenF.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
if (mSevenG != null) {
try {
mSevenG.setValue(false);
mSevenG.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
if (mSevenDP != null) {
try {
mSevenDP.setValue(false);
mSevenDP.close();
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
}

To display a number on seven segment device, we define a function, called showNumber().

private void showNumber(int num){

try {
// set all leds off
mSevenA.setValue(false);
mSevenB.setValue(false);
mSevenC.setValue(false);
mSevenD.setValue(false);
mSevenE.setValue(false);
mSevenF.setValue(false);
mSevenG.setValue(false);
mSevenDP.setValue(false);

switch(num){
case 0:
mSevenA.setValue(true);
mSevenB.setValue(true);
mSevenA.setValue(true);
mSevenA.setValue(true);
mSevenA.setValue(true);
mSevenA.setValue(true);
mSevenA.setValue(false);
mSevenDP.setValue(true);
break;
case 1:
mSevenA.setValue(false);
mSevenB.setValue(true);
mSevenC.setValue(true);
mSevenD.setValue(false);
mSevenE.setValue(false);
mSevenF.setValue(false);
mSevenG.setValue(false);
mSevenDP.setValue(true);
break;
case 2:
mSevenA.setValue(true);
mSevenB.setValue(true);
mSevenC.setValue(false);
mSevenD.setValue(true);
mSevenE.setValue(true);
mSevenF.setValue(false);
mSevenG.setValue(true);
mSevenDP.setValue(true);
break;
case 3:
mSevenA.setValue(true);
mSevenB.setValue(true);
mSevenC.setValue(true);
mSevenD.setValue(true);
mSevenE.setValue(false);
mSevenF.setValue(false);
mSevenG.setValue(true);
mSevenDP.setValue(true);
break;
case 4:
mSevenA.setValue(false);
mSevenB.setValue(true);
mSevenC.setValue(true);
mSevenD.setValue(false);
mSevenE.setValue(false);
mSevenF.setValue(true);
mSevenG.setValue(true);
mSevenDP.setValue(true);
break;
case 5:
mSevenA.setValue(true);
mSevenB.setValue(false);
mSevenC.setValue(true);
mSevenD.setValue(true);
mSevenE.setValue(false);
mSevenF.setValue(true);
mSevenG.setValue(true);
mSevenDP.setValue(true);
break;
case 6:
mSevenA.setValue(true);
mSevenB.setValue(false);
mSevenC.setValue(true);
mSevenD.setValue(true);
mSevenE.setValue(true);
mSevenF.setValue(true);
mSevenG.setValue(true);
mSevenDP.setValue(true);
break;
case 7:
mSevenA.setValue(true);
mSevenB.setValue(true);
mSevenC.setValue(true);
mSevenD.setValue(false);
mSevenE.setValue(false);
mSevenF.setValue(false);
mSevenG.setValue(false);
mSevenDP.setValue(true);
break;
case 8:
mSevenA.setValue(true);
mSevenB.setValue(true);
mSevenC.setValue(true);
mSevenD.setValue(true);
mSevenE.setValue(true);
mSevenF.setValue(true);
mSevenG.setValue(true);
mSevenDP.setValue(true);
break;
case 9:
mSevenA.setValue(true);
mSevenB.setValue(true);
mSevenC.setValue(true);
mSevenD.setValue(true);
mSevenE.setValue(false);
mSevenF.setValue(true);
mSevenG.setValue(true);
mSevenDP.setValue(true);
break;
}
Log.i(TAG, "Seven segment: " + num);
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}

We implement our timer on mSevenSegmentRunnable. In this function, we set a number on seven segment
by calling showNumber() function.

private Runnable mSevenSegmentRunnable = new Runnable() {


@Override
public void run() {
if (mSevenA == null) return;
if (mSevenB == null) return;
if (mSevenC == null) return;
if (mSevenD == null) return;
if (mSevenE == null) return;
if (mSevenF == null) return;
if (mSevenG == null) return;
if (mSevenDP == null) return;

showNumber(mState);
mState++;
if(mState>9)
mState = 0;

mHandler.postDelayed(mSevenSegmentRunnable, INTERVAL_BETWEEN_BLINKS_M
}
};

Save all codes. Try to compile.

5.4.5 Configuring Remote Raspberry Pi


We must connect Android Things on your computer. Please follow instructions on chapter 3 and 4.

5.4.6 Testing
You can compile your project. Deploy and execute your program. You should see a number on 7-segment
display module.

The following is a sample output on 7-segment display.


You also see the program output on Android Monitor output on Android Studio.
6. Working with I2C/TWI Protocol

This chapter explains how to work with I2C on Raspberry Pi 3 board and write program to access I2C.
6.1 Getting Started
The I2C (Inter-Integrated Circuit) bus was designed by Philips in the early '80s to allow easy
communication between components which reside on the same circuit board. TWI stands for Two Wire
Interface and for most marts this bus is identical to I²C. The name TWI was introduced by Atmel and other
companies to avoid conflicts with trademark issues related to I²C.

I2C bus consists of two wires, SDA (Serial Data Line) and SCL (Serial Clock Line). The following is
I2C bus on Raspberry Pi 3 board.
To connect device via I2C, you can do the following connection.

You should define which to be master and slave.

We also can define 1 master and two slave devices.

There are many devices which use I2C to communicate to other. The following is a list of sample device
with I2C enabled:

EEPROM IC with I2C support


ADC/DAC with I2C support, for instance, http://www.adafruit.com/product/935
Real Time Clock (RTC), http://www.adafruit.com/products/264
LCD+Keypad module with I2C support, for instance, http://www.adafruit.com/product/1109
For testing, I used PCF8591 AD/DA Converter module with sensor and actuator devices. You can find it
on the following online store:

Amazon, http://www.amazon.com/PCF8591-Converter-Module-Digital-
Conversion/dp/B00BXX4UWC/
eBay, http://www.ebay.com
Dealextreme, http://www.dx.com/p/pcf8591-ad-da-analog-to-digital-digital-to-analog-converter-
module-w-dupont-cable-deep-blue-336384
Aliexpress, http://www.aliexpress.com/

In addition, you can find this device on your local electronics store/online store.

This module has mini form model too, for instance, you can find it on Amazon,
http://www.amazon.com/WaveShare-PCF8591T-Converter-Evaluation-Development/dp/B00KM6X2OI/ .
This module use PCF8591 IC and you can read the datasheet on the following URLs.

http://www.electrodragon.com/w/images/e/ed/PCF8591.pdf
http://www.nxp.com/documents/data_sheet/PCF8591.pdf

On Android Things for Raspberry Pi 3, we can access I2C using I2cDevice object,
https://developer.android.com/things/reference/com/google/android/things/pio/I2cDevice.html .
6.2 Demo 1: Sensor Device Based I2C
The objective of this section is to illustrate how to read data on I2C bus. We use PCF8591 AD/DA
converter with sensor devices as I2C external source. You can read this module on this link,
http://www.electrodragon.com/w/images/8/89/PCF8591_ADC_DAC_ADDA_Analog_Digital_Converter_
. In our scenario, we will read three sensor devices in PCF8591 AD/DA modules via I2C.

Let's start!.

6.2.1 Sensor Device Base I2C


Now you can connect your PCF8591 AD/DA to Raspberry Pi 3 board . The following is demo wiring :

Module SCL --> Raspberry Pi board SCL


Module SDA --> Raspberry Pi board SDA
Module VCC ---> Raspberry Pi board +3.3V
Module GND ---> Raspberry Pi board GND

The following is a sample of hardware implementation.

6.2.2 Writing Program


In this section, we build a program to access sensor via I2C port. We create a timer to read sensor through
I2C protocol.

6.2.2.1 Creating a Project

Create a project, call I2CDemo, on Android Studio. Please follow instructions on section 4.3.1 and
4.3.2.

6.2.2.2 Writing Codes

Firstly, we modify build. gradle (Module: app) and AndroidManifest.xml files. Please read section 4.3.2.

Now we focus on MainActivity program file. We declare all required libraries that will be used.

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.things.pio.I2cDevice;
import com.google.android.things.pio.PeripheralManagerService;

import java.io.IOException;

Declare variables for I2C pins and timer.

public class MainActivity extends AppCompatActivity {


private static final String TAG = "MainActivity";
private static final String TAGI2C = "I2C";
private static final int INTERVAL_BETWEEN_I2C_MS = 2000;
private static final String I2C_DEVICE_NAME = "I2C1";
private static final int I2C_PCF8591 = 0x48;
private static final byte I2C_PCF8591_CH0 = 0x40;
private static final byte I2C_PCF8591_CH1 = 0x41;
//private static final byte I2C_PCF8591_CH2 = 0x42; // unused
private static final byte I2C_PCF8591_CH3 = 0x43;
private Handler mHandler = new Handler();
private I2cDevice mDevice;
private int mState;
On onCreate() method, we initialize I2C pins. Then, we activate timer, mI2cRunnable.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

PeripheralManagerService manager = new PeripheralManagerService();


try {

mDevice = manager.openI2cDevice(I2C_DEVICE_NAME, I2C_PCF8591);

} catch (IOException e) {
Log.w(TAG, "Unable to access I2C device", e);
}
mState = 1;
mHandler.post(mI2cRunnable);

We add onDestroy() to clear all resource usages.

@Override
protected void onDestroy() {
super.onDestroy();

if (mDevice != null) {
try {
mDevice.close();
mDevice = null;
} catch (IOException e) {
Log.w(TAG, "Unable to close I2C device", e);
}
}
}

We implement our timer on mI2cRunnable. In this function, we set analog value through I2C.

private Runnable mI2cRunnable = new Runnable() {


@Override
public void run() {
if (mDevice == null) return;

try {

if(mState==1) {
// read i2c : thermistor
mDevice.writeRegByte(I2C_PCF8591_CH0, (byte)1);
byte[] buffer = new byte[2];
mDevice.read(buffer, buffer.length);
Log.i(TAGI2C, "Thermistor: " + buffer[1]);
}
if(mState==2) {
// read i2c : photo-voltaic cell
mDevice.writeRegByte(I2C_PCF8591_CH1, (byte)1);
byte[] buffer = new byte[2];
mDevice.read(buffer, buffer.length);
Log.i(TAGI2C, "Photo-voltaic: " + buffer[1]);
}

if(mState==3) {
// read i2c : potentiometer
mDevice.writeRegByte(I2C_PCF8591_CH3, (byte)1);
byte[] buffer = new byte[2];
mDevice.read(buffer, buffer.length);
Log.i(TAGI2C, "Potentiometer: " + buffer[1]);
}
mState++;
if(mState>3)
mState = 1;

mHandler.postDelayed(mI2cRunnable, INTERVAL_BETWEEN_I2C_MS);
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}

}
};

Save this code.

6.2.2.3 Configuring Remote Machine

We must connect Android Things on your computer. Please follow instructions on chapter 3 and 4.

6.2.3 Testing
Now you can compile and upload the program to the board in debugging mode.

The following is a sample output on Android Monitor output.


6.3 Demo 2: Actuator Device Based I2C
The objective of this section is to illustrate how to read data on I2C bus. We use PCF8591 AD/DA
converter module with actuator device as I2C external source. This module has an actuator, LED. We pass
a digital value between 0 and 255 to the module.

Let's start!.

6.3.1 Actuator Device


You can see an actuator device, LED, on PCF8591 AD/DA converter module in Figure below. See red
arrow.

6.3.2 Writing Program


In this section, we build a program to access actuator via I2C port.

6.3.2.1 Creating a Project


Create a project, call I2CDemoActuator, on Android Studio. Please follow instructions on section 4.3.1
and 4.3.2.

6.3.2.2 Writing Codes

Firstly, we modify build. gradle (Module: app) and AndroidManifest.xml files. Please read section 4.3.2.

Now we focus on MainActivity program file. We declare all required libraries that will be used.

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.things.pio.I2cDevice;
import com.google.android.things.pio.PeripheralManagerService;

import java.io.IOException;

Declare variables for I2C pins and timer.

public class MainActivity extends AppCompatActivity {


private static final String TAG = "MainActivity";
private static final String TAGI2C = "I2C";
private static final int INTERVAL_BETWEEN_I2C_MS = 2000;
private static final String I2C_DEVICE_NAME = "I2C1";
private static final int I2C_PCF8591 = 0x48;
//private static final byte I2C_PCF8591_CH0 = 0x40;
//private static final byte I2C_PCF8591_CH1 = 0x41;
private static final byte I2C_PCF8591_CH2 = 0x42;
//private static final byte I2C_PCF8591_CH3 = 0x43;
private Handler mHandler = new Handler();
private I2cDevice mDevice;
private byte analogVal;

On onCreate() method, we initialize I2C pins. Then, we activate timer, mI2cRunnable.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

PeripheralManagerService manager = new PeripheralManagerService();


try {

mDevice = manager.openI2cDevice(I2C_DEVICE_NAME, I2C_PCF8591);

} catch (IOException e) {
Log.w(TAG, "Unable to access I2C device", e);
}
analogVal = 0;
mHandler.post(mI2cRunnable);
}

We add onDestroy() to clear all resource usages.

@Override
protected void onDestroy() {
super.onDestroy();

if (mDevice != null) {
try {
mDevice.close();
mDevice = null;
} catch (IOException e) {
Log.w(TAG, "Unable to close I2C device", e);
}
}
}

We implement our timer on mI2cRunnable. In this function, we set analog value through I2C.

private Runnable mI2cRunnable = new Runnable() {


@Override
public void run() {
if (mDevice == null) return;

try {
mDevice.writeRegByte(I2C_PCF8591_CH2, analogVal);
Log.i(TAGI2C,"Write I2C: " + analogVal);

analogVal += 15;
if(analogVal>255)
analogVal = 0;

mHandler.postDelayed(mI2cRunnable, INTERVAL_BETWEEN_I2C_MS);
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}

}
};

Save this code.

6.3.2.3 Configuring Remote Machine

We must connect Android Things on your computer. Please follow instructions on chapter 3 and 4.

6.3.3 Testing
Now you can compile and upload program to a board on debugging mode. Then, you can see program
output on Android Monitor output.

On PCF8591 AD/DA converter module, you can a red LED is dimming. A sample output can be seen in
Figure below.
7. Working with SPI Protocol

This chapter explains how to work with SPI on Raspberry Pi 3 board for Android Things.
7.1 Getting Started
The Serial Peripheral Interface (SPI) is a communication bus that is used to interface one or more slave
peripheral integrated circuits (ICs) to a single master SPI device; usually a microcontroller or
microprocessor of some sort. Raspberry Pi 3 has two SPI ports.

SPI in Raspberry can be defined on the following pins: SPI0:

MOSI (GPIO 19)


MISO (GPIO 21)
SCLK (GPIO 23)
CS0 (GPIO 24)
CS1 (GPIO 26)

You can see these pins on the Raspberry Pi GPIO pins, shown in Figure below.
Pi works as SPI Master. If you want to connect to SPI Slave Devices, you can connect with the following
configuration.
(image source: http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus)
7.2 Demo: Hello SPI
The objective of the first demo is to get started how to work with SPI on Raspberry Pi 3 board. In this
scenario, we apply SPI loopback. To access SPI, we can use objects from SpiDevice object,
https://developer.android.com/things/reference/com/google/android/things/pio/SpiDevice.html.

The following is our scenario:

Send 2 byte data to SPI0


Receive 2 byte from SPI0

Because we build SPI loopback, we will receive what we sent.

Let's start.

7.2.1 Hardware Configuration


Hardware configuration is easy. You just connect MOSI and MISO pins with each other. In this demo, I
used SPI0 on Raspberry Pi 3 board so I connect MOSI (GPIO 19) pin to MISO (GPIO 21) pin through a
jumper cable.

The following is a sample of hardware configuration.


7.2.2 Writing Program
Firstly, we modify build. gradle (Module: app) and AndroidManifest.xml files. Please read section 4.3.2.

Now we focus on MainActivity program file. We declare all required libraries that will be used.

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.things.pio.PeripheralManagerService;
import com.google.android.things.pio.SpiDevice;

import java.io.IOException;
import java.util.Random;

Declare variables for all SPI program and timer.


public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int INTERVAL_BETWEEN_SPI_MS = 2000;
private static final String SPI_DEVICE_NAME = "SPI0.0";
private Handler mHandler = new Handler();
private SpiDevice mDevice;

On onCreate() method, we initialize SPI pins. Then, we activate timer, mSpiRunnable.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

try {
PeripheralManagerService manager = new PeripheralManagerService();
mDevice = manager.openSpiDevice(SPI_DEVICE_NAME);
} catch (IOException e) {
Log.w(TAG, "Unable to access SPI device", e);
}
mHandler.post(mSpiRunnable);
}

We add onDestroy() to clear all resource usages.

@Override
protected void onDestroy() {
super.onDestroy();

if (mDevice != null) {
try {
mDevice.close();
mDevice = null;
} catch (IOException e) {
Log.w(TAG, "Unable to close SPI device", e);
}
}
}

To display byte to string, we define a function, called bytesToHexString().

private String bytesToHexString(byte[] bytes)


{
StringBuilder sb = new StringBuilder();
for(byte b : bytes){
sb.append(String.format("%02x ", b&0xff));
}

return sb.toString();
}

We implement our timer on mSpiRunnable. In this function, we generate radom byte values that will be
used to send to SPI protocol. We prepare rx variable to receive data from SPI. We call
bytesToHexString() to display byte to String.

private Runnable mSpiRunnable = new Runnable() {


@Override
public void run() {
if (mDevice == null) return;

try {
byte[] tx = new byte[2];
byte[] rx = new byte[2];

new Random().nextBytes(tx);
mDevice.transfer(tx, rx, tx.length);

Log.i(TAG,"Send: " + bytesToHexString(tx));


Log.i(TAG,"Recv: " + bytesToHexString(rx));

mHandler.postDelayed(mSpiRunnable, INTERVAL_BETWEEN_SPI_MS);
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}

}
};

Save all codes. Try to compile.

Save this code.

7.2.3 Testing
Compile and upload your program to remote Raspberry Pi 3 board. You should see sent and received data
on Android Monitor output.
A sample output can be seen in Figure below.
8. Working with UART

This chapter explains how to work with UART on Raspberry Pi 3 board for Android Things.
8.1 Getting Started
UART in Raspberry can be defined on the following pins:

UART0:

UART0 TX (pin 8)
UART0 RX (pin 10)

You can see these pins on the Raspberry Pi GPIO pins, shown in Figure below.
8.2 Demo: Hello UART
The objective of the first demo is to get started how to work with UART on Raspberry Pi 3 board. In this
scenario, we send data to UART and then receive it via. To access UART, we can use objects from
UartDevice,
https://developer.android.com/things/reference/com/google/android/things/pio/UartDevice.html.

The following is our scenario:

Send 2 byte data to UART0


Receive 2 byte from UART0 using serial device

We need a serial hardware to read data from Raspberry Pi UART. You can read section 3.4.

Let's start.
8.2.1 Configuring Android Things
By default, Android Things uses UART pins on Raspberry Pi as serial console. If we want to use UART
pins, you should disable a serial console on Raspberry Pi.

Firstly, unplug a micro SD card from Raspberry Pi to your computer. Please follows the instructions on
https://developer.android.com/things/hardware/raspberrypi.html.

For instance, I perform this task on macOS.

Open Terminal and type this command.

$ sudo mkdir -p /Volumes/pisdcard


$ diskutil list

You should see disk list. My micro SD is detected on /dev/disk2.


Now you can mount your micro SD card into your computer. Then, you open cmdline.txt file.

$ sudo mount -t msdos /dev/disk2s1 /Volumes/pisdcard


$ cd /Volumes/pisdcard
$ nano cmdline.txt

You should see a content of cmdline.txt file.


Please change "console=serial0,115200" to "console=tty0". Save this file.
Now you should modify config.txt.

Add “dtoverlay=pi3-disable-bt” into the file. Then, remove or comment these codes enabled_uart=1

core_freq=400

Save all changes.

8.2.2 Hardware Configuration


Hardware configuration is easy. You just connect the following scheme:

Tx from serial hardware to UART0 (RXD) Raspberry Pi


Rx from serial hardware to UART0 (TXD) Raspberry Pi

The following is a sample of hardware configuration.


8.2.3 Writing Program
Firstly, we modify build. gradle (Module: app) and AndroidManifest.xml files. Please read section 4.3.2.

Now we focus on MainActivity program file. We declare all required libraries that will be used.

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.things.pio.PeripheralManagerService;
import com.google.android.things.pio.UartDevice;

import java.io.IOException;
import java.util.Random;

Declare variables for UART pins and timer.

public class MainActivity extends AppCompatActivity {


private static final String TAG = "MainActivity";
private static final int INTERVAL_BETWEEN_UART_MS = 2000;
private static final String UART_DEVICE_NAME = "UART0";
private Handler mHandler = new Handler();
private UartDevice mDevice;
On onCreate() method, we initialize UART pins. Then, we activate timer, mUartRunnable.

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

try {
PeripheralManagerService manager = new PeripheralManagerService();
mDevice = manager.openUartDevice(UART_DEVICE_NAME);

} catch (IOException e) {
Log.w(TAG, "Unable to access UART device", e);
}
mHandler.post(mUartRunnable);
}

We add onDestroy() to clear all resource usages.

@Override
protected void onDestroy() {
super.onDestroy();

if (mDevice != null) {
try {
mDevice.close();
mDevice = null;
} catch (IOException e) {
Log.w(TAG, "Unable to close UART device", e);
}
}
}

We define a function, bytesToHexString(), to convert byte array to Hex string.

private String bytesToHexString(byte[] bytes)


{
StringBuilder sb = new StringBuilder();
for(byte b : bytes){
sb.append(String.format("%02x ", b&0xff));
}

return sb.toString();
}
We implement our timer on mUartRunnable. In this function, we send data through UART.

private Runnable mUartRunnable = new Runnable() {


@Override
public void run() {
if (mDevice == null) return;

try {
byte[] tx = new byte[2];

new Random().nextBytes(tx);

int count = mDevice.write(tx, tx.length);


Log.i(TAG,"Send: " + bytesToHexString(tx) + " . Len: " + count);

mHandler.postDelayed(mUartRunnable, INTERVAL_BETWEEN_UART_MS);
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}

}
};

Save this code.

8.2.4 Testing
Compile and upload your program to remote Raspberry Pi 3 board. You should see sent data on Android
Monitor console.

A sample output can be seen in Figure below.


To see received data, you can open a serial tool such as CoolTerm. Then, open a serial port of serial
hardware. Configure to use baudrate 9600 because we don't set baudrate on the code.
Change to Hex view so you can see the received data in Hex format. A sample of program output in
Figure below.
Source Code

Source code can be downloaded on http://www.aguskurniawan.net/book/things121292.zip .


Contact

If you have question related to this book, please contact me at aguskur@hotmail.com . My


blog: http://blog.aguskurniawan.net .

This book was downloaded from AvaxHome!

Visit my blog for more new books:

www.avxhm.se/blogs/AlenMiler

Вам также может понравиться