如下表不同操作系統(tǒng)的串口地址,Android是基于Linux的所以一般情況下使用Android系統(tǒng)的設(shè)備串口地址為/dev/ttyS0...
成都創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作與策劃設(shè)計(jì),廊坊網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:廊坊等地區(qū)。廊坊做網(wǎng)站價(jià)格咨詢:13518219792
最近有項(xiàng)目需要實(shí)現(xiàn)windows機(jī)器和Android開發(fā)版進(jìn)行UART串口通信,經(jīng)過3天查找嘗試,特記錄一下最終方案,希望之后的同行少走彎路,最后在git上回開源我最終的方案希望大家支持。
Android 3.0.1
Gradle 4.1
ARM開發(fā)版 : RK3399
PC機(jī)器:Win10
開發(fā)機(jī)器:MAC 10.13.3
先上圖
由于 android-serialport-api 項(xiàng)目中的so使用較old的ndk編譯,所以在對(duì)于Android 6.0 以上版本兼容的時(shí)候會(huì)報(bào)錯(cuò) dlopen failed: "has text relocations" 。且使用的mk進(jìn)行編譯,特升級(jí)為用cmake編譯。
升級(jí) android-serialport-api
項(xiàng)目結(jié)構(gòu):
app對(duì)應(yīng)原項(xiàng)目中的各個(gè)Activity, androidserial 是module 對(duì)應(yīng)編譯之前的so,還有API的封裝。可以直接引用androidserial,調(diào)用方法參考app目錄下的activity。
注意 關(guān)于權(quán)限!
當(dāng)接入開發(fā)板后如果發(fā)現(xiàn) Error You do not have read/write permission to the serial port 需要root 權(quán)限 ,在開發(fā)者模式中開啟root 權(quán)限 adb和應(yīng)用
使用一下命令開啟Android對(duì)串口的讀寫權(quán)限
setenforce 0 : 關(guān)閉防火墻,有人說關(guān)鍵是這,但是我的環(huán)境不用關(guān)閉,只要給權(quán)限就可以
注意 關(guān)于ttyS1 - 6 ttyS1 - 6 對(duì)應(yīng)的是 UART 串口1-6 一般都是一一對(duì)應(yīng)的。這個(gè)具體要看一下開發(fā)板的說明。
記錄的比較糙,還請(qǐng)見諒,如有問題請(qǐng)留言,我看到后肯定回復(fù)。項(xiàng)目主要看結(jié)構(gòu),剩下的都是復(fù)制黏貼的事。 git地址:
使用CH340串口
亂碼解決方案
1.排除通訊波特率等。
2.先UartInit(),再調(diào)用SetConfig(...)。
MyAppCH340.driver.UartInit();
MyAppCH340.driver.SetConfig(9600,(byte)8,(byte)1,(byte)0,(byte)0);
1.打開串口。
2.串口處于監(jiān)聽狀態(tài)
3.想串口寫入數(shù)據(jù),串口接收到數(shù)據(jù)返回?cái)?shù)據(jù)
SerialPort類所在的包一定要和上圖包名一直,因?yàn)榇谕ㄓ嵭枰褂胘ni中的函數(shù)。
package android_serialport_api;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.fx.serialporttest.L;
public class SerialPort {
/*
* Do not remove or rename the field mFd: it is used by native method
* close();
*/
private FileDescriptor mFd;
private FileInputStream mFileInputStream;
private FileOutputStream mFileOutputStream;
/**
* 構(gòu)造方法
* @param device 串口地址
* @param baurate 波特率
* @param flags
* @throws IOException
* @throws InterruptedException
*/
public SerialPort(File device,int baudrate,int flags) {
/*
* 檢測(cè)是否有訪問權(quán)限
*/
if(!device.canRead()||!device.canWrite()){
//如果沒有讀寫權(quán)限,嘗試chmod命令這個(gè)文件
L.tag("沒有讀寫權(quán)限");
Process su;
try {
su = Runtime.getRuntime().exec("/system/bin/su");//獲取root讀寫權(quán)限
String cmd = "chmod 777"+device.getAbsolutePath()+"\n"+"exit\n";
su.getOutputStream().write(cmd.getBytes()); //向此路徑文件寫入命令
if((su.waitFor()!=0||!device.canRead()||!device.canWrite())){
throw new SecurityException();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
mFd = open(device.getAbsolutePath(),baudrate,flags);
if(mFd==null){
mFd = open(device.getAbsolutePath(),baudrate,flags);
L.tag("native open return null");
}
mFileInputStream = new FileInputStream(mFd);
mFileOutputStream = new FileOutputStream(mFd);
}
public FileInputStream getmFileInputStream() {
return mFileInputStream;
}
public void setmFileInputStream(FileInputStream mFileInputStream) {
this.mFileInputStream = mFileInputStream;
}
public FileOutputStream getmFileOutputStream() {
return mFileOutputStream;
}
public void setmFileOutputStream(FileOutputStream mFileOutputStream) {
this.mFileOutputStream = mFileOutputStream;
}
//JNI
private native static FileDescriptor open(String path,int baudrate,int flags);
public native void close();
static {
System.loadLibrary("serial_port");
}
}
package android_serialport_api;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.fx.serialporttest.L;
public? class SerialPortFinger {
private static ReadThread readThread;
private static FileInputStream mFileInputStream;
private static FileOutputStream mFileOutputStream;
static String path = "/dev/ttyS0";//設(shè)備主板的串口地址,地址有所不同
public? void startListener(){
SerialPort serialPort = new SerialPort(new File(path), 9600, 0);//9600是波特率,這個(gè)也是有所不同,具體要看設(shè)備
mFileInputStream = serialPort.getmFileInputStream();
mFileOutputStream = serialPort.getmFileOutputStream();//獲取串口寫入流
readThread? = new ReadThread();
readThread.start();//開啟監(jiān)聽
}
/**
* 發(fā)送指令到串口
*
* @param cmd
* @return
*/
public boolean sendCmds(String cmd) {
boolean result = true;
byte[] mBuffer = (cmd+"\r\n").getBytes();
try {
if (mFileOutputStream != null) {
mFileOutputStream.write(mBuffer);
} else {
result = false;
}
} catch (IOException e) {
e.printStackTrace();
result = false;
}
return result;
}
static class ReadThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
int len;
StringBuffer sb = new StringBuffer("");
while(true){ //循環(huán)監(jiān)聽串口,讀取返回的數(shù)據(jù)
byte[] buffer = new byte[1024];
if(mFileInputStream==null){
return;
}
try {
len = mFileInputStream.read(buffer);
if(len0){
sb.append(new String(buffer, 0, len));
}
if(!sb.toString().equals(""))
{
L.tag(sb.toString());//收到串口的返回?cái)?shù)據(jù),在日志中打印出來
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
L.tag("接受完成");
}
}
}
}
Android串口通信簡單封裝,可以用于和連接串口的硬件通信或者進(jìn)行硬件調(diào)試
Step 1. Add the JitPack repository to your build file
Step 2. Add the dependency
讀取文件權(quán)限應(yīng)該是需要的
獲取所有串口地址
打開串口,設(shè)置讀取返回?cái)?shù)據(jù)超時(shí)時(shí)間
發(fā)送指令
打開或者關(guān)閉日志,默認(rèn)關(guān)閉
//關(guān)閉串口
網(wǎng)頁題目:android的串口,Android串口
網(wǎng)頁鏈接:http://vcdvsql.cn/article28/dsigscp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、網(wǎng)站排名、、靜態(tài)網(wǎng)站、虛擬主機(jī)、網(wǎng)頁設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)