Welcome to the first, of hopefully many, part of my AndroidThings tutorial. I wanted to have a way of learning more myself and also share some of the things I've picked up along the way about AndroidThings. This series is made for anyone who wants to learn more about AndroidThings and created by the HacksterMIA community. Hopefully this becomes useful for many others!
With that lets get started!
What is AndroidThings?Before diving into messing with AndroidThings, its important to know what it is and why its so cool! AndroidThings is new IoT platform made by Google, and more importantly it runs Android. Here's a link to learn a little more about it: https://developer.android.com/things/index.html. So what this means is that you can potentially take some of the same Android dev experience and create some awesome IoT projects, or if you're someone that already knows Java and doesn't want to bother with learning another language like Python or C/C++ just to get started in IoT, then you're also in luck!
What to ExpectReal quick, I just wanted to explain what you can come to expect throughout this series. For starters, this is a 4 part series, which will take you from the very beginner's stage of AndroidThings to a more advanced stage towards the end. Now it's very possible that even after the 4 parts, this series can continue but that's for later. Throughout the parts of this series you'll learn how to take AndroidThings, put it on a Raspberry Pi, make some lights blink and even do it from an Android device other than the Pi.
Getting StartedSo in order to get started, there are a couple of things we need to get. First you'll want to make sure you download Android Studio.
When installing Android Studio its important that you also make sure to install Android Oreo (8.0 API 26). At this time AndroidThings is only supported on Android 8.0 or later.
To verify this, just open up Android Studio after you've installed it and at the bottom right of the dialog window click on "Configure" -> "SDK Manager".
And make sure that "Android 8.0 (Oreo)" is selected and click "Apply" or "OK" to start the download/install.
Next you'll want to grab some hardware. For this first part, and throughout the series, I'll be using a Raspberry Pi 3. You'll want to also make sure you grab an 8GB micro SD card, LED and some resistors. And of course, a breadboard and a power adapter for your Pi and some jumpers. A monitor and HDMI will also be pretty helpful once we have AndroidThings running (we're going to need to grab the IP address later on to push our project to the Pi).
Last thing we'll need to make sure we have is an account for AndroidThings so that we can create our images that will later be flashed. Check out this link and be sure to get setup.
Once setup you should see a console similar to this:
Before we can get into writing any code for our Raspberry Pi, we need to have it running AndroidThings.
First thing, we need to create an image in order to flash AndroidThings onto the Raspberry Pi. So let's log back into the AndroidThings console and click on "Create a Product".
After clicking that button, you should see a pop like this:
Feel free to enter anything you'd like for the Product Name but be sure to select "Raspberry Pi 3" for the SOM type. You can go ahead and leave the remaining default settings if you'd like. Click "Create" and you should have successfully created your first AndroidThings product!
Next we'll want to create our image. You should be on a screen that looks similar to this:
Click on "Factory Images" and you should be presented with a screen to create a new image.
Click "Next":
Click "Next" again:
And then name your new image anything you'd like. Then click "Create Build". You should then see the view update below and your new image being setup.
Once it's ready you'll see a "Download" link, go ahead and click that to have your new image packaged and downloaded.
This part could take a few minutes, so might be a good time to grab a cup of coffee. Eventually you should have a zip file downloaded which contains the image for your Pi (should be something like iot_rpi3).
Awesome, nearly at the finish line now for having AndroidThings running on your Raspberry Pi! Now we need to flash the image onto the micro SD card. I would recommend using something like Etcher to easily flash the image, but just about image flashing software should work. For this tutorial I will be using Etcher.
Go ahead and open Etcher.
And next select your iot_rpi3 image. Select your drive (the micro SD card) and then "Flash!". This process could take a few more minutes, so maybe another cup of coffee?
And that's it! Once that's done just insert your micro SD card into the Raspberry Pi and power it on.
If you have a monitor hooked up you should eventually see the AndroidThings home screen.
Before diving into the AndroidThings project, let's go ahead and take care of the hardware portion. For this part you'll need your Raspberry Pi, jumpers, resistors, LED and breadboard.
Follow the following schematic to setup your hardware:
Here's an image of what the setup should look like:
Now that we have a Raspberry Pi running AndroidThings, we're now ready to start building things for it. First let's start up Android Studio.
Go ahead and click on "Start a new Android Studio project" to get going. If you would like to see the final source code for this part, feel free to checkout the repo here.
Fill in your project info, here is a screenshot to show you an example:
And then click "Next". Make sure to uncheck "Phone and Tablet", we won't be needing this yet in our project and make sure to check "Android Things" with "API 26: Android 8.0 (Oreo)" selected. Then click "Next":
Select "Android Things Empty Activity" and click "Next".
Then go ahead and uncheck "Generate a UI layout File", we'll be making an LED blink so there we won't have any UI yet. Click "Finish" and Android Studio will start putting your new project together.
Once that's done you should see your new project and the MainActivity file opened. (If it's not open, then go ahead and double click the file on the left and open it up!)
Before diving into the MainActivity and adding in our code for some super awesome LED blinking, we need to take care of a small detail. To make things a little simpler we are going to create a BoardDefaults class which will house some details about the different boards we can use for AndroidThings (this will also be useful for other projects you would want to make).
To add your new class, go ahead and right click on the main package (where your MainActivity file is on the left) and select Java Class file and enter BoardDefaults.
public class BoardDefaults {
private static final String DEVICE_EDISON_ARDUINO = "edison_arduino";
private static final String DEVICE_EDISON = "edison";
private static final String DEVICE_JOULE = "joule";
private static final String DEVICE_RPI3 = "rpi3";
private static final String DEVICE_IMX6UL_PICO = "imx6ul_pico";
private static final String DEVICE_IMX6UL_VVDN = "imx6ul_iopb";
private static final String DEVICE_IMX7D_PICO = "imx7d_pico";
private static String sBoardVariant = "";
/**
* Return the GPIO pin that the LED is connected on.
* For example, on Intel Edison Arduino breakout, pin "IO13" is connected to an onboard LED
* that turns on when the GPIO pin is HIGH, and off when low.
*/
public static String getGPIOForLED() {
switch (getBoardVariant()) {
case DEVICE_EDISON_ARDUINO:
return "IO13";
case DEVICE_EDISON:
return "GP45";
case DEVICE_JOULE:
return "J6_25";
case DEVICE_RPI3:
return "BCM6";
case DEVICE_IMX6UL_PICO:
return "GPIO4_IO22";
case DEVICE_IMX6UL_VVDN:
return "GPIO3_IO06";
case DEVICE_IMX7D_PICO:
return "GPIO_34";
default:
throw new IllegalStateException("Unknown Build.DEVICE " + Build.DEVICE);
}
}
/**
* Return the GPIO pin that the Button is connected on.
*/
public static String getGPIOForButton() {
switch (getBoardVariant()) {
case DEVICE_EDISON_ARDUINO:
return "IO12";
case DEVICE_EDISON:
return "GP44";
case DEVICE_JOULE:
return "J7_71";
case DEVICE_RPI3:
return "BCM21";
case DEVICE_IMX6UL_PICO:
return "GPIO2_IO03";
case DEVICE_IMX6UL_VVDN:
return "GPIO3_IO01";
case DEVICE_IMX7D_PICO:
return "GPIO_174";
default:
throw new IllegalStateException("Unknown Build.DEVICE " + Build.DEVICE);
}
}
private static String getBoardVariant() {
if (!sBoardVariant.isEmpty()) {
return sBoardVariant;
}
sBoardVariant = Build.DEVICE;
// For the edison check the pin prefix
// to always return Edison Breakout pin name when applicable.
if (sBoardVariant.equals(DEVICE_EDISON)) {
PeripheralManagerService pioService = new PeripheralManagerService();
List<String> gpioList = pioService.getGpioList();
if (gpioList.size() != 0) {
String pin = gpioList.get(0);
if (pin.startsWith("IO")) {
sBoardVariant = DEVICE_EDISON_ARDUINO;
}
}
}
return sBoardVariant;
}
}
You can copy and paste the code above into your new class and you can check out the full file here.
Now back to MainActivity! Time to get going on some LED blinking code. Right at the top of your class add the following code:
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
private Gpio mLedGpio;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "Starting ButtonActivity");
PeripheralManagerService pioService = new PeripheralManagerService();
try {
Log.i(TAG, "Configuring GPIO pins");
mLedGpio = pioService.openGpio(BoardDefaults.getGPIOForLED());
mLedGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
} catch (IOException e) {
Log.e(TAG, "Error configuring GPIO pins", e);
}
}
This adds the Gpio object which we will use for controlling the flow for the pin on the Raspberry Pi to the LED. We create an instance of the PeripheralManagerService which allows you to open and setup the Gpio object we want to add. Using the service we then request the pin for our LED and set the direction for the pin.
Next we'll add our loop that will basically tell the Raspberry Pi to turn on/off the LED. Following the code above go ahead and add the following code below:
@Override
protected void onStart() {
super.onStart();
Runnable ledBlinker = new Runnable() {
@Override
public void run() {
while(true) {
// Turn on the LED
setLedValue(true);
sleep(3000);
// Turn off the LED
setLedValue(false);
sleep(3000);
}
}
};
new Thread(ledBlinker).start();
}
The code we added now sets up the onStart for the app. This code will be executed when the app starts up for the first time. In the onStart we are creating a Runnable which will allow us to execute the LED loop on a separate thread.
Now taking a look at the code inside the Runnable, we have a while loop which turns on/off the LED with a 3 second pause in between. And as you can probably tell, the loop is setup to run infinitely. Feel free to adjust this anyway you'd like.
So far with the code we have, there might be some errors or complaining in the IDE, that's alright we're going to add some of the missing code next!
private void sleep(int milliseconds){
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Update the value of the LED output.
*/
private void setLedValue(boolean value) {
try {
mLedGpio.setValue(value);
} catch (IOException e) {
Log.e(TAG, "Error updating GPIO value", e);
}
}
Add the above code. We a sleep method which wraps up our delays and the setLedValue which pretty much turns on/off the LED.
Finally, we need to add some clean up. Add the following code next:
@Override
protected void onDestroy(){
super.onDestroy();
if (mLedGpio != null) {
try {
mLedGpio.close();
} catch (IOException e) {
Log.e(TAG, "Error closing LED GPIO", e);
} finally{
mLedGpio = null;
}
mLedGpio = null;
}
}
This adds the onDestroy method which closes the pin and cleans up the Gpio object. The onDestroy method gets called when we close up the app.
After that your final file should look something similar to this.
Once everything is looking good and the project builds successfully, we can run our first AndroidThings project!
Let's connect with our Raspberry Pi using ADB, this will allow us to deploy the project through Android Studio.
Open up Command Prompt or Terminal and navigate to your Android SDK install. If you are not sure where it is located, open up the "SDK Manager" from Android Studio and take note of "Android SDK Location" towards the top.
Locate adb tool, usually found in platform-tools and run the following command:
adb connect <raspberry-pi-ipaddress>
Hopefully, you still have that ip address handy from earlier when we initially ran AndroidThings on the Raspberry Pi, otherwise I would recommend hooking a monitor and powering on the device to grab the ip address. If you run into any trouble here please check out the AndroidThings docs to help troubleshoot.
After you have successfully connected your Raspberry Pi to your machine, you should now be able to deploy your project using Android Studio.
Go ahead and click the run button and you should see a dialog window appear which will hopefully have your Pi listed. Select it and run!
If all goes well, you should see the LED blink! If not, then not to worry, maybe just back up a bit and run through some of the steps and see where things went off or leave some comments and I can try my best to help!
Wrap upYou did it! You have successfully survived your first brush with AndroidThings and have taken some major steps in learning how you things up and how you can run a project and make your Raspberry Pi do things. This a great accomplishment but it's also only the beginning. You've completed part 1 but there are 3 more parts to go through before this series ends, but even if this is where you decide you get off its good to know that you have definitely gained some experience with AndroidThings whether you realize it or not.
I hope those of you that followed this tutorial found it very useful and interesting. If there are any points that seem confusing, unclear, or just plain nonsense, please leave me a comment or send me some feedback and I can clear things up or adjust the tutorial to make things better.
Thank you for checking out part 1 and I hope you continue through the next parts and complete this series. Part 2 will be coming soon and will take your current project to the next level with some button interaction!
Comments