3 changed files with 469 additions and 12 deletions
-
195485通信超时问题排查指南.md
-
136app/src/main/java/com/ouxuan/oxface/debug/Ox485DebugHelper.java
-
150app/src/main/java/com/ouxuan/oxface/device/Ox485.java
@ -0,0 +1,195 @@ |
|||
# 485通信超时问题排查指南 |
|||
|
|||
## 问题描述 |
|||
|
|||
根据您提供的日志,485模块在查询摄像头人数时出现超时问题: |
|||
|
|||
``` |
|||
10:34:13.824 Ox485 D 发送485人数查询命令: 0F030001000294E5 |
|||
10:34:23.825 Ox485 E 485人数查询超时 |
|||
``` |
|||
|
|||
## 问题分析 |
|||
|
|||
1. **命令发送成功**:日志显示命令 `0F030001000294E5` 已成功发送 |
|||
2. **无响应数据**:在10秒超时时间内,没有收到任何响应数据 |
|||
3. **可能原因**: |
|||
- 485设备未正常工作或断电 |
|||
- 485通信线路故障 |
|||
- 设备地址配置错误 |
|||
- 波特率不匹配 |
|||
- 串口权限或占用问题 |
|||
|
|||
## 代码修改内容 |
|||
|
|||
### 1. 增强的发送命令方法 |
|||
|
|||
- 添加了串口状态检查 |
|||
- 增加了详细的发送日志 |
|||
- 验证命令发送结果 |
|||
|
|||
### 2. 改进的连接建立方法 |
|||
|
|||
- 增加了设备文件存在性检查 |
|||
- 添加了文件权限检查 |
|||
- 验证串口打开状态 |
|||
|
|||
### 3. 详细的超时处理 |
|||
|
|||
- 记录准确的等待时间 |
|||
- 输出详细的状态信息 |
|||
- 提供故障诊断信息 |
|||
|
|||
### 4. 新增诊断功能 |
|||
|
|||
- `diagnose485Connection()` 方法:全面检查485连接状态 |
|||
- `Ox485DebugHelper` 类:提供完整的诊断工具 |
|||
|
|||
## 使用调试工具 |
|||
|
|||
### 在代码中调用诊断方法 |
|||
|
|||
```java |
|||
// 方法1:完整诊断(推荐) |
|||
Ox485DebugHelper.runFullDiagnosis(); |
|||
|
|||
// 方法2:快速测试 |
|||
Ox485DebugHelper.quickTest(); |
|||
|
|||
// 方法3:单独诊断连接 |
|||
Ox485.getInstance().diagnose485Connection(); |
|||
``` |
|||
|
|||
### 查看诊断结果 |
|||
|
|||
诊断工具会检查以下内容: |
|||
|
|||
1. **串口设备文件** |
|||
- 文件是否存在:`/dev/ttyS6` |
|||
- 文件权限:可读/可写权限 |
|||
|
|||
2. **串口管理器状态** |
|||
- 串口是否打开 |
|||
- 内部连接状态 |
|||
- 连接中状态 |
|||
|
|||
3. **485配置** |
|||
- 485模式开关状态 |
|||
- 串口路径、波特率等参数 |
|||
- 查询命令格式 |
|||
|
|||
4. **连接历史** |
|||
- 最后成功通信时间 |
|||
- 重试次数统计 |
|||
|
|||
5. **实际通信测试** |
|||
- 尝试发送命令并等待响应 |
|||
|
|||
## 排查步骤 |
|||
|
|||
### 第一步:运行诊断工具 |
|||
|
|||
在您的Activity中添加以下代码: |
|||
|
|||
```java |
|||
// 在onCreate或其他适当位置调用 |
|||
Ox485DebugHelper.runFullDiagnosis(); |
|||
``` |
|||
|
|||
### 第二步:检查硬件连接 |
|||
|
|||
1. 确认485设备电源是否正常 |
|||
2. 检查485通信线路连接 |
|||
3. 验证设备地址设置(当前使用0F) |
|||
4. 确认设备波特率设置(当前使用9600) |
|||
|
|||
### 第三步:检查系统权限 |
|||
|
|||
```bash |
|||
# 检查串口设备文件 |
|||
ls -l /dev/ttyS6 |
|||
|
|||
# 检查权限 |
|||
chmod 666 /dev/ttyS6 # 如果权限不足 |
|||
``` |
|||
|
|||
### 第四步:测试通信协议 |
|||
|
|||
当前使用的485命令: |
|||
- **命令**:`0F030001000294E5` |
|||
- **含义**:查询地址为0F的设备的人数数据 |
|||
- **期望响应**:9字节数据,格式为 `[15, 3, 4, 0, 人数, *, *, *, *]` |
|||
|
|||
### 第五步:逐步排查 |
|||
|
|||
1. **确认设备响应** |
|||
```java |
|||
// 发送简单的测试命令 |
|||
Ox485.getInstance().send485HexCommand("0F030001000294E5"); |
|||
``` |
|||
|
|||
2. **监控所有接收数据** |
|||
- 查看日志中是否有任何 `Ox485接收到数据` 的记录 |
|||
- 即使是错误格式的数据也会被记录 |
|||
|
|||
3. **尝试不同的设备地址** |
|||
```java |
|||
// 如果0F不响应,尝试其他地址 |
|||
Ox485.getInstance().send485HexCommand("01030001000295F4"); // 地址01 |
|||
``` |
|||
|
|||
## 常见问题解决方案 |
|||
|
|||
### 问题1:串口设备文件不存在 |
|||
|
|||
**解决方案**: |
|||
- 检查硬件连接 |
|||
- 确认设备树配置 |
|||
- 重启设备 |
|||
|
|||
### 问题2:权限不足 |
|||
|
|||
**解决方案**: |
|||
```bash |
|||
chmod 666 /dev/ttyS6 |
|||
chown system:system /dev/ttyS6 |
|||
``` |
|||
|
|||
### 问题3:设备不响应 |
|||
|
|||
**解决方案**: |
|||
- 检查485设备电源 |
|||
- 验证设备地址配置 |
|||
- 使用万用表检查485信号 |
|||
- 尝试不同的波特率 |
|||
|
|||
### 问题4:数据格式错误 |
|||
|
|||
**解决方案**: |
|||
- 确认设备协议文档 |
|||
- 检查命令格式 |
|||
- 验证校验码计算 |
|||
|
|||
## 预期的正常日志 |
|||
|
|||
修改后,正常的485通信日志应该类似: |
|||
|
|||
``` |
|||
Ox485 D 485串口状态检查通过,开始发送命令 |
|||
Ox485 D 准备发送485命令: 0F030001000294E5, 转换后字节数组: [15, 3, 0, 1, 0, 2, -108, -27] |
|||
Ox485 D 485命令发送结果: true |
|||
Ox485 D Ox485发送数据成功: 0f030001000294e5, 数据长度: 8 |
|||
Ox485 D Ox485接收到数据: 0f03040000xxxx, 字节数组: [15, 3, 4, 0, X, ...], 数据长度: 9 |
|||
Ox485 D 485获取人数成功: X |
|||
``` |
|||
|
|||
## 联系支持 |
|||
|
|||
如果按照上述步骤仍无法解决问题,请提供: |
|||
|
|||
1. 完整的诊断日志 |
|||
2. 硬件连接图 |
|||
3. 485设备型号和协议文档 |
|||
4. 系统版本信息 |
|||
|
|||
修改后的代码增加了大量诊断信息,应该能帮助您快速定位485通信超时的根本原因。 |
@ -0,0 +1,136 @@ |
|||
package com.ouxuan.oxface.debug; |
|||
|
|||
import com.ouxuan.oxface.device.Ox485; |
|||
import com.ouxuan.oxface.utils.LogManager; |
|||
|
|||
/** |
|||
* Ox485调试助手 |
|||
* 用于排查485通信问题 |
|||
* |
|||
* @author AI Assistant |
|||
* @version 1.0 |
|||
* @date 2024/09/22 |
|||
*/ |
|||
public class Ox485DebugHelper { |
|||
|
|||
private static final String TAG = "Ox485DebugHelper"; |
|||
|
|||
/** |
|||
* 执行完整的485诊断流程 |
|||
*/ |
|||
public static void runFullDiagnosis() { |
|||
LogManager.logInfo(TAG, "========== 开始485完整诊断流程 =========="); |
|||
|
|||
Ox485 ox485 = Ox485.getInstance(); |
|||
|
|||
// 1. 基础状态检查 |
|||
LogManager.logInfo(TAG, "步骤1: 基础状态检查"); |
|||
String status = ox485.get485Status(); |
|||
LogManager.logInfo(TAG, "当前状态: " + status); |
|||
|
|||
// 2. 连接诊断 |
|||
LogManager.logInfo(TAG, "步骤2: 连接诊断"); |
|||
ox485.diagnose485Connection(); |
|||
|
|||
// 3. 等待3秒后进行测试 |
|||
LogManager.logInfo(TAG, "步骤3: 等待3秒后进行通信测试"); |
|||
new android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(() -> { |
|||
testCommunication(); |
|||
}, 3000); |
|||
|
|||
LogManager.logInfo(TAG, "========== 485完整诊断流程结束 =========="); |
|||
} |
|||
|
|||
/** |
|||
* 测试485通信 |
|||
*/ |
|||
private static void testCommunication() { |
|||
LogManager.logInfo(TAG, "========== 开始485通信测试 =========="); |
|||
|
|||
Ox485 ox485 = Ox485.getInstance(); |
|||
|
|||
ox485.sendHex485ForPeopleNum(new Ox485.PeopleNumCallback() { |
|||
@Override |
|||
public void onSuccess(int peopleNum) { |
|||
LogManager.logInfo(TAG, "✓ 485通信测试成功 - 获取到人数: " + peopleNum); |
|||
LogManager.logInfo(TAG, "========== 485通信测试完成(成功) =========="); |
|||
} |
|||
|
|||
@Override |
|||
public void onError(String errorMessage) { |
|||
LogManager.logError(TAG, "✗ 485通信测试失败: " + errorMessage); |
|||
|
|||
// 失败时打印详细状态 |
|||
String status = ox485.get485Status(); |
|||
LogManager.logError(TAG, "失败时状态: " + status); |
|||
|
|||
// 建议解决方案 |
|||
printTroubleshootingSuggestions(errorMessage); |
|||
|
|||
LogManager.logInfo(TAG, "========== 485通信测试完成(失败) =========="); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 打印故障排查建议 |
|||
*/ |
|||
private static void printTroubleshootingSuggestions(String errorMessage) { |
|||
LogManager.logInfo(TAG, "========== 故障排查建议 =========="); |
|||
|
|||
if (errorMessage.contains("超时")) { |
|||
LogManager.logInfo(TAG, "超时问题排查建议:"); |
|||
LogManager.logInfo(TAG, "1. 检查485设备是否正常工作"); |
|||
LogManager.logInfo(TAG, "2. 检查485设备连接线路"); |
|||
LogManager.logInfo(TAG, "3. 确认设备地址是否正确(当前命令中设备地址为0F)"); |
|||
LogManager.logInfo(TAG, "4. 检查485设备波特率是否匹配(当前: 9600)"); |
|||
LogManager.logInfo(TAG, "5. 使用万用表或示波器检查485信号"); |
|||
} else if (errorMessage.contains("串口")) { |
|||
LogManager.logInfo(TAG, "串口问题排查建议:"); |
|||
LogManager.logInfo(TAG, "1. 检查串口设备文件是否存在: /dev/ttyS6"); |
|||
LogManager.logInfo(TAG, "2. 检查应用权限是否足够"); |
|||
LogManager.logInfo(TAG, "3. 确认串口未被其他程序占用"); |
|||
LogManager.logInfo(TAG, "4. 重启设备后重试"); |
|||
} else if (errorMessage.contains("解析")) { |
|||
LogManager.logInfo(TAG, "数据解析问题排查建议:"); |
|||
LogManager.logInfo(TAG, "1. 检查接收到的数据格式"); |
|||
LogManager.logInfo(TAG, "2. 确认485设备返回的数据协议"); |
|||
LogManager.logInfo(TAG, "3. 验证数据长度和校验码"); |
|||
} else { |
|||
LogManager.logInfo(TAG, "通用排查建议:"); |
|||
LogManager.logInfo(TAG, "1. 重启应用程序"); |
|||
LogManager.logInfo(TAG, "2. 检查硬件连接"); |
|||
LogManager.logInfo(TAG, "3. 联系技术支持"); |
|||
} |
|||
|
|||
LogManager.logInfo(TAG, "========== 故障排查建议结束 =========="); |
|||
} |
|||
|
|||
/** |
|||
* 快速测试485连接 |
|||
*/ |
|||
public static void quickTest() { |
|||
LogManager.logInfo(TAG, "========== 485快速测试 =========="); |
|||
|
|||
Ox485 ox485 = Ox485.getInstance(); |
|||
|
|||
// 如果485模式未开启,则开启 |
|||
if (!ox485.isGateCamera485OxOn()) { |
|||
LogManager.logInfo(TAG, "485模式未开启,正在开启..."); |
|||
ox485.setGateCamera485OxOn(true); |
|||
} |
|||
|
|||
// 执行一次查询 |
|||
ox485.sendHex485ForPeopleNum(new Ox485.PeopleNumCallback() { |
|||
@Override |
|||
public void onSuccess(int peopleNum) { |
|||
LogManager.logInfo(TAG, "✓ 快速测试成功 - 人数: " + peopleNum); |
|||
} |
|||
|
|||
@Override |
|||
public void onError(String errorMessage) { |
|||
LogManager.logError(TAG, "✗ 快速测试失败: " + errorMessage); |
|||
} |
|||
}); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue