Around the beginning of 2017, Google introduced an IoT platform called Android Things, which makes it easy for Android developers to develop IoT applications. Given Polyglot Programming’s interest in both IoT and Android, we were very early adopters of this platform, back when it was called Brillo. As part of our work with this platform, we’ve been involved in hosting workshops through the Atlanta Google Developer Group to help get people up and running with it. The documentation from Google is pretty good for experienced developers, but along the way we’ve discovered some things to help you as a beginner, or as a GDG organizer wanting to host your own workshop. This post assumes that you already have a basic understanding of the platform, have flashed the image to your SD card, and that you have some knowledge about hardware in general.
Why use a Pi?
At the time of this writing, there are six hardware platforms supported by Android Things: Two from Intel, three from NXP, and one from the Pi Foundation. Intel has recently discontinued their IoT platform and the ones that you can find for sale are still pretty expensive, roughly $80. The NXP boards are also in the same price range. The Pi 3, by comparison, costs about $40. That makes it a more accessible choice for people on a budget.
Understanding the Pi
First of, the only officially supported Pi is the Raspberry Pi 3. We’ve heard unconfirmed reports of it working on a Pi 2, but can conclusively confirm that it will not even boot on the Pi Zero! If you look at the diagram of a Pi 3, you’ll notice that the USB power port is for power only. While USB can be used for bi-directional data transfer, at this time, the USB ports on an Android Things Pi cannot be used for ADB sessions. Therefore you will need to get your device connected to a network via an Ethernet cable or Wi-Fi.
For this option to work, you need to be on a network where peer-to-peer connections are allowed. Most home networks and mobile hotspots allow for this, but some public ones may not, for security reasons. If you have access to a physical Ethernet port, the easiest way to get this working is to hook your device up to a HDMI display. After the device boots up (with no installed apps), it will display the current IP address at the bottom of the screen. From there you can follow the instructions here to connect your device to your Wi-Fi network so that you don’t have to maintain a constant physical Internet connection. But, what happens if you don’t have access to a physical Ethernet port or HDMI display (and would it be a pain to work from these?)
USB to TTY cable/Serial debug to the rescue (sort of)
Luckily, you can use a USB to TTY serial cable to get to a serial debug console, which is the same thing you’d get if you were to type in
Note: If you plan on using a physical serial interface to your device, you’ll need to disable the ability to use this. In that scenario you’ll either need to revert to a physical Ethernet connection to change settings, or, alternatively, create another mechanism for changing the network, such as your own BLE-based configuration option.
To get started, hook the cable up as per the diagram above. Once you have the cable hooked up, you’ll need to use a terminal program to access the serial connection. If you’re on MacOS, Zterm is a good free option, or Serial. If you’re using the AdaFruit cable on a Mac, the port will be called SLABUSB_TO_UART. Go to the official Android Things documentation to get the rest of the settings. Once you have connected with the correct settings, you should see a prompt that looks something like this (you may need to hit enter once to get this):
If you haven’t played around with the shell before, but are familiar with Linux, it might be a good time to splunk around the filesystem to see what is going on. Android, at its heart, is based on Linux.
Checking the status of your network connection
Android, like most Unix-based systems, supports the ifconfig command. Typing this on an Android Things device connected to a wired Ethernet connection, will look something like this:
wlan0 Link encap:Ethernet HWaddr b8:27:eb:54:86:07 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:11712 errors:0 dropped:11712 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:5421496 TX bytes:0 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope: Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:354 errors:0 dropped:0 overruns:0 frame:0 TX packets:354 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:175044 TX bytes:175044 eth0 Link encap:Ethernet HWaddr b8:27:eb:01:d3:52 inet addr:192.168.0.96 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::ba27:ebff:fe01:d352/64 Scope: Link inet6 addr: 2602:302:d15c:5fc8:ba27:ebff:fe01:d352/64 Scope: Global inet6 addr: 2602:302:d15c:5fc8:44ec:a445:3f14:9d22/64 Scope: Global UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:55690 errors:0 dropped:118 overruns:0 frame:0 TX packets:10105 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:10610970 TX bytes:2274942
The lines that we’ll be focusing on are the wlan0 entry (wireless adapter) and eth0 (wired adapter). In the example above, our physical Ethernet adapter is connected to the network with an IP address of 192.168.0.96.
Connecting to a Wi-Fi network
The official documentation provides some instructions on connecting to a wireless network here. Under Step 1, there’s an important detail that they left out about the password. Specifically, that you will need to add an extra space after the password. If you don’t, the command loses the last character, and you will have continued failed attempts at connecting to the network! You can use the instructions provided by Google to verify your connection. Another trick is to use the ifconfig command from the shell/serial debug session.
wlan0 Link encap:Ethernet HWaddr b8:27:eb:54:86:07 inet addr:192.168.0.83 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: 2602:302:d15c:5fc8:5e7:fe2b:89c0:b51c/64 Scope: Global inet6 addr: fe80::ba27:ebff:fe54:8607/64 Scope: Link inet6 addr: 2602:302:d15c:5fc8:ba27:ebff:fe54:8607/64 Scope: Global UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:794 errors:0 dropped:646 overruns:0 frame:0 TX packets:253 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:287291 TX bytes:43241 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope: Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:29 errors:0 dropped:0 overruns:0 frame:0 TX packets:29 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:3459 TX bytes:3459 eth0 Link encap:Ethernet HWaddr b8:27:eb:01:d3:52 inet addr:192.168.0.96 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::ba27:ebff:fe01:d352/64 Scope: Link inet6 addr: 2602:302:d15c:5fc8:a91f:194b:baaf:6cea/64 Scope: Global inet6 addr: 2602:302:d15c:5fc8:ba27:ebff:fe01:d352/64 Scope: Global UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12306 errors:0 dropped:1 overruns:0 frame:0 TX packets:10998 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1107193 TX bytes:2085638
If you have successfully connected, you will see an IP address assigned under the wlan0 adapter. Now you can use adb connect <ip-address> to connect to the Pi. Once you’ve done that, you can interact with your Android Things device over ADB.
Stay tuned for our next post where we will talk about writing your first application with Android Things!