如何将HC-05传输的Arduino三超声波传感器数据分显至Android多TextView
问题
我正在开发一款通过HC-05蓝牙模块连接Arduino与Android的应用,Arduino搭载三个超声波传感器。目前已实现设备连接并能接收传感器数据,但所有传感器的距离信息均显示在同一个TextView中,希望将其分别显示在三个TextView里,不清楚需修改代码的哪些部分。
修改方案
核心思路是给Arduino发送的传感器数据添加唯一标识,让Android端能区分不同传感器的数据,再分别更新对应TextView。
一、Arduino代码修改
优化数据发送格式,用结构化标识区分三个传感器,同时提升传输效率:
int LtriggerPin = 13; int LechoPin = 12; int RtriggerPin = 11; int RechoPin = 10; int CtriggerPin = 9; int CechoPin = 8; void setup() { Serial1.begin(9600); pinMode(LtriggerPin, OUTPUT); pinMode(LechoPin, INPUT); pinMode(RtriggerPin, OUTPUT); pinMode(RechoPin, INPUT); pinMode(CtriggerPin, OUTPUT); pinMode(CechoPin, INPUT); } void loop(){ sensor(); delay(500); // 统一控制采样间隔,避免重复延迟 } void sensor() { int durationL, distanceL; int durationR, distanceR; int durationC, distanceC; // 左侧传感器采样 digitalWrite(LtriggerPin, HIGH); delayMicroseconds(10); // 更精确的触发脉冲延迟 digitalWrite(LtriggerPin, LOW); durationL = pulseIn(LechoPin, HIGH); distanceL = (durationL/2) / 29.1; // 右侧传感器采样 digitalWrite(RtriggerPin, HIGH); delayMicroseconds(10); digitalWrite(RtriggerPin, LOW); durationR = pulseIn(RechoPin, HIGH); distanceR = (durationR/2) / 29.1; // 中间传感器采样 digitalWrite(CtriggerPin, HIGH); delayMicroseconds(10); digitalWrite(CtriggerPin, LOW); durationC = pulseIn(CechoPin, HIGH); distanceC = (durationC/2) / 29.1; // 结构化发送:用L/R/C标识传感器,|分隔数据,换行作为结束标记 Serial1.print("L:"); Serial1.print(distanceL); Serial1.print("|R:"); Serial1.print(distanceR); Serial1.print("|C:"); Serial1.println(distanceC); }
修改要点:
- 替换原有的自然语言描述,改用
L:/R:/C:作为传感器唯一标识 - 用
|分隔多个传感器数据,换行符\n作为完整数据的结束标记 - 统一采样延迟到
loop中,避免每个传感器单独延迟导致的传输卡顿 - 把
delay(10)改为delayMicroseconds(10),符合超声波传感器的触发要求
二、Android代码修改
1. 蓝牙线程代码优化
调整数据读取逻辑,确保获取完整的一行传感器数据:
@Override public void run() { byte[] buffer = new byte[1024]; int bytes; StringBuilder sb = new StringBuilder(); // 拼接完整数据的缓存 while (true) { try { bytes = mmInStream.read(buffer); if (bytes > 0) { String temp = new String(buffer, 0, bytes, StandardCharsets.UTF_8); sb.append(temp); // 检测到换行符时,说明已获取完整一行数据 if (temp.contains("\n")) { String fullData = sb.toString().trim(); sb.setLength(0); // 清空缓存 handler.obtainMessage(MainActivity.MESSAGE_READ, fullData) .sendToTarget(); } } } catch (IOException e) { e.printStackTrace(); break; } } } // write、cancel方法保持不变
修改要点:
- 使用
StringBuilder拼接分包读取的数据,避免数据截断 - 以Arduino发送的换行符作为完整数据的判断标记
2. Handler代码修改
解析结构化数据,分别更新对应TextView:
// 提前在Activity中初始化三个TextView实例:tvLeft、tvRight、tvCenter handler = new Handler(Looper.getMainLooper()){ @Override public void handleMessage(Message msg){ if(msg.what == MESSAGE_READ){ String fullData = (String) msg.obj; // 按|分割数据 String[] sensorData = fullData.split("\\|"); for(String data : sensorData){ if(data.startsWith("L:")){ tvLeft.setText(data.substring(2) + " cm"); } else if(data.startsWith("R:")){ tvRight.setText(data.substring(2) + " cm"); } else if(data.startsWith("C:")){ tvCenter.setText(data.substring(2) + " cm"); } } } if(msg.what == CONNECTING_STATUS){ if(msg.arg1 == 1) Tv3.setText(getString(R.string.BTConnected) + msg.obj); else Tv3.setText(getString(R.string.BTconnFail)); } } };
修改要点:
- 按
|分割接收到的完整数据,逐个判断传感器标识 - 提取距离值并添加单位后,更新对应的TextView
- 确保已在Activity中通过
findViewById初始化三个TextView实例
内容的提问来源于stack exchange,提问作者Jezdi
相关产品推荐
相关产品推荐

