Android Things обладает уникальной способностью легко подключаться к внешним электронным компонентам с помощью периферийного API и поддержки встроенных устройств. В этой статье вы узнаете о различных типах периферийных устройств, к которым вы можете подключиться для настройки устройств IoT с Android Things.
Работа с разными интерфейсами
Android Things позволяет подключать большинство устройств к вашей плате прототипов с помощью Peripheral API, который поддерживает интерфейсы GPIO, PWM, I 2 C, SPI и UART, каждый из которых является стандартным интерфейсом для связи с периферийными устройствами. В этом разделе вы узнаете, что это за интерфейсы и как взаимодействовать с устройствами, которые вы подключили к плате прототипирования вещей Android с помощью этих соединений.
GPIO
Штырьки ввода / вывода общего назначения (GPIO) используются для цифровой (двоичной) связи с компонентами, например, для считывания, нажата кнопка или нет, или для включения или выключения светодиода. Из методов ввода-вывода, которые вы увидите в этом руководстве, GPIO является наиболее простым в использовании, для которого требуется только один вывод и используются логические значения для высокого или низкого состояния.
Прежде чем вы сможете подключиться к выводу GPIO, вам необходимо знать уникальное имя этого вывода. Вы можете получить имена всех доступных контактов, getGpioList()
PeripheralManagerService
и вызвав getGpioList()
. На Raspberry Pi это вернет следующий список:
1
|
[BCM12, BCM13, BCM16, BCM17, BCM18, BCM19, BCM20, BCM21, BCM22, BCM23, BCM24, BCM25, BCM26, BCM27, BCM4, BCM5, BCM6]
|
Чтобы выяснить, какие контакты представляют каждый из них, вы можете обратиться к диаграмме ввода / вывода Raspberry Pi.
Когда у вас есть имя контакта, с которого вы будете читать или писать, вы можете получить Gpio
объект Gpio
на этот вывод, вызвав openGpio(String pin_name)
из вашего PeripheralManagerService
.
1
2
3
4
5
|
try {
mGpio = service.openGpio(PIN_NAME);
} catch (IOException e){
}
|
Контакты GPIO могут быть использованы для ввода или вывода. Если вы будете использовать пин-код для считывания информации, вам нужно будет настроить направление вывода как DIRECTION_IN
и установить тип триггера для этого вывода, чтобы он знал, когда ваши приложения должны знать, что что-то произошло.
1
2
|
mGpio.setDirection(Gpio.DIRECTION_IN);
mGpio.setEdgeTriggerType(Gpio.EDGE_BOTH);
|
Типы триггеров состоят из EDGE_NONE
, EDGE_RISING
, EDGE_FALLING
и EDGE_BOTH
. Если кнопка нажата, то возникает событие нарастания, когда замыкание кнопки завершено, и на физическом выводе появляется сигнал высокого напряжения. Падение происходит, когда кнопка отпущена. Ваш код будет уведомлен об изменениях в зависимости от типа установленного триггера.
Теперь, когда ваш GPIO прослушивает краевые триггеры, вам нужно будет создать GpioCallback
чтобы зарегистрировать значение компонента GPIO в вашем приложении.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
private GpioCallback mCallback = new GpioCallback() {
@Override
public boolean onGpioEdge(Gpio gpio) {
try {
Log.d(«Tuts+», «GPIO value: » + gpio.getValue());
} catch( IOException e ) {
}
return super.onGpioEdge(gpio);
}
@Override
public void onGpioError(Gpio gpio, int error) {
super.onGpioError(gpio, error);
}
};
|
Как только ваш обратный вызов создан, зарегистрируйте его с вашим объектом Gpio
.
1
|
mGpio.registerGpioCallback(mCallback);
|
Если ваш вывод GPIO записывает информацию, вам нужно установить направление DIRECTION_OUT_INITIALLY_LOW
или DIRECTION_OUT_INITIALLY_HIGH
, в зависимости от того, хотите ли вы, чтобы компонент запускался как включенный или выключенный. Для выходного контакта типы триггеров не требуются.
1
|
mGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
|
Для записи на устройство вы можете вызвать setValue(boolean)
объекта Gpio
чтобы установить состояние компонента.
1
|
mGpio.setValue(true);
|
После завершения работы приложения вам нужно будет отменить регистрацию обратного вызова ввода, если оно было создано и зарегистрировано, и закрыть доступ к периферийному устройству с помощью метода close()
в onDestroy()
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@Override
protected void onDestroy() {
super.onDestroy();
if( mGpio != null ) {
try {
mGpio.unregisterGpioCallback(mCallback);
mGpio.close();
mGpio = null;
} catch( IOException e ) {
}
}
}
|
PWM
Устройства с широтно-импульсной модуляцией (ШИМ) используют для работы чередование цифровых состояний, называемое пропорциональным управляющим сигналом. Существует три основных части пропорционального управляющего сигнала, о которых необходимо знать:
- Частота: описывает частоту повторения выходного импульса. Единица измерения частоты — герц (Гц).
- Рабочий цикл: представляет ширину импульса в пределах установленной частоты. Рабочий цикл выражается в процентах от высоких сигналов на частоте, поэтому цикл, который работает в половине случаев, будет иметь 50% рабочий цикл.
- Период: представляет собой время, которое требуется для каждого цикла вверх / вниз. Период обратно связан с частотой.
Регулируя рабочий цикл сигнала, вы можете контролировать среднее время включения волны. Ниже вы можете увидеть пример 50% периода сигнала.
Некоторые устройства, которые могут использовать сигнал ШИМ, включают серводвигатели, которые используют частоту для определения своего положения, или светодиодную матрицу, которая может использовать сигнал ШИМ для регулировки яркости.
Даже с помощью только двигателей и устройств GPIO вы можете создавать большое количество устройств IoT, таких как «умное» дерево катов с лазерным приводом.
Подобно GPIO, вы можете получить список доступных портов ШИМ, создав PeripheralManagerService
и вызвав getPwmList()
. На Raspberry Pi этот список будет выглядеть следующим образом:
1
|
[PWM0, PWM1]
|
Как только вы узнаете имя PWM-контакта, который хотите использовать, вы можете открыть соединение с этим периферийным устройством, используя метод openPwm(String)
. Это нужно будет заключить в блок try/catch
чтобы обработать возможность возникновения IOException
.
1
2
3
4
5
|
try {
mPwm = service.openPwm(PIN_NAME);
} catch( IOException e ) {
}
|
После того, как вы открыли соединение с вашим выводом ШИМ, вы можете управлять настройками на нем, такими как частота и рабочий цикл.
1
2
3
|
mPwm.setPwmFrequencyHz(120);
mPwm.setPwmDutyCycle(25);
mPwm.setEnabled(true);
|
Прежде чем закончить работу с приложением и уничтожить Activity
, вам необходимо закрыть соединение и освободить ссылку на ваше ШИМ-устройство.
01
02
03
04
05
06
07
08
09
10
11
12
|
@Override
protected void onDestroy() {
super.onDestroy();
if( mPwm != null ) {
try {
mPwm.close();
mPwm = null;
} catch( IOException e ) {
}
}
}
|
Я 2 с
Шина Inter-Integrated Circuit (I 2 C) позволяет вашему проекту обмениваться данными с несколькими устройствами по одному физическому соединению, а также отправлять сложные данные с помощью нескольких контактов вашего Pi или другого встроенного устройства. I 2 C использует синхронную связь между устройствами и использует тактовый сигнал, чтобы гарантировать, что устройства отвечают в соответствующее время.
Устройство, которое выдает тактовый сигнал, который часто будет вашим устройством Android Things, называется ведущим, а все подключенные периферийные устройства, которые получают этот сигнал, называются подчиненными.
В отличие от ШИМ и GPIO, для которых требуется только один контакт, для устройств I 2 C требуется три соединения:
- Общий тактовый сигнал (сокращенно SCL), который выдает тактовый сигнал от ведущего устройства к подчиненным устройствам.
- Shared Data Line (сокращенно SDA), которая является соединением, используемым для фактической передачи данных. Поскольку I 2 C является стандартом синхронной (полудуплексной) связи, то есть данные могут перемещаться только в одном направлении за раз, только одно устройство может использовать это соединение в любой конкретный момент времени.
- Электрическое заземление.
Стоит отметить, что каждое подчиненное устройство I 2 C запрограммировано с заданным адресом и будет отвечать только тогда, когда ведущее устройство отправляет запрос данных для этого конкретного адреса.
Некоторые периферийные устройства, которые могут использовать этот метод подключения, включают в себя сегментированные светодиодные матричные дисплеи и различные усовершенствованные датчики.
Каждое устройство Android Things будет иметь набор выводов, используемых для I 2 C, которые вы можете найти, просмотрев документацию по вашей конкретной плате макетирования. Для Raspberry Pi вы можете сослаться на изображение распиновки в верхней части этой статьи, в котором говорится, что SDA и SDL — это контакты 3 и 5. Чтобы найти имя вашего I 2 C, вы можете запустить следующий код:
1
2
3
4
5
6
|
PeripheralManagerService manager = new PeripheralManagerService();
List<String> deviceList = manager.getI2cBusList();
if( !deviceList.isEmpty() ) {
Log.d( «Tuts+», deviceList.toString() );
}
|
Приведенный выше фрагмент кода выведет следующее на Raspberry Pi:
1
|
[I2C1]
|
Как только вы узнаете название вашей шины I 2 C, вы можете подключиться к устройствам на этой шине, используя их программный адрес. Вы можете найти программный адрес и другие сведения о низкоуровневом соединении в «таблице данных» периферийного компонента — это необходимо для чтения, если вы хотите использовать периферийное устройство для встроенного проекта!
01
02
03
04
05
06
07
08
09
10
|
private I2cDevice mDevice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
PeripheralManagerService manager = new PeripheralManagerService();
mDevice = manager.openI2cDevice(I2C_DEVICE_NAME, I2C_ADDRESS);
} catch (IOException e) {}
}
|
При обмене данными с устройством через I 2 C вы можете использовать протокол системной шины управления (SMBus) для помещения данных в регистры или для извлечения данных, которые были сохранены в регистрах на каждом периферийном устройстве. Это делается с использованием адреса устройства и адреса регистра, а Android Things позволяет считывать или записывать отдельные байты из регистра или группы байтов из нескольких регистров следующими способами:
-
readRegByte()
иwriteRegByte()
: чтение или запись одного байта из определенного регистра. -
readRegWord()
иwriteRegWord()
: чтение или запись байтов из двух последовательных регистров на периферийном устройстве в формате сwriteRegWord()
байтов. -
readRegBuffer()
иwriteRegBuffer()
: чтение или запись байтов из до 32 последовательных регистров. Значения записываются или извлекаются какbyte array
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public void singleByte(I2cDevice device, int address) throws IOException {
// Read one register from slave
byte value = device.readRegByte(address);
// Write the value back to slave
device.writeRegByte(address, value);
}
public byte[] multipleBytes(I2cDevice device, int startAddress) throws IOException {
// Read three consecutive register values
byte[] data = new byte[3];
device.readRegBuffer(startAddress, data, data.length);
return data;
}
|
Когда ваше приложение будет готово к закрытию на устройстве Android Things, обязательно отмените регистрацию шины I 2 C.
01
02
03
04
05
06
07
08
09
10
11
|
@Override
protected void onDestroy() {
super.onDestroy();
if (mDevice != null) {
try {
mDevice.close();
mDevice = null;
} catch (IOException e) {}
}
}
|
SPI
Соединения последовательного периферийного интерфейса (SPI) работают аналогично соединениям I 2 C, за исключением того, что они поддерживают полнодуплексную связь. Это означает, что данные могут считываться и записываться на периферийные устройства одновременно, вместо того, чтобы требовать от главного устройства запроса информации от подчиненных периферийных устройств. Тактовый сигнал все еще необходим для управления потоком данных от нескольких устройств на шине сигналов SPI. Для функционирования SPI требуется минимум четыре соединения:
- Master Out Slave In (MOSI)
- Master In Slave Out (MISO)
- Тактовый сигнал (CLK)
- Общая земля (GND)
Кроме того, требуется пятое соединение, если к шине SPI подключено несколько устройств SPI. Это Chip Select (CS), который используется для сигнализации аппаратного адреса периферийных устройств, чтобы ваше ведущее устройство могло обмениваться данными с определенным ведомым устройством.
Некоторые примеры периферийных устройств, использующих SPI, включают в себя платы со светодиодной матрицей и устройства чтения карт SD, и стоит отметить, что многие периферийные устройства, которые поддерживают I 2 C, также будут поддерживать SPI.
Как и в предыдущих примерах, вам нужно знать имя SPI-соединения на вашей плате Android Things. Вы можете найти это, создав PeripheralManagerService
и вызвав getSpiBusList()
для этого объекта. На Raspberry Pi у вас будет следующее:
1
|
[SPI0.0, SPI0.1]
|
Как только вы узнаете имя шины SPI, которую вы будете использовать, вы можете открыть соединение с ней.
01
02
03
04
05
06
07
08
09
10
11
|
private SpiDevice mDevice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
PeripheralManagerService manager = new PeripheralManagerService();
mDevice = manager.openSpiDevice(SPI_DEVICE_NAME);
} catch (IOException e) {
}
}
|
Чтобы устройства могли обмениваться данными по шине SPI, все они должны «говорить на одном языке», то есть они должны быть настроены на одинаковую тактовую частоту и формат данных. В то время как некоторые периферийные устройства могут регулировать формат данных и тактовую частоту, другие не могут. Поскольку все устройства на шине SPI должны работать с одинаковой конфигурацией, важно знать возможности ваших периферийных устройств, прежде чем пытаться подключить их к вашей шине SPI. Для вашей шины SPI необходимо установить четыре параметра / параметра:
- Режим SPI. Режим SPI состоит из двух основных компонентов: высокий или низкий тактовый сигнал, когда данные не передаются, и какой фронт импульса используется для передачи данных.
- Частота: представляет общий тактовый сигнал в Гц и, скорее всего, будет значением, определяемым возможностями ваших подчиненных устройств.
- Битовое выравнивание: используется для установки порядка байтов в ваших данных. По умолчанию Android Things будет использовать big-endian, ставя самый значимый big (MSB) на первое место.
- Bits per word (BPW): контролирует, сколько битов будет отправлено на подчиненное устройство перед переключением сигнала выбора микросхемы. По умолчанию будет отправлено восемь бит на слово.
В Java-коде Android Things вы можете установить эти четыре значения на шине SPI следующим образом:
1
2
3
4
5
6
|
// Low clock, leading edge transfer
device.setMode(SpiDevice.MODE0);
device.setFrequency(16000000);
device.setBitsPerWord(8);
device.setBitJustification(false);
|
То, как вы взаимодействуете со своими устройствами по шине SPI, зависит от того, работаете ли вы в полнодуплексном или полудуплексном режиме. Если ваши устройства настроены на полудуплекс, то вы захотите обмениваться данными между ведомыми устройствами и ведущим устройством с помощью методов read()
и write()
объекта SpiDevice
. Если вы работаете в полнодуплексном режиме, вам может потребоваться использовать метод transfer()
с двумя буферами массива байтов: один с данными для отправки, а другой пустой буфер для хранения данных ответов.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
//Half-duplex mode
public void sendCommand(SpiDevice device, byte[] buffer) throws IOException {
// Shift data out to slave
device.write(buffer, buffer.length);
// Read the response
byte[] response = new byte[32];
device.read(response, response.length);
}
// Full-duplex mode
public void sendCommand(SpiDevice device, byte[] buffer) throws IOException {
byte[] response = new byte[buffer.length];
device.transfer(buffer, response, buffer.length);
}
|
Когда ваше приложение будет готово к закрытию на устройстве Android Things, не забудьте отменить регистрацию вашего устройства SPI.
01
02
03
04
05
06
07
08
09
10
11
|
@Override
protected void onDestroy() {
super.onDestroy();
if (mDevice != null) {
try {
mDevice.close();
mDevice = null;
} catch (IOException e) {}
}
}
|
УАПП
Более сложные периферийные устройства, такие как ЖК-дисплеи, устройства чтения карт SD и модули GPS, часто используют последовательную связь через порты UART при связи с ведущим устройством. UART позволяет устройствам асинхронно отправлять необработанные данные в буфер на другом устройстве. Этот буфер затем читается в порядке «первым пришел — первым вышел». Он также позволяет настроить формат данных и скорость передачи на обоих подключенных устройствах. Оба устройства должны согласовать скорость передачи, поскольку UART не поддерживает тактовый сигнал, но скорости передачи, как правило, выше, чем I 2 C, и данные могут передаваться в полнодуплексном режиме между устройствами. В отличие от I 2 C и SPI, только одно подключенное периферийное устройство разрешено для каждого соединения UART.
Периферийные устройства UART имеют три основных провода:
- RX, который используется для получения данных.
- TX, который используется для передачи данных.
- GND, электрическое заземление.
На периферийных компонентах эти штыри обычно обозначаются так:
Кроме того, некоторые устройства UART могут включать еще два соединения для управления потоком данных:
- Запрос на отправку (РТС)
- Очистить для отправки (CLS)
Как и во всех предыдущих примерах, вам необходимо знать имя UART-соединения вашего устройства Android. Вы можете найти это с помощью следующего кода:
1
2
3
4
5
6
|
PeripheralManagerService manager = new PeripheralManagerService();
List<String> deviceList = manager.getUartDeviceList();
if (!deviceList.isEmpty()) {
Log.d(«Tuts+», deviceList.toString());
}
|
На Raspberry Pi вывод журнала будет выглядеть так:
1
|
[UART0]
|
После того, как вы знаете имя вашего UART-соединения, вы можете создать устройство Android Things UART так же, как вы открывали другие соединения устройства.
1
2
|
PeripheralManagerService manager = new PeripheralManagerService();
mDevice = manager.openUartDevice(UART_DEVICE_NAME);
|
Как только у вас будет ваше устройство, вам нужно будет настроить формат для фреймов данных, которые будут отправляться между устройствами. Есть четыре свойства, которые нужно знать:
- Количество бит данных: UART может отправлять от пяти до девяти бит для представления символа данных. Отправка меньшего количества битов обеспечивает более высокую скорость передачи данных, но ограничивает диапазон символов, которые могут быть отправлены.
- Бит четности: используется для проверки того, что содержимое данных передачи суммируется с четным или нечетным числом. Если четность не установлена, бит четности удаляется из передачи. Это используется для проверки ошибок при передаче.
- Стоповые биты: можно установить 1 или 2 бита. Передача будет простаивать в течение продолжительности, равной количеству стоп-битов, чтобы указать, что кадр данных закончился.
- Скорость в бодах: скорость в бодах — это скорость передачи вашего фрейма данных. Поскольку в UART нет тактовых сигналов, оба устройства должны быть настроены на скорость передачи данных до начала передачи.
Каждый из этих параметров может быть настроен на устройстве UART следующим образом:
1
2
3
4
|
uart.setBaudrate(9600);
uart.setDataSize(6);
uart.setParity(UartDevice.PARITY_NONE);
uart.setStopBits(2);
|
Ранее вы узнали, что для устройств UART есть две настройки проводки: с дополнительными управляющими сигналами и без. Вы можете настроить свое устройство UART в коде с помощью setHardwareFlowControl()
.
1
2
3
|
uartDevice.setHardwareFlowControl(UartDevice.HW_FLOW_CONTROL_AUTO_RTSCTS);
//or
uartDevice.setHardwareFlowControl(UartDevice.HW_FLOW_CONTROL_NONE);
|
После того, как вы закончили настройку своих устройств, пришло время читать и записывать данные с вашей платы Android Things и периферийного устройства UART. Запись выполняется путем вызова метода write()
с буфером байтового массива и длиной этого массива.
1
|
uartDevice.write(buffer, buffer.length);
|
Несмотря на то, что вы можете непрерывно запрашивать данные в буфере чтения вашего устройства, лучше всего создать объект UartDeviceCallback
, который предоставляет метод с именем onUartDeviceDataAvailable()
который будет запускаться при наличии данных. Когда это так, вы можете читать данные из буфера данных вашего устройства. Вы сможете связать этот обратный вызов с вашим устройством UART с registerUartDeviceCallback
, хотя вам нужно будет не забывать вызывать unregisterUartDeviceCallback
когда вы закончите использовать обратный вызов. Когда данные доступны, вы можете получить их с помощью метода read()
UART.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
private UartDeviceCallback mUartCallback = new UartDeviceCallback() {
@Override
public boolean onUartDeviceDataAvailable(UartDevice uart) {
byte[] buffer = new byte[MAX_BUFFER_SIZE];
try {
uartDevice.read(buffer, buffer.length)
//do something with the data in the buffer byte array
} catch (IOException e) {}
//Returning true keeps the callback active.
//the callback will automatically unregister.
return true;
}
@Override
public void onUartDeviceError(UartDevice uart, int error) {}
};
@Override
protected void onStart() {
super.onStart();
mDevice.registerUartDeviceCallback(mUartCallback);
}
@Override
protected void onStop() {
super.onStop();
mDevice.unregisterUartDeviceCallback(mUartCallback);
}
|
Когда вы закончите свою Activity
, не забудьте закрыть и обнулить ссылку на ваше устройство UART.
01
02
03
04
05
06
07
08
09
10
11
|
@Override
protected void onDestroy() {
super.onDestroy();
if (uartDevice != null) {
try {
uartDevice.close();
uartDevice = null;
} catch (IOException e) {}
}
}
|
Расширенный ввод-вывод и будущие обновления
Хотя Peripheral API позволяет общаться практически с любым устройством, которое может быть подключено к вашей плате Android Things, Google предоставил некоторую дополнительную поддержку, чтобы сделать ваши устройства IoT еще проще. В этом разделе мы рассмотрим некоторые дополнительные периферийные устройства, доступные через Android Things.
Собственный ввод / вывод
Хотя Android Things предоставляет разработчикам Android простой способ начать разработку IoT с помощью Android SDK и Java, многие приложения IoT уже существуют на C и C ++, и другие разработчики предпочитают работать на этих языках по разным причинам. Чтобы поддержать это, Google дополнил Периферийный API поддержкой нативных приложений и NDK. Я не буду углубляться в эту тему, но связи устанавливаются и используются очень похоже на те, которые обсуждались выше.
WiFi и Bluetooth
Без способа подключения к Интернету устройства IoT были бы просто вещами . Благодаря встроенной беспроводной поддержке ваши устройства Android Things могут подключаться к Интернету и использовать различные онлайн-ресурсы, такие как Firebase и другие службы Google, или любые другие фоновые службы. Кроме того, использование таких инструментов, как Сервисы Google Play и API Nearby Connections, позволяет пользователям напрямую взаимодействовать с вашим устройством через их сеть WLAN.
Хотя в настоящее время эта функция недоступна в предварительных версиях Android-приложений для разработчиков, подключение Bluetooth также является важной возможностью IoT. Используя Bluetooth, вы можете создавать несколько IoT-устройств или аксессуаров и передавать их на короткие расстояния . Это позволяет каждому устройству иметь дополнительную контекстную информацию о своей среде, такую как домашнее или рабочее пространство пользователя, чтобы лучше обслуживать пользователя.
USB
Некоторые устройства работают с USB-портами прототипа платы, хотя это не полностью включено в текущей итерации предварительного просмотра для разработчиков Android Things. Во втором предварительном просмотре для разработчиков Google добавил аудио через USB с поддержкой текста в речь, и разработчики подтвердили работу других устройств, таких как USB-микрофоны. Поскольку USB API протестированы и одобрены в более поздних версиях Android Things, появится множество устройств, которые можно просто подключить к устройству IoT в качестве аксессуара.
Камеры и дисплеи
Некоторые устройства, такие как Raspberry Pi, оснащены встроенными дополнительными соединениями ввода / вывода, такими как HDMI, дисплей и камера. К счастью, все это доступно с Android Things, что позволяет подключить камеру с помощью ленточного кабеля 15 см …
… или дисплей через ленточный кабель или соединение HDMI:
Вывод
Поздравляем! Вы многое изучили, но узнали невероятно ценную информацию о подключении и управлении периферийными устройствами с помощью платы Android Things. Используя эти знания, вы сможете подключаться и взаимодействовать с различными аппаратными компонентами.
В следующем посте этой серии мы будем использовать наши знания API периферийных устройств для создания программного драйвера для компонента датчика движения GPIO, который затем можно будет использовать в более крупном проекте Android Things.
А пока посмотрите другие наши учебники и статьи о разработке для Android!