Android开发板串口(SerialPort)通信
Android开发板串口(SerialPort)通信
Roy88关注
22017.09.07 18:01:22字数 1,618阅读 28,511
前言:
最近在总是看见有人在群里面问一些串口通信相关的问题,特别是对于我们这些做APP出生的程序员来说,初次接触串口通信的确是会遇到各种Bug,各种摸不着头脑。串口通信偏向嵌入式一点,是Android设备通过串口与其他设备进行通信的一种方式,本文介绍的Android纯串口的通信,并不是手机上的USB串口通信。
简介:
首先简述一下此项目应用,它是一个简单的物联网智能盒子,主要工作:是通过Android开发板上的串口进行数据读写操作。一块Android开发板外接一个单片机,Android上面跑有MQTT服务与后台服务器通信,Android机收到MQTT发布的不同信息后,将信息转换成不同的串口指令发给单片机,Android板收到对应的MQTT消息就做相应的界面处理并将MQTT消息转换成不同的串口指令发给单片机,然后单片机直接控制硬件设备工作。
一、什么是串口?
串行端口 (SerialPort)简称:串口,主要用于数据被逐位按顺序传送的通讯方式称为串口通讯(简单来讲就是按顺序一位一位地传输数据)。
常见的串口有25针和9针(遵循RS-232标准)
二、串口通信原理
串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节。
串口用于ASCII码字符的传输。通信使用3根线完成,分别是地线(GND)、发送(TX)、接收(RX)。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。
三、Android应用串口通信的实现
Android SDK并没有在Framework层实现封装关于串口通信的类库。但是,Android是基于Linux kernel 2.6上的,所以我们可以像在Linux系统上一样来使用串口。因为Framework层中并没有封装关于串口通信的类库,所以我们需要通过Android NDK来实现打开、读写串口,然后提供接口供JAVA本地调用。
这里可以参照Google已经给出了源码,地址在GitHub android-serialport-api
这是12年的代码,还是Eclipse工程,本文主要介绍如何在Android Studio中使用。这里先得配置好NDK环境
1:项目配置
首先看一下项目结构:创建了一个jni目录,jni目录用来放生成的头文件(.h文件)及Java本地方法的C代码实现类;
此Demo支持多串口通信
Java层的代码,Google已经给封装好了,主要的都在 SerialPort.java
第一步:拷贝创建 native方法的java类 SerialPort.java 到自己的项目中;
第二步:生成.h头文件; 生成方法有多种,这里使用 cd \app\src\main\java 进入到java目录下;
方式1: javah -classpath . -jni +全限定类名;
方式2:javah -d ../jni +全限定类名;(此方式会直接创建一个jni目录,然后把生成的.h文件存放在目录里面)
第三步:实现SerialPort.java类中的本地方法,这里直接拷贝Google写好的C实现,将c代码中的函数名与生成的头文件中的函数名保持一致
配置build.gradle
如需帮助请 + QQ:631934797
使用
串口作操都封装到SerialPortUtil类中
/**
* Created by Roy88 on 2017/6/18.
*
*串口工具类
*/
public classSerialPortUtil {
private static finalStringTAG= SerialPortUtil.class.getSimpleName();
public staticSerialPortserialPort=null;
public staticInputStreammInputStream=null;
public staticOutputStreammOutputStream=null;
public static booleanflag=false;
private staticBufferedReaderbr;
/**
* 打开串口
*/
public static voidopenSrialPort(String port, intbaudrate){
Log.i(TAG,"打开串口");
try{
serialPort=newSerialPort(newFile("/dev/"+ port),baudrate,0);
//获取打开的串口中的输入输出流,以便于串口数据的收发
mInputStream=serialPort.getInputStream();
mOutputStream=serialPort.getOutputStream();
flag=true;
//接收串口数据
receiveSerialPort();
}catch(IOException e) {
e.printStackTrace();
}
}
/**
* 接收串口数据
*/
public static voidreceiveSerialPort(){
newThread(newRunnable() {
@Override
public voidrun() {
//循环接收串口数据
while(flag) {
try{
if(mInputStream==null)return;
br=newBufferedReader(newInputStreamReader(mInputStream));
String str;
while((str =br.readLine()) !=null)
{
if(TextUtils.isEmpty(str))continue;
Log.i(TAG,"接收串口数据:"+ str);
if(String.valueOf(str.charAt(0)).equals("{") && str.substring(str.length() -1).equals("}")){
acceptAndNotify(str);
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
/**
* 区分收到的指令数据并分类分发
*
*@paramjsonBack收到的JSON指令
*/
private static voidacceptAndNotify(String jsonBack) {
if(jsonBack ==null||"".equals(jsonBack.trim()))
throw newIllegalArgumentException("JsonBack is illegal, please check args ... ");
JsonParser jsonParser =newJsonParser();
JsonObject json = (JsonObject) jsonParser.parse(jsonBack);
if(json ==null)
throw newJsonParseException("Json Parse error, please check args ... ");
String protocolResult = json.getAsJsonPrimitive("protocol").getAsString();
if(protocolResult ==null||"".equals(protocolResult))
throw newNumberFormatException("转化错误... ");
switch(protocolResult) {
case"coin_in":
// EventBus.getDefault().post(new SerialPortEvent(GsonUtil.parse(jsonBack, CoinAndRemoteCoinBean.class)));
break;
case"remote_coin_in":
// EventBus.getDefault().post(new SerialPortEvent(GsonUtil.parse(jsonBack, CoinAndRemoteCoinBean.class)));
break;
case"key_event":
// EventBus.getDefault().post(new SerialPortEvent(GsonUtil.parse(jsonBack, OrientationAndKeyBean.class)));
break;
}
}
/**
* 发送串口数据
*@paramdata要发送的数据
*/
public static voidsendSerialPort(String data){
Log.i(TAG,"发送串口数据:"+ data);
try{
byte[] sendData = data.getBytes();
mOutputStream.write(sendData);
mOutputStream.flush();
Log.i(TAG,"发送串口数据成功!");
}catch(IOException e) {
e.printStackTrace();
Log.i(TAG,"发送串口数据失败!");
}
}
/**
*关闭串口
*关闭串口中的输入输出流
*然后将flag的值设为flag,终止接收数据线程
*/
public static voidcloseSerialPort(){
Log.i(TAG,"关闭串口");
try{
if(serialPort!=null) {
serialPort.close();
}
if(mInputStream!=null) {
mInputStream.close();
}
if(mOutputStream!=null){
mOutputStream.close();
}
if(br!=null){
br.close();
}
flag=false;
}catch(IOException e) {
e.printStackTrace();
}
}
}
本文没有介绍关于jni、NDK的内容,因为上网有很讲这方面知识讲解。如有不了解的请自行百度、google。
注意:
不同的开发板操作的串口路径是不同的,比如我的开发板上的串口路径是“/dev/ttyS5”;还有就是数据传输的波特率要设置成一致,不然收到的数据会乱码。
如需帮助请 + QQ:631934797
Android开发板串口(SerialPort)通信相关推荐
- android 板串口路径,Android开发板串口读写操作
首先,把com.friendlyarm.AndroidSDK包(自己下载)添加到项目中. //打开串口,返回串口描述符fd fd = HardwareControler.openSerialPort( ...
- Android开发板之串口开发
Android开发板之串口开发 简介 首先描述一下我的应用项目,它是一个简单的智能盒子,主要内容:是通过Android开发板上的串口进行数据的读取操作,一块android开发板外接一个Arduino, ...
- android开发板只有网口和串口如何使用android studio进行调试
android开发板只有网口和串口如何使用android studio进行调试 1.要先准备一条串口线,或者串口转usb的线,用于在pc端与开发板端建立连接. 2.要下载一个在pc端运行的超级终端,我 ...
- Android开发板
由于公司要做智能自助设备,因此需要在Android开发板上开发,记录一下经验 一.Android开发板应用 Android开发板应用: 商业应用:机顶盒.广告机,自助机,售卖机,多媒体教学,人脸识别, ...
- Android开发板 MTK 4g/5g 安卓开发板定制
厂商:深圳新移科技 公司介绍:专业提供 4G.5G 安卓核心板 / 开发板.物联网方案.整机定制开发生产 一.Android 开发板应用: 商业应用:安防监控,图像识别设备,4G 音视频传输,智能手持 ...
- Android开发板开发总结
ADB常见命令 adb connect ip[:port]:连接Android开发板(要求开发板开启ADB服务) adb disconnect ip:断开与Android开发板的连接 adb shel ...
- 在Android开发板跑一个LED驱动的历程(个人笔记)
[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) 在Android开发板跑一个LED驱动的历程(个人笔记) 1. 板子端, 放置驱动程序 1.1 编写一个驱动程序 驱动程序的编写上, ...
- 树莓派Pico W无线开发板MQTT协议通信MicroPython编程实践
本博文介绍采用Thonny+MicroPython和umqtt.simple库MQTTClient类的对象方法编制树莓派Pico W无线开发板MQTT协议通信程序,将Pico W无线开发板.电脑或An ...
- [安卓开发板]迅为IMX6 四核Android开发板
工业级核心板-Android开发板 10层高速PCB设计,充分保证电磁兼容 处理器:开发板默认是四核商业扩展级芯片,可根据用户需求更换单核.双核.工业级.汽车级处理器,批量更省成本. 扩展引脚:320 ...
最新文章
- QWidget一生,从创建到销毁事件流
- 如何看待Spring下单例模式与线程安全的矛盾
- html保存blob,HTML文本图像并保存为Blob到数据库
- Java面向对象(四)final关键字
- 信用卡逾期三个月以上不还?小心坐牢!
- dig下载_DIG的完整形式是什么?
- mysql数据库连接配置路径_关于mysql安装后更改数据库路径方法-linux环境
- 期权“不公平”是认识上的错误
- 程序执行原理(科普)
- mfc三视图和斜等测图实现_编程实现TCP协议数据传输
- php 抽奖活动_php 实现活动人选抽奖功能代码
- oracle序列建同义词,oracle序列创建同义词
- 黎曼的zeta函数(0)
- 通过香港招行一卡通收回PayPal资金
- spring boot 1.x和 2.x通过代码修改默认address和端口
- 相册里的WEB3 Festivals香港记忆
- 计算机用户与权限如何设置密码,如何设置电脑用户权限_如何设置电脑使用时间...
- 【Node.js】前端页面仔的必修课,认识node
- 重要通知丨涂鸦安防SaaS产品 新版本发布!
- 贝叶斯方法和采样技术结合-MCMC-后验分布
热门文章
- 爬取五大平台621款手机,告诉你双十一在哪买最便宜!
- [问题解决]delphi中找不到DCU文件问题解决方案
- `算法知识` 笛卡尔坐标系, 边长与边权, 曼哈顿距离, 欧几里得距离,外接矩形
- linux mint18 +nvidia GTX 1060+CUDA 9.0
- 哈利波特魔法觉醒冬青心愿怎么玩
- 东北大学秦皇岛分校计算机类排名,2021年东北大学秦皇岛分校重点专业排名及优势王牌专业分数线(文科 理科)...
- Linux 复制文件到当前文件夹
- 要不要去北京上海发展?
- Web核心技术之JSP(过时技术)
- EOF和NULL的区别