codesys中打开linux端的串口_干货分享——安卓串口通信
1 引言
串行接口是一种可以将接受来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给CPU的器件。串口通信(Serial Communications)是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式。
2 串口参数
串口中有五个重要的参数:串口设备名称、波特率、奇偶校验位、数据位、停止位。设备名称:串口的名称。Linux下查看串口名称使用 ls -l /dev/ttyS*。波特率:传输速率的参数。波特率表示每秒钟传送的二进制位数。常用的有115200、9600。校验位:在串口通信中一种简单的检错方式,有四种检错方式:偶、奇、高和低,允许无校验位。数据位:通信中实际数据位的参数停止位:用于表示单个包的最后一位。
3 开发流程
由于串口通信过程处于硬件底层,使用串口通信需要在系统层次进行操作,谷歌官方为解决这种困难,使用JNI封装了SerialPort类来帮助开发者简化串口通信。
下载链接:serialPort-api。
3.1 导入SerialPort类
(1)在工程的java文件夹下创建android_serialport_api包,并将下载的SerialPort.java文件放在此包下。
(2)在java目录下创建jni目录,并将Android.mk、Application.mk、gen_SerialPort_h.sh、SerialPort.c、SerialPort.h放至此目录下。
(3)在java目录下创建jnilibs目录,将下载的armeabi、armeabi-v7a、x86拷贝至此目录。
4)在项目的bulid.gradle中添加以下代码:
sourceSets {main { jni.srcDirs = [] }
}
SerialPort源代码:
package android_serialport_api;import android.util.Log;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;public class SerialPort {private static final String TAG = "SerialPort";public FileDescriptor mFd;//输入输出数据流private FileInputStream mFileInputStream;private FileOutputStream mFileOutputStream;public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {//检查访问权限,如果没有读写权限,进行文件操作,修改文件访问权限if (!device.canRead() || !device.canWrite()) {try {//通过挂载到linux的方式,修改文件的操作权限Process su = Runtime.getRuntime().exec("/system/xbin/su");String cmd = "chmod 777 " + device.getAbsolutePath() + "n" + "exitn";su.getOutputStream().write(cmd.getBytes());if ((su.waitFor() != 0) || !device.canRead() || !device.canWrite()) {Log.e("SerialPort", "SerialPort: 没有权限");throw new SecurityException();}} catch (Exception e) {e.printStackTrace();throw new SecurityException();}}//调用本地jni方法打开串口mFd = open(device.getAbsolutePath(), baudrate, flags);if (mFd == null) {//若mFd为空则打开失败 Log.e(TAG, "native open returns null");throw new IOException();}mFileInputStream = new FileInputStream(mFd);mFileOutputStream = new FileOutputStream(mFd);}//获取输入输出流public InputStream getInputStream() {return mFileInputStream;}public OutputStream getOutputStream() {return mFileOutputStream;}// JNI(调用java本地接口,实现串口的打开和关闭)// path参数为串口路径,对应linux系统下串口的描述// baudrate 设置的波特率private native static FileDescriptor open(String path, int baudrate, int flags);//本地jni方法关闭串口public native void close();//加载jni下的C文件库static {Log.d(TAG, "本地库加载中");System.loadLibrary("serial_port");}
}
3.2 打开串口
打开串口操作在SerialPort的构造函数中完成,只需创建SerrialPort对象即可打开串口。
private String path = "/dev/ttyMT0";private int baudrate = 115200;serialPort = new SerialPort(new File(path),baudrate,0);if (serialPort == null){Log.e(TAG, "串口打开失败");}
3.3 发送数据
若要通过串口发送数据需要获取串口输出流,发送代码如下:
//获取输出数据流
outputStream = serialPort.getOutputStream();
//发送数据sendData,类型为字节数组
outputStream.write(sendData);
//刷新缓冲区
outputStream.flush();
3.4 接收数据
从串口接收需要获取串口输入流,并且读取数据需要单独开启线程,代码如下:
inputStream = serialPort.getInputStream();/*** 单开一线程,来读数据*/private class ReadThread extends Thread{@Overridepublic void run() {super.run();//判断进程是否在运行,更安全的结束进程while (!threadStatus){byte[] buffer = new byte[1024];int size; //读取数据的大小try {size = inputStream.read(buffer);if (size > 0){Log.e(TAG, "读取的数据数目 = " + size);}} catch (IOException e) {Log.e(TAG, "run: 数据读取异常:" +e.toString());}}}}
3.5 关闭串口
关闭串口之前需要先关闭数据的输入输出流,在调用close方法关闭串口,代码如下:
inputStream.close();
outputStream.close();
serialPort.close();
4 结语
通过上述过程可以实现对于串口的通信过程,为便于串口操作,可以封装SerialPortUtils类来辅助操作窗口:
SerialPortUtils.java:
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android_serialport_api.SerialPort;public class SerialPortUtils {private final String TAG = "SerialPortUtils";//串口路径private String path = "/dev/ttyMT0";//设置波特率private int baudrate = 115200;public boolean serialPortStatus = false; //是否打开串口标志public String data;public boolean threadStatus; //线程状态,为了安全终止线程public SerialPort serialPort = null;public InputStream inputStream = null;public OutputStream outputStream = null;/*** 打开串口* @return serialPort串口对象*/public SerialPort openSerialPort(){try {serialPort = new SerialPort(new File(path),baudrate,0);this.serialPortStatus = true;threadStatus = false; //线程状态//获取打开的串口中的输入输出流,以便于串口数据的收发inputStream = serialPort.getInputStream();outputStream = serialPort.getOutputStream();new ReadThread().start(); //开始线程监控是否有数据要接收} catch (IOException e) {Log.e(TAG, "openSerialPort: 打开串口异常:" + e.toString());return serialPort;}Log.d(TAG, "openSerialPort: 打开串口");return serialPort;}/*** 关闭串口*/public void closeSerialPort(){try {inputStream.close();outputStream.close();this.serialPortStatus = false;this.threadStatus = true; //线程状态serialPort.close();} catch (IOException e) {Log.e(TAG, "closeSerialPort: 关闭串口异常:"+e.toString());return;}Log.d(TAG, "closeSerialPort: 关闭串口成功");}/*** 发送串口指令(字符串)* @param data String数据指令*/public void sendSerialPort(String data){Log.e(TAG, "sendSerialPort: 发送数据");try {byte[] sendData = data.getBytes(); //string转byte[]this.data = new String(sendData); //byte[]转stringif (sendData.length > 0) {outputStream.write(sendData);outputStream.flush();Log.e(TAG, "sendSerialPort: 串口数据发送成功");}} catch (IOException e) {Log.e(TAG, "sendSerialPort: 串口数据发送失败:"+e.toString());}}/*** 单开一线程,来读数据*/private class ReadThread extends Thread{@Overridepublic void run() {super.run();//判断进程是否在运行,更安全的结束进程while (!threadStatus){Log.e(TAG, "进入线程run");//64 1024byte[] buffer = new byte[1024];int size; //读取数据的大小try {size = inputStream.read(buffer);Log.e(TAG, "size = " + size);if (size > 0){}} catch (IOException e) {Log.e(TAG, "run: 数据读取异常:" +e.toString());}}}}
}
我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。相信它会给大家带来很多收获:
上述【高清技术脑图】以及【配套的架构技术PDF】可以私信我【666】免费获取,技术问题私信我【999】免费解答。
codesys中打开linux端的串口_干货分享——安卓串口通信相关推荐
- codesys中打开linux端的串口_CODESYS版本3.5 SP14 Patch 3发布
此版本有以下内容更新 主要功能概述: CODESYS Engineering 改进了智能输入辅助.监视列表.监视. CPU负载.编译调试等; 新的数据类型:LREAL或REAL中的__VECTOR [ ...
- 在命令行中打开远程端的图形应用程序
X server是Linux系统里面图形接口服务器的简称.比较常见的Linux界面操作环境有KDE和GNOME,为它们提供系统支持的就是X server,而并非Linux核心. 介绍两种方法在命令行中 ...
- lwip协议栈优化_干货分享 | KNI性能优化实践
友情提示:全文5000多文字,预计阅读时间15分钟 文章源自现网实践对支撑及用户态/内核态网络报文交换场景的认识,欢迎有Linux/FreeBSD内核.网络协议栈.DPDK优化实践经验的同学留言探讨- ...
- vs code vue插件_干货分享 | Vue框架常见问题浅谈
友情提示:全文7800多文字,预计阅读时间10分钟 Vue是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手, ...
- 达梦数据库删除用户_干货分享丨DM8用户管理
原标题:干货分享丨DM8用户管理 用户介绍 安装创建达梦企业版数据库后,系统会默认创建四类数据库账号,分别是: SYS:达梦数据库内置管理用户,不能登录,数据库使用的大部分的数据字典和动态性能视图. ...
- sysdba 默认密码_干货分享|DM数据库密码策略和登录限制设置
在数据库的用户安全中,口令复杂度策略和资源限制是用户安全重要的一部分.在DM数据库中,口令策略分为系统口令策略和用户口令策略.只有安全版本才支持对每个用户设置口令策略(即用户口令策略),非安全版本,只 ...
- python怎么模拟浏览器交互_干货分享:python爬虫模拟浏览器的两种方法实例分析(赶紧收藏)...
今天为大家带来的内容是:干货分享:python爬虫模拟浏览器的两种方法实例分析(赶紧收藏) 文章主要介绍了python爬虫模拟浏览器的两种方法,结合实例形式分析了Python爬虫模拟浏览器的两种常见操 ...
- eureka 之前的服务如何关闭_干货分享 | 服务注册中心Spring Cloud Eureka部分源码分析...
友情提示:全文13000多文字,预计阅读时间10-15分钟 Spring Cloud Eureka作为常用的服务注册中心,我们有必要去了解其内在实现机制,这样出现问题的时候我们可以快速去定位问题.当我 ...
- android分享文件分享结果_干货分享丨DM删除归档日志文件的多种方法
上一期我们讲解了DM数据库归档日志的切换,本期我们讲解DM数据库归档日志文件的删除. 本章内容已在如下环境上测试: ①操作系统:中标麒麟7: ②数据库版本:达梦8: 相关关键字:DM数据库.归档日志文 ...
最新文章
- TP-GAN 让图像生成再获突破,根据单一侧脸生成正面逼真人脸
- 1.8 Collections类操作集合详解——排序,查找,复制
- 最好用的微型计算机,《微型计算机原理及应用》试题及答案 好
- 2017.6.12 crash的数字表格 思考记录
- AngularJS表单操作几个例子(表单提交,表单编辑默认值)
- 解决Mac Chrome打开HTTPS证书错误问题
- MySql Binlog初识
- 修改Oracle密码
- 打印机质量测试软件,打印机断针测试软件
- http 报文格式、状态码
- 7 爬虫 CrawlSpider类 增量式爬虫 分布式爬虫 生产者消费者模式
- python自动提交网页表单_Python 自动化表单提交实例代码
- 一部手机最长能用几年?
- UG二次开发GRIP刻字
- 北京 Beijing
- JavaScript 实现 标签页 切换效果
- 免费LOGO在线生成
- 1225:金银岛 题解
- 如何搭建视频通信服务器架构
- 基于社交系统ThinkSNS搭建校园社交系统
热门文章
- Arrays.sort() 为什么可以对 int 等数组进行排序?我跟面试官扯了半个小时 | 原力计划...
- 我通过了 Google 技术面试,所以你也能行!
- 从 Pod 到案例,给小白的 Kubernetes 技术课
- 计算机界 TOP 3 难题:“相等”是软件工程中许多重大问题的根源!
- 在家远程办公效率低?那你一定要收好这个「在家办公」神器!
- 知乎热议!学完 Python 之后,我的编程能力竟然退化了!
- 微信回应 iOS 13.2 杀后台;谷歌以 21 亿美元收购 Fitbit;优麒麟 19.10.1 发布 | 极客头条...
- 保温杯都这么给力了,你的 Bug 就不能少点?
- 即使在微软 Azure 上,Linux 也大有一统天下之势!
- 中国如何在 AI 芯片实现弯道超车?