用Java语言开发物联网设备应用(4)

认识外设

外设通常指输入输出设备,是计算机系统最重要的组成部分之一。物联网设备往往要和五花八门的外设打交道,比如传感器、GPS、按钮、摄像头、显示屏、麦克风、扬声器······凡此种种,不一而足。除了要和网络服务器交互以外,从各种外设上取得数据,或是通过外设进行各种控制,是物联网设备的主要特点。

常见的外设接口

物联网设备的外设虽然五花八门,但是外设和主控芯片(CPU)的接口类型,通常就是那么几种:

UART

就是我们常说的“串口”,主要用来用作通讯。很多物联网常用外设,比如GPS模组、蓝牙模组、2G/4G模组等等,都支持使用UART来和主控芯片通讯。

GPIO

通常叫做“通用IO接口”,这里的IO(或说I/O)是指输入/输出。GPIO的操作非常简单,就是高低电平的输入或者输出,比如点亮一个LED灯,或者从一个开关按钮读取按下状态等等。

SPI

串行外设接口,比起UART,SPI接口能支持很高的数据吞吐率,比如网络控制器、FLASH存储器这些需要高速和CPU交换数据的外设,通常是使用SPI接口的。不过SPI是分主从设备的,数据交换是由主SPI设备发起的从SPI听命于主设备的控制。

IIC

是Inter-Integrated Circuit Bus的简称,通常翻译成“集成电路总线”。IIC的特点是需要的连线少,控制逻辑简单易实现,也适用于一主多从的总线式外设连接布局。实际使用中,很多种类型的传感器产品都支持IIC接口,比如温度传感器、加速度传感器等等。

PWM

Pulse Width Modulation,即“脉冲宽度调制器”,或者不那么准确但是简单地理解为“脉冲波发生器”。在机械控制中用的最多,比如步进电机。也可以用来控制简单的喇叭发声。

ADC/DAC

即“模数/数模转换器”。像电压这样的模拟量,计算机需要将其数字化才能够处理,这就是“模-数”转换。反之则是“数-模”转换。

IIS:

Integrate Inte**ce of Sound。从名字就可以看出来,这个接口是接声音输入输出设备的。一般的音频采集芯片、音频编解码芯片或是音频播放芯片都支持IIS接口。

Java对外设接口的支持

Java在外设控制这方面,以前并没有专门的接口。从OpenJDK 7开始,OpenJDK加入了DeviceIO作为外设控制的标准接口,对物联网设备常见的外设接口做了标准化支持。
JOSH针对小型物联网设备,对DeviceIO进行了小幅改动。通过JOSH DeviceIO API(org.joshvm.j2me.dio.* ),目前支持的接口类型有UART、GPIO、SPI和IIC,Java程序员可以实现用Java语言控制外设,比如控制电平开关、读取传感器数据等等。换言之,可以实现用Java语言编写物联网设备的外设驱动程序,并实现驱动程序的动态安装。
下面,我们通过一些示例,看看是如何通过JOSH DeviceIO API实现外设访问功能的。

输出高低电平——GPIO控制篇

首先创建一个GPIO端口配置。这段代码的主要意思,是配置GPIO#2号端口为输出模式。

GPIOPinConfig cfg1 = new GPIOPinConfig(GPIOPinConfig.UNASSIGNED, 2, 
									   GPIOPinConfig.DIR_OUTPUT_ONLY,
					                   GPIOPinConfig.MODE_OUTPUT_OPEN_DRAIN,
					                   GPIOPinConfig.TRIGGER_NONE, false);

然后通过DeviceManager打开GPIO#2端口

GPIOPin gpioPin = (GPIOPin) DeviceManager.open(cfg1, DeviceManager.EXCLUSIVE);

下面这段代码,是将GPIO#2端口置为高电平,一秒钟后再设置为低电平,然后再等待一秒。如此循环10次。

int retry = 10;
while (retry-- > 0) {
				// 将GPIO拉高
				gpioPin.setValue(true);
				Thread.sleep(1000);
				// 将GPIO拉低
				gpioPin.setValue(false);
				Thread.sleep(1000);
			}

如果接一个LED灯到GPIO#2上的话,将看到LED灯在以一秒为间隔闪烁10次。
完整的代码可以由此下载:https://doc.joshvm.com/static/ESP32/sample/GpioDemo.zip

使用串口通讯——UART控制篇

首先确定打开的是几号串口,下面这个Demo是打开串口1,也就是COM1。然后确定使用的波特率,这里设为9600。

	private static String com = "COM1";
	// 波特率
	private static int baudrate = 9600;

	private static StreamConnection streamConnection;
	private static InputStream inputStream;
	private static OutputStream outputStream;

	
	public static void main(String[] args) {
		String host = "comm:" + com + ";baudrate=" + baudrate;
		try {
			// 建立连接
			streamConnection = (StreamConnection) Connector.open(host);
			······

接下来获取输入输出流

			inputStream = streamConnection.openInputStream();
			outputStream = streamConnection.openOutputStream();

将从外设从串口发来的数据按16进制打印到log,并写回串口

			int len = 0;
			byte[] buffer = new byte[256];
			StringBuffer stringBuffer = null;
			// 读数据
			while ((len = inputStream.read(buffer)) != -1) {

				stringBuffer = new StringBuffer();
				for (int i = 0; i < len; i++) {
					stringBuffer.append(Integer.toHexString(buffer[i] & 0xFF) + " ");
				}
				System.out.println(stringBuffer.toString());
				
				//发送数据
				sendData(buffer, 0, len);
			}

这个是发送数据的函数实现

	private static void sendData(byte[] buffer, int off, int len) throws IOException {
		if (outputStream != null) {
			outputStream.write(buffer, off, len);
		}
	}

完整的代码可以由此下载:https://doc.joshvm.com/static/ESP32/sample/UartDemo.zip

下一步——访问网络

连接网络是物联网设备的基本需求,Java可以让我们非常方便地编写联网应用,并处理各种复杂的应用层网络协议。我从下一篇起,会向大家介绍如何用Java编写网络应用,将物联网设备与网络服务器连接起来。


版权声明:本文为max1k原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。