天天看點

安卓開發中如何使用序列槽進行通信

寫在前面

  • 很久不寫部落格,然後最近因為需要用到安卓闆子上的序列槽,然後看了好多文章,發現好多文章都是複制來複制去的,一點邏輯都沒有,實在受不了噢,無奈之下,隻能自己做個筆記了。

準備工作

  • 安卓開發工具,Android Studio 我這裡的版本是3.6.3
  • 安卓SDK 我選擇了API29
  • 安卓Builde Tools 選擇了29.0.3
  • NDK選擇了:android-ndk-r17c
  • 對于環境這塊,如果後續要更新這篇文章的話,到時候會同意整一個環境搭建篇。畢竟我現在也是半桶水,半路出家搞安卓平台相關的。

搭建工程

  • 老樣子,在安卓Studio界面的工具欄中選擇File->New->New Project
    安卓開發中如何使用序列槽進行通信
  • 建立的檔案名稱,包類型之類的資訊如下,最後選擇finish
    安卓開發中如何使用序列槽進行通信

環境配置

  • 在app/build.gradle檔案配置中的dependencies,加上
安卓開發中如何使用序列槽進行通信
  • 在gradle/build.gradle中添加
安卓開發中如何使用序列槽進行通信
  • 工程編譯設定,這裡按照預設的方式設定就可以.
安卓開發中如何使用序列槽進行通信
  • 在根目錄下的local.properties檔案中,添加ndk路徑,這裡的ndk上網搜一下,很容易下載下傳到的
ndk.dir= 你們ndk的路徑
           
安卓開發中如何使用序列槽進行通信
  • 最後點選Android Studio 工具欄上的Run->run app,編譯運作。

應用程式

  • 在activity檔案中,添加一個按鍵控件,并将id取為button2
    安卓開發中如何使用序列槽進行通信
  • 代碼方面,建立2個class,具體代碼如下
安卓開發中如何使用序列槽進行通信
  • MainActivity代碼如下
package com.kuensan.uart;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private rs485Thread Rs485nThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button) this.findViewById(R.id.button2);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TODO Auto-generated method stub
                setTitle("button1 被使用者點選了");
                Log.i("widgetDemo", "button2 被使用者點選了。");
                System.out.println("被使用者點選了 111");

                startGuestScreen();
            }
        });
    }

    private void startGuestScreen() {
        if (Rs485nThread == null) {
            Rs485nThread = new rs485Thread("/dev/ttyHSL2", 115200);
        }
        if (!Rs485nThread.isAlive()) {
            Rs485nThread.start();
        }

        Rs485nThread.sendRs485Data();
    }

}

           
  • rs485Thread代碼如下
package com.kuensan.uart;

import android.util.Log;
import android.serialport.SerialPort;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidParameterException;
import java.util.Arrays;


public class rs485Thread extends Thread {

    protected SerialPort mSerialPort;
    protected OutputStream mOutputStream;
    private InputStream mInputStream;


    public rs485Thread(String deviceName, int baudrate) {
        try {
            closeSerialPort();
            if (mSerialPort == null) {
                mOutputStream = mSerialPort.getOutputStream();
                mInputStream = mSerialPort.getInputStream();
                mSerialPort = getSerialPort(deviceName, baudrate);
            }
        } catch (InvalidParameterException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * @Title: closeSerialPort
     * @Description: 關閉序列槽
     * @param:
     * @return: void
     */
    private void closeSerialPort() {
        if (mSerialPort != null) {
            mSerialPort.close();
            mSerialPort = null;
        }
        if (mOutputStream != null) {
            try {
                mOutputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (mInputStream != null) {
            try {
                mInputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /**
     * @Title: getSerialPort
     * @Description: 打開序列槽裝置
     * @param: @param deviceName 序列槽裝置名
     * @param: @return 傳回序列槽類執行個體對象
     * @param: @throws SecurityException
     * @param: @throws IOException
     * @param: @throws InvalidParameterException
     * @return: SerialPort
     */
    private SerialPort getSerialPort(String deviceName, int baudrate)
            throws SecurityException, IOException, InvalidParameterException {
        if (mSerialPort == null) {
            /* Open the serial port */
            mSerialPort = new SerialPort(new File(deviceName), baudrate);
        }
        return mSerialPort;
    }

    /**
     * @Title: serialPortSendData
     * @Description: 發送資料
     * @param: @param data 要發送的資料的數組
     * @param: @return
     * @return: boolean 成功true 失敗false
     */
    public boolean serialPortSendData(byte[] data) {
        if (mOutputStream == null) {
            return false;
        }
        try {
            Log.d("dove", "發送的資料是:" + Arrays.toString(data));
            mOutputStream.write(data);
            mOutputStream.flush();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void sendRs485Data() {

        byte[] bData = new byte[8];
        int iLen = 0;

        bData[iLen++] = (byte) 0xAA;//開頭
        bData[iLen++] = (byte) 0x11;//發送字的标記

        bData[iLen++] = (byte) 0x22;

        bData[iLen++] = (byte) 0x33;
        bData[iLen++] = (byte) 0x44;

        bData[iLen++] = (byte) 0x55;
        bData[iLen++] = (byte) 0x66;

        bData[iLen++] = (byte) 0;

        serialPortSendData(bData);

    }
}

           
  • 最後進行編譯,安裝到目标闆上,這裡我根據硬體序列槽位置,選擇了 dev/ttyHSL2裝置,波特率設定為115200

驗證

  • 闆子現在不在手上,是以先不進行驗證了,待闆子回來的時候再驗證。