当前位置:   article > 正文

快速开发和使用Android串口_android 串口开发

android 串口开发

一、什么是串口

        串口叫做串行接口,也称串行通信接口,也可以叫做COM口,按电气标准及协议来分包括RS-232-C、RS-422、RS485、USB等。串行接口是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信,从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。

二、串口通讯方式

  • 单工模式:只支持数据在一个方向上传输;在同一时间只有一方能接收或发送信息,不能实现双向通信。一般用在只向一个方向传输数据的场合,比如跟打印机通讯。
  • 半双工模式:如果只有一条通讯线,那么它既可以发送数据也可以接收数据,但不能同时进行发送和接收。如果使用两条通讯线,数据可以在两个方向传输,但是在同一时间只可以有一方接受或发送信息,实际上是一种切换方向的单工通讯。比如RS485-2W通讯就是采用这种模式。
  • 全双工模式:数据可以同时往两个方向传输,相当于两个单工通讯的结合,它要求发送设备和接收设备都有独立的发送和接收能力,在同一时间可以同时进行发送和接收数据,实现双向通信,数据传输效率比较高。比如RS-232通讯就是采用这种模式。

串口通讯是一个字符一个字符地传输,每个字符一位一位地传输,总是以“起始位”开始,以“停止位”结束,字符之间没有固定的时间间隔要求。
实际传输时每一位的信号宽度与波特率有关,波特率越高,宽度越小,在进行传输之前,双方一定要使用同一个波特率。 

三、Android串口开发

        通过使用serialport库,直接上代码 :

第一步导包:

// 在项目根目录的build.gradle文件中添加:
allprojects {
    repositories {
        ...
        mavenCentral()
    }
}
// 在项目Module下的build.gradle文件中添加:
dependencies {
    implementation 'io.github.xmaihh:serialport:2.1.1'
}

第二步代码:

  1. import android.os.Build;
  2. import android.os.Bundle;
  3. import android.os.Handler;
  4. import android.os.Message;
  5. import android.os.SystemClock;
  6. import android.support.annotation.RequiresApi;
  7. import android.support.v7.app.AppCompatActivity;
  8. import android.util.Log;
  9. import android.view.View;
  10. import android.widget.EditText;
  11. import android.widget.RadioGroup;
  12. import android.widget.Toast;
  13. import com.alibaba.fastjson.JSONObject;
  14. import java.io.IOException;
  15. import java.io.InputStream;
  16. import butterknife.BindView;
  17. import butterknife.ButterKnife;
  18. import butterknife.OnClick;
  19. import tp.xmaihh.serialport.SerialHelper;
  20. import tp.xmaihh.serialport.bean.ComBean;
  21. import tp.xmaihh.serialport.stick.AbsStickPackageHelper;
  22. import tp.xmaihh.serialport.utils.ByteUtil;
  23. public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {
  24. @BindView(R.id.rg_type)
  25. RadioGroup mRgType;
  26. @BindView(R.id.et_read_content)
  27. EditText mEtReadContent;
  28. @BindView(R.id.et_send_content)
  29. EditText mEtSendContent;
  30. private SerialHelper serialHelper;
  31. private boolean isHexType = false;
  32. private String text = "";
  33. private Handler mHandler = new Handler(new Handler.Callback() {
  34. @Override
  35. public boolean handleMessage(Message msg) {
  36. ComBean comBean = (ComBean) msg.obj;
  37. String time = comBean.sRecTime;
  38. String rxText;
  39. rxText = new String(comBean.bRec);
  40. if (isHexType) {
  41. //转成十六进制数据
  42. rxText = ByteUtil.ByteArrToHex(comBean.bRec);
  43. }
  44. text += "Rx-> " + time + ": " + rxText + "\r" + "\n";
  45. mEtReadContent.setText(text);
  46. return false;
  47. }
  48. });
  49. @RequiresApi(api = Build.VERSION_CODES.M)
  50. @Override
  51. protected void onCreate(Bundle savedInstanceState) {
  52. super.onCreate(savedInstanceState);
  53. setContentView(R.layout.activity_main);
  54. ButterKnife.bind(this);
  55. mRgType.setOnCheckedChangeListener(this);
  56. initSerialConfig();
  57. }
  58. private void initSerialConfig() {
  59. //初始化SerialHelper对象,设定串口名称和波特率(此处为接收扫码数据)
  60. serialHelper = new SerialHelper("/dev/ttyACM0", 9600) {
  61. @Override
  62. protected void onDataReceived(ComBean paramComBean) {
  63. Message message = mHandler.obtainMessage();
  64. message.obj = paramComBean;
  65. Log.e("TAG", "onDataReceived: " + JSONObject.toJSONString(message.obj));
  66. mHandler.sendMessage(message);
  67. }
  68. };
  69. /*
  70. * 默认的BaseStickPackageHelper将接收的数据扩展成64位,一般用不到这么多位
  71. * 我这里重新设定一个自适应数据位数的
  72. */
  73. serialHelper.setStickPackageHelper(new AbsStickPackageHelper() {
  74. @Override
  75. public byte[] execute(InputStream is) {
  76. try {
  77. int available = is.available();
  78. if (available > 0) {
  79. byte[] buffer = new byte[available];
  80. int size = is.read(buffer);
  81. if (size > 0) {
  82. return buffer;
  83. }
  84. } else {
  85. SystemClock.sleep(50);
  86. }
  87. } catch (IOException e) {
  88. e.printStackTrace();
  89. }
  90. return null;
  91. }
  92. });
  93. }
  94. @OnClick({R.id.bt_open, R.id.bt_close, R.id.bt_send, R.id.bt_clear_content})
  95. public void onButtonClicked(View view){
  96. switch (view.getId()) {
  97. case R.id.bt_open:
  98. if (serialHelper.isOpen()) {
  99. Toast.makeText(this, Const.SPORT_NAME + "串口已经打开", Toast.LENGTH_SHORT).show();
  100. return;
  101. }
  102. try {
  103. serialHelper.open();
  104. } catch (IOException e) {
  105. e.printStackTrace();
  106. }
  107. Toast.makeText(this, Const.SPORT_NAME + "串口打开成功", Toast.LENGTH_SHORT).show();
  108. break;
  109. case R.id.bt_close:
  110. if (serialHelper.isOpen()) {
  111. serialHelper.close();
  112. Toast.makeText(this, Const.SPORT_NAME + "串口已经关闭", Toast.LENGTH_SHORT).show();
  113. }
  114. break;
  115. case R.id.bt_clear_content:
  116. text = "";
  117. mEtReadContent.setText(text);
  118. break;
  119. case R.id.bt_send:
  120. if (!serialHelper.isOpen()) {
  121. Toast.makeText(this, Const.SPORT_NAME + "串口没打开 发送失败", Toast.LENGTH_SHORT).show();
  122. return;
  123. }
  124. String sendContent = mEtSendContent.getText().toString();
  125. if (isHexType) {
  126. serialHelper.sendHex(sendContent);
  127. } else {
  128. serialHelper.sendTxt(sendContent);
  129. }
  130. break;
  131. }
  132. }
  133. @Override
  134. public void onCheckedChanged(RadioGroup group, int checkedId) {
  135. switch (checkedId) {
  136. case R.id.rb_txt:
  137. isHexType = false;
  138. mEtSendContent.setText(Const.TXT_TYPE_SEND);
  139. break;
  140. case R.id.rb_hex:
  141. isHexType = true;
  142. mEtSendContent.setText(Const.HEX_TYPE_SEND);
  143. break;
  144. }
  145. }
  146. @Override
  147. protected void onDestroy() {
  148. super.onDestroy();
  149. serialHelper.close();
  150. serialHelper = null;
  151. }
  152. }
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. tools:context=".MainActivity">
  8. <!--串口操作部分-->
  9. <LinearLayout
  10. android:layout_width="match_parent"
  11. android:layout_height="wrap_content"
  12. app:layout_constraintBottom_toTopOf="@id/ll_read_data"
  13. android:layout_marginBottom="@dimen/dp_10"
  14. android:orientation="horizontal">
  15. <Button
  16. android:id="@+id/bt_open"
  17. android:layout_width="0dp"
  18. android:layout_weight="1"
  19. android:layout_height="wrap_content"
  20. android:text="@string/open_serial"
  21. android:layout_marginStart="@dimen/dp_10"
  22. android:layout_gravity="center_vertical"/>
  23. <TextView
  24. android:layout_width="0dp"
  25. android:layout_weight="1"
  26. android:layout_height="wrap_content"
  27. android:textSize="@dimen/edit_text_size"
  28. android:text="@string/data_type"
  29. android:layout_marginStart="@dimen/dp_10"
  30. android:layout_gravity="center_vertical"/>
  31. <RadioGroup
  32. android:id="@+id/rg_type"
  33. android:layout_width="0dp"
  34. android:layout_weight="2"
  35. android:layout_height="wrap_content"
  36. android:layout_gravity="center"
  37. android:layout_marginStart="@dimen/dp_10"
  38. android:orientation="horizontal">
  39. <RadioButton
  40. android:id="@+id/rb_txt"
  41. android:layout_width="0dp"
  42. android:layout_weight="1"
  43. android:layout_height="wrap_content"
  44. android:checked="true"
  45. android:text="@string/data_type_txt"/>
  46. <RadioButton
  47. android:id="@+id/rb_hex"
  48. android:layout_width="0dp"
  49. android:layout_weight="1"
  50. android:layout_height="wrap_content"
  51. android:layout_marginStart="@dimen/dp_10"
  52. android:text="@string/data_type_hex"/>
  53. </RadioGroup>
  54. <Button
  55. android:id="@+id/bt_close"
  56. android:layout_width="0dp"
  57. android:layout_weight="1"
  58. android:layout_height="wrap_content"
  59. android:text="@string/close_serial"
  60. android:layout_marginStart="@dimen/dp_10"
  61. android:layout_marginEnd="@dimen/dp_10"
  62. android:layout_gravity="center_vertical"/>
  63. </LinearLayout>
  64. <!--数据接收部分-->
  65. <LinearLayout
  66. android:id="@+id/ll_read_data"
  67. android:layout_width="match_parent"
  68. android:layout_height="wrap_content"
  69. app:layout_constraintTop_toTopOf="parent"
  70. app:layout_constraintBottom_toBottomOf="parent"
  71. android:orientation="horizontal">
  72. <!--数据接收显示-->
  73. <EditText
  74. android:id="@+id/et_read_content"
  75. android:layout_width="0dp"
  76. android:layout_height="200dp"
  77. android:layout_marginStart="@dimen/dp_10"
  78. android:layout_weight="6"
  79. android:background="@drawable/edit_bg"
  80. android:cursorVisible="false"
  81. android:focusable="false"
  82. android:focusableInTouchMode="false"
  83. android:gravity="top"
  84. android:padding="@dimen/dp_5"
  85. android:textSize="@dimen/edit_text_size" />
  86. <Button
  87. android:id="@+id/bt_clear_content"
  88. android:layout_width="0dp"
  89. android:layout_weight="1"
  90. android:layout_height="wrap_content"
  91. android:text="@string/clear_all_data"
  92. android:layout_marginStart="@dimen/dp_10"
  93. android:layout_marginEnd="@dimen/dp_10"
  94. android:layout_gravity="center_vertical"/>
  95. </LinearLayout>
  96. <View
  97. android:id="@+id/view_line"
  98. android:layout_width="match_parent"
  99. android:layout_height="@dimen/dp_2"
  100. android:layout_marginTop="@dimen/dp_10"
  101. android:layout_marginStart="@dimen/dp_10"
  102. android:layout_marginEnd="@dimen/dp_10"
  103. android:background="@color/colorAccent"
  104. app:layout_constraintTop_toBottomOf="@id/ll_read_data"/>
  105. <!--数据发送部分-->
  106. <LinearLayout
  107. android:id="@+id/ll_send_data"
  108. android:layout_width="match_parent"
  109. android:layout_height="wrap_content"
  110. app:layout_constraintTop_toBottomOf="@id/view_line"
  111. android:layout_marginTop="@dimen/dp_10"
  112. android:orientation="horizontal">
  113. <!--数据接收显示-->
  114. <EditText
  115. android:id="@+id/et_send_content"
  116. android:layout_width="0dp"
  117. android:layout_height="200dp"
  118. android:layout_marginStart="@dimen/dp_10"
  119. android:layout_weight="6"
  120. android:singleLine="false"
  121. android:background="@drawable/edit_bg"
  122. android:gravity="top"
  123. android:padding="@dimen/dp_5"
  124. android:inputType="text"
  125. android:textSize="@dimen/edit_text_size"
  126. android:text="@string/txt_data"/>
  127. <Button
  128. android:id="@+id/bt_send"
  129. android:layout_width="0dp"
  130. android:layout_weight="1"
  131. android:layout_height="wrap_content"
  132. android:text="@string/send_data"
  133. android:layout_marginStart="@dimen/dp_10"
  134. android:layout_marginEnd="@dimen/dp_10"
  135. android:layout_gravity="center_vertical"/>
  136. </LinearLayout>
  137. </android.support.constraint.ConstraintLayout>

 第三步说明:

        上面代码,在创建serialHelper之时,就已经传入了一个onDataReceived()方法,用来监听串口数据接收,但是如要打开串口才能开启监听。

SerialHelper创建完成,打开串口

serialHelper.open();

如果需要设置其他的属性,比如设置奇偶检验,需要在执行open()之前设定。

serialHelper.setPort(String sPort);      //设置串口
serialHelper.setBaudRate(int iBaud);     //设置波特率
serialHelper.setStopBits(int stopBits);  //设置停止位
serialHelper.setDataBits(int dataBits);  //设置数据位
serialHelper.setParity(int parity);      //设置校验位
serialHelper.setFlowCon(int flowcon);    //设置流控

发送数据

serialHelper.send(byte[] bOutArray); // 发送byte[]
serialHelper.sendHex(String sHex);  // 发送Hex
serialHelper.sendTxt(String sTxt);  // 发送ASCII

关闭串口

serialHelper.close(); 

效果图 

 四、参考文章

Android串口使用2之使用Google官方库android-serialport-api_android-serialport-api使用_Steven Jon的博客-CSDN博客

mirrors / xmaihh / Android-Serialport · GitCode 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/326585
推荐阅读
相关标签
  

闽ICP备14008679号