IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> android——串口、网口与外设进行数据交互 -> 正文阅读

[嵌入式]android——串口、网口与外设进行数据交互

当开始接触到传感器的时候,觉得一切都是未知的。就拿温度传感器来说,当时我在想:我怎么就通过Android板读取到当前的温度呢?我又该怎么做呢,我该怎么下手呢?于是我先上网搜了下,然后我疯狂的和传感器厂家进行交流,哈哈哈感觉人家技术支持已经烦我了。接下来,我们言归正传。

一、在什么场景下使用

一般可以通过Android板与硬件进行联动,比如温湿度的监测、蓄电池的电能、噪音监测、智能电表的相关参数、体温检测仪、血压检测仪等等,只要你能想到的,一般都能与Android板通信。当然了,前提是必须他这个硬件要支持数据的传输啦,哈哈哈。

二、常见的数据传递
我们常见的数据传递有蓝牙、串口、网口等等。而我要记录的就是网口、串口的通讯。

1、串口

  • 串口是串行接口(serialport)的简称,也称为串行通信接口或COM接口。
  • 串口通信是指采用串行通信协议(serial communication)在一条信号线上将数据一个比特一个比特地逐位进行传输的通信模式。
  • 常见的串口有,RS232,RS485等等,这是根据电气标准来分的,具体为什么这么分我也不知道。

这里我就简单的介绍了什么是串口,串口用的模式大多数都是FIFO(先进先出)的数据结构。
如下图所示,是常见的设备间串口通讯结构图。每个设备都有一个DB9接口,通过DB9接口连接RS-232标准的串口线进行数据传输。由于通过RS-232标准传输的电平信号到达设备后,不能直接被识别,所以会通过电平转换芯片转换成能识别的TTL电平信号,实现通讯。

相互通讯的两个设备间,一个设备发送数据,一个设备接收数据。一般情况下,发送数据的设备称为DTE,如计算机;接收数据的设备称为DCE,如调制解调器。
在这里插入图片描述
在写java代码之前,我们还得知道一个概念,就是波特率
波特率:在信息传输通道中,携带数据信息的信号单元叫码元,每秒钟通过信道传输的码元数称为码元传输速率,简称波特率。比特率:9600bps,意思就是每秒中传输9600bit。

就拿我做的一个需求来说,就是对接智能电池的信息。大致流程就是,我通过串口去读取电池的信息,然后将读取到的数据解析。

因为要每隔一段时间读一次数据,所以我写了一个service,就命名为BatService好了,在onCreate()中进行串口的初始化工作。

a、首先就是先初始化串口,指定哪个串口,和使用的波特率大小。
b、接下来就是创建两个线程,一个用于读,一个用于写。所以我写了ReadBatThreadWriteBatThread,我这里为了简易说下流程,线程安全方面没有进行管理。初始化的时候读线程初始化就是getInputStream(),写线程初始化就是getOutputStream(),对inputstream和outputstream有不清楚的可以去看我之前有一篇文章提到过。
InputStream和OutputStream的用法

    @Override
    public void onCreate() {
        super.onCreate();
        try {

            SerialPort mbatSerialPort = new SerialPort(new File("/dev/ttyS0"), 19200, 0);
            ReadBatThread readBatThread = new ReadBatThread(mbatSerialPort.getInputStream());
            readBatThread.start();
            WriteBatThread writeBatThread = new WriteBatThread(mbatSerialPort.getOutputStream());
            writeBatThread.start();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

c、接来下就是写具体的读写线程了
先看写线程,一般写线程就是我们给所需要的读取信息的设备(我这里就是电池)发送一条指令。像我要读取电池的信息,我这里就根据定义的协议,发送一个读指令,一般为16进制数。而与设备之间传递的一般是字节流,我们发送的时候将十六进制字符串转成字节数组就可以了。

private class WriteBatThread extends Thread {
        private OutputStream mOus;

        public WriteBatThread(OutputStream ous) {
            if (ous == null) {
                throw new NullPointerException("流异常");
            }
            mOus = ous;
        }

        @Override
        public void run() {
            super.run();
            while (!this.isInterrupted()) {
                if (mOus != null) {
                    try {
                    //这里就是给设备发送读指令,readHex就是十六进制指令字符串
                        mOus.write(Transform.HexString2Bytes(readHex));
                        Thread.sleep(5000);
                    } catch (IOException | InterruptedException | NoSuchElementException pE) {
                        Log.e(TAG, pE.toString());
                    }
                }

            }
            IOUtils.close(mOus);
        }
    }

下面是16进制字符串转换成字节数组的方法,你可以把它自己的工具类中。注意在进行写的时候,要把IO进行关闭。

	// 把16进制字符串转换成字节数组
	public static byte[] HexString2Bytes(String hexStr) {
		byte[] b = new byte[hexStr.length() / 2];
		for (int i = 0; i < b.length; i++) {
            b[i] = (byte) Integer.parseInt(hexStr.substring(2 * i, 2 * i + 2), 16);
        }
		return b;
	}

这时候你已经给设备发送了你想要读取他电池信息的指令了,接下来是不是他就要给你返回电池信息了,所以就要写一个读线程。

 class ReadBatThread extends Thread {

        InputStream ins;
        public ReadBatThread(InputStream pInputStream) {
            if (pInputStream == null) {
                throw new NullPointerException("流异常");
            }
            ins = pInputStream;
        }

        @Override
        public void run() {
            super.run();
            int count = -1;
            byte[] buf = new byte[500];
            byte[] temp;
            String data;
            ArrayList<Integer> procotol;
            while (!interrupted()) {
                try {
                    if ((count = ins.read(buf)) != -1) {
                        temp = new byte[count];
                        System.arraycopy(buf, 0, temp, 0, count);
                        data = Transform.bytesToHexString(temp);
                        procotol = new ArrayList<>((data.length()) / 2);
                        String item;
                        int element;
                        for (int i = 0; i < (data.length()) / 2; i++) {
                            item = data.substring(i * 2, i * 2 + 2);
                            element = Integer.parseInt(item, 16);
                            procotol.add(element);
                        }
                        //上面的操作是为了把byte转成hexString,便于观察,在这个协议中,最终又转换为了10进制数进行处理
                        //接下来就是根据指定的协议进行解析了,哪几位代表的是什么,怎么计算。举个例子,比如地址码是一个byte,你就可以用procotol.get(0),得到地址码的十进制数。
                    }
                } catch (IOException pE) {
                }
            }
            IOUtils.close(ins);
        }
    }

同样的不要忘记关流,下面是将字节数组转换成16进制字符串的方法。

	// 把字节数组转换成16进制字符串
	public static String bytesToHexString(byte[] byteArray) {
		StringBuffer hexStr = new StringBuffer(byteArray.length * 2);
		for (int i = 0; i < byteArray.length; i++) {
			String sTemp = Integer.toHexString(0xFF & byteArray[i]);
			int j = 0;
			while (j < 2 - sTemp.length()) {
				sTemp = "0" + sTemp;
				j++;
			}
			hexStr.append(sTemp.toUpperCase());
		}
		return hexStr.toString();
	}

上面就是串口的读取方式了,这样就可以使android板与外设进行通讯数据传递了。

2、网口
其实网口通讯的原理和串口通讯差不多,只是他们初始化的时候不一样,后面数据的读取可以说是一模一样。就是要让外设与你的android程序在同一个局域网内就可以进行通讯了,主要用到的就是socket。初始化的时候用socket对象的getOutputStream()和getInputStream()方法就可以了。

		String host = "1.1.1.1";//网络ip地址
        int port = 9999;//端口号
        Socket mSocket = new Socket(host, port);
        mSocket.getOutputStream();
        mSocket.getInputStream();

其实socket这个知识点可以去深入的了解一下,我这里就不说了,哈哈哈哈~~~
这样就串口和网口与外设信息交互的流程大致就到这里啦,如果有什么错误或不足的地方请各位大佬指出来哦,嘻嘻!!!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-01 17:03:16  更:2021-10-01 17:05:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:42:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码