参考文章:
Android Things 外设I/O-UART
目录
1. 新建一个 Android Things 工程
2. 硬件连接
3. Arduino 端代码
4. Android Things 端代码
4.1. 添加权限
4.2 找到 UART 设备的名称
4.3 打开UART设备并使用Handler来定时发送消息
4.4 注册及注销UART事件回调
4.5 UART事件处理程序
4.6 配置UART参数
4.7 MainActivity.java 完整代码
5. 最终效果
1. 新建一个 Android Things 工程
一直下一步就好,如果找不到 Android Things 则需要升级你的 Android Studio(我的版本号为:3.1.2)
2. 硬件连接
我用的是三线连接,如下图:
树莓派引脚如下图:
最终连接图如下:
3. Arduino 端代码
void setup() {
Serial.begin(115200);
Serial.println("Uart Initialized. Now commucation begins...");
}
void loop() {
if(Serial.available()) {
String msg = Serial.readString();
Serial.println(msg);
}
}
代码的作用就是打开串口,设置通信速率,其它的参数使用默认值。一旦串口接收到数据,就打印出来,验证通信是否成功。
4. Android Things 端代码
4.1. 添加权限
这步非常重要,上面两篇参考文章里都没有写,搞得我一直以为是硬件连接出错了,最后在 Logcat 里看到 promission deny。。。
<uses-permission android:name="com.google.android.things.permission.USE_PERIPHERAL_IO"/>
4.2 找到 UART 设备的名称
List<String> deviceList = PeripheralManager.getInstance().getUartDeviceList();
if (deviceList.isEmpty()) {
Log.i(TAG, "No UART port available on this device.");
} else {
Log.i(TAG, "List of available devices: " + deviceList);
}
4.3 打开UART设备并使用Handler来定时发送消息
先使用PeripheralManager来获取一个实例,然后通过该实例来管理UART设备。
try {
mUartDevice = PeripheralManager.getInstance().openUartDevice(UartName);
configureUart(mUartDevice);
mHandler.post(new Runnable() {
@Override
public void run() {
try {
mUartDevice.write(msg.getBytes(), msg.getBytes().length);
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, "run: " + msg);
mHandler.postDelayed(this, 2000);
}
});
} catch (IOException e) {
e.printStackTrace();
}
4.4 注册及注销UART事件回调
只有在APP处于前台时才监听事件。
@Override
protected void onStart() {
super.onStart();
try {
mUartDevice.registerUartDeviceCallback(mUartDeviceCallback);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onStop() {
super.onStop();
mUartDevice.unregisterUartDeviceCallback(mUartDeviceCallback);
}
4.5 UART事件处理程序
当串口接收到数据后,可以在这里处理,这里只演示了RPI3发送数据的情况,没有处理接收后的数据。当然我们可以在这里加一条简单的LOG语句来处理接收到的信息。
为了避免在缓冲区为空时不必要地轮询UART,用UartDevice注册一个UartDeviceCallback。 当有可用于读取的数据时,此回调调用onUartDeviceDataAvailable()方法。 当应用程序不再侦听传入数据时,应该取消注册回调。
onUartDeviceDataAvailable()回调返回一个布尔值,指示回调是否应该在接收未来中断事件时自动取消注册。 此处返回true,以便在每次UART FIFO中显示数据时继续接收事件。
private UartDeviceCallback mUartDeviceCallback = new UartDeviceCallback() {
@Override
public boolean onUartDeviceDataAvailable(UartDevice uartDevice) {
return false;
}
};
4.6 配置UART参数
注意与Arduino端的配置要相同,否则接收到的数据就是乱码了。
启动位 - 在发送数据之前,该行保持活动状态,持续1位持续时间的固定时间间隔,以指示新字符的开始。
数据位 - 表示数据字符的各位。 UART可以配置为在5-9个数据位之间发送以表示字符。 较少的位减少了数据的范围,但可以增加有效的数据传输速率。
奇偶校验位 - 可选错误校验值。 如果UART配置为偶校验或奇校验,则会在帧中添加一个额外的位,以指示数据位的内容是否为偶数或奇数值。 将此设置为none会从帧中删除该位。
停止位 - 在传输所有数据之后,线路被重置一个可配置的时间间隔,以指示该字符的结束。 这可以配置为保持空闲1或2位持续时间。
public void configureUart(UartDevice uart) throws IOException {
uart.setBaudrate(115200);
uart.setDataSize(8);
uart.setParity(UartDevice.PARITY_NONE);
uart.setStopBits(1);
}
4.7 MainActivity.java 完整代码
package com.example.lilihan.at_test2;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import com.google.android.things.pio.PeripheralManager;
import com.google.android.things.pio.UartDevice;
import com.google.android.things.pio.UartDeviceCallback;
import java.io.IOException;
import java.util.List;
import static android.content.ContentValues.TAG;
public class MainActivity extends Activity {
private static final String UartName = "UART0"; // 你的 UART 设备名称
private UartDevice mUartDevice;
private Handler mHandler = new Handler();
private String msg = "test";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 找到你的 UART 设备名称
List<String> deviceList = PeripheralManager.getInstance().getUartDeviceList();
if (deviceList.isEmpty()) {
Log.i(TAG, "No UART port available on this device.");
} else {
Log.i(TAG, "List of available devices: " + deviceList);
}
try {
mUartDevice = PeripheralManager.getInstance().openUartDevice(UartName);
configureUart(mUartDevice);
mHandler.post(new Runnable() {
@Override
public void run() {
try {
mUartDevice.write(msg.getBytes(), msg.getBytes().length);
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, "run: " + msg);
mHandler.postDelayed(this, 2000);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onStart() {
super.onStart();
try {
mUartDevice.registerUartDeviceCallback(mUartDeviceCallback);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onStop() {
super.onStop();
mUartDevice.unregisterUartDeviceCallback(mUartDeviceCallback);
}
private UartDeviceCallback mUartDeviceCallback = new UartDeviceCallback() {
@Override
public boolean onUartDeviceDataAvailable(UartDevice uartDevice) {
return false;
}
};
public void configureUart(UartDevice uart) throws IOException {
uart.setBaudrate(115200);
uart.setDataSize(8);
uart.setParity(UartDevice.PARITY_NONE);
uart.setStopBits(1);
}
}
5. 最终效果
在 Arduino 串口调试工具中可以查看输出