Android Things之七:树莓派3实现串口通信
关于Android Things的探索,并不会因为买不起i.MX 7D的显示屏配件而止步!接下来只能换上树莓派3B来继续学习了。
从今天开始,准备使用RPI3来代替i.MX7D做Android Things开发。
因为接下来准备探索GUI编程。不错,Android Things是支持GUI的,不过专用的显示屏太贵,而RPI3也是支持Android Things并且提供了HDMI接口,不必另外专门购买一个专用的显示屏了。
UART是用于与外围设备交换原始数据的通用接口。它是通用的,因为数据传输速度和数据字节格式都是可配置的。同时它是异步的(UART而非USART),因为没有时钟信号来同步两个设备之间的数据传输。设备硬件会在先进先出(FIFO)缓冲区中收集所有传入数据,直到应用程序读取完成为止。
UART数据传输是全双工的,这意味着可以同时发送和接收数据。它通常比I 2 C 快,但缺少共享时钟意味着两个设备必须就每个设备能够以最小的定时误差独立地遵守的通用数据传输速率达成一致。
UART外设通常有两种形式:
• 3线端口包括数据接收(RX),数据发送(TX)和接地参考(GND)信号。
• 5线端口添加用于硬件流控制的发送请求(RTS)和清除发送(CTS)信号。流控制允许接收设备指示其FIFO缓冲器暂时满,并且发送设备应该在发送任何更多数据之前等待。
与SPI和I2C不同,UART仅支持两个器件之间的点对点通信。
一般为了简单,通常只使用UART来通信,这样只需要三根线就可以通信,如图。为了和RPI3进行UART通信,另外使用了一块Arduino UNO,通过Arduino的UART与RPI进行通信。
RPI3的GPIO引脚接口如下
连接后的硬件如下
接下来开始写代码。
Arduino端的代码非常简单,如下
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Uart Initialized. Now commucation begins...");
}
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available()) {
String msg = Serial.readString();
Serial.println(msg);
}
}
代码的作用就是打开串口,设置通信速率,其它的参数使用默认值。一旦串口接收到数据,就打印出来,验证通信是否成功。
接下来是Android Things端的代码了。相比GPIO/I2C等设备通信来说,UART的通信稍微复杂一些,主要是增加了事件监听机制。这样的好处是减少轮询时大量CPU时间的浪费。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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();
}
}
在onCreate函数里,主要做了两件事:一是打开UART设备;其次是使用Handler来定时发送消息。
打开UART设备与前面使用GPIO的方法并无差别,先使用PeripheralManager来获取一个实例,然后通过该实例来管理UART设备,这些方法都放在try...catch块中以处理异常。
Handler来实现定时操作是Android中常见的操作,参考前文相关介绍,这里每隔2秒发送一段信息。
@Override
protected void onStart() {
super.onStart();
try {
mUartDevice.registerUartDeviceCallback(mUartDeviceCallback);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onStop() {
super.onStop();
mUartDevice.unregisterUartDeviceCallback(mUartDeviceCallback);
}
这一段代码用来注册及注销UART事件回调,即只有在APP处于前台时才监听事件。
private UartDeviceCallback mUartDeviceCallback = new UartDeviceCallback() {
@Override
public boolean onUartDeviceDataAvailable(UartDevice uartDevice) {
return false;
}
};
这里是UART事件处理程序,当串口接收到数据后,可以在这里处理,这里只演示了RPI3发送数据的情况,没有处理接收后的数据。当然我们可以在这里加一条简单的LOG语句来处理接收到的信息。
public void configureUart(UartDevice uart) throws IOException {
uart.setBaudrate(115200);
uart.setDataSize(8);
uart.setParity(UartDevice.PARITY_NONE);
uart.setStopBits(1);
}
这里配置UART参数,注意与Arduino端的配置要相同,否则接收到的数据就是乱码了。
将代码上传到RPI3,通过Android Studio及Arduino各自的监听机制,可以看到实时的通信情况,如下图
这是Arduino端的串口监视器查看到的结果,注意通信率为115200。
这是Android Studio的Logcat输出的信息,使用了filter来过滤其它的信息,只显示与串口通信相关的输出。
接下来准备开始GUI的编程体验,通过RPI3的HDMI接口连接显示器,可以实现图形化的操作外设
这是Android Things的桌面(如果也能称为桌面的话),这里可以看到一些硬件相关的信息,如IP地址,GPIO等外设,要查看更具体的外设信息,可以点击I/O Pinout,得到如下信息
接下来就可以开始激动的GUI之旅了!