You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派CM4使用Java Pi4J读取I2C设备寄存器故障排查

问题排查与解决

1. 先理清I2C设备地址和寄存器地址的区别

你当前代码里把device(0x18)设为设备地址,同时读取寄存器0x18,这里大概率混淆了两者的概念。先通过shell命令确认设备的真实I2C地址:

i2cdetect -y 1

扫描结果里的十六进制数值才是设备地址,而0x18是你要读取的寄存器地址。比如如果i2cget -y 1 0x08 0x18能正常返回值,那0x08就是设备地址,0x18是寄存器地址。

2. 修正Pi4J代码的核心问题

关键问题点:未释放总线资源

原始代码没有关闭Pi4J Context,这是导致I2C总线冻结的直接原因——Pi4J占用总线后未释放,其他工具(如i2cget)无法再访问,必须重启设备。同时要修正设备地址配置:

Context context = Pi4J.newAutoContext();
try {
    I2CProvider i2CProvider = context.provider("linuxfs-i2c");
    // device()参数填扫描到的真实设备地址,不是寄存器地址
    I2CConfig i2cConfig = I2C.newConfigBuilder(context)
            .id("owiic-relay") // id是自定义标识,无需和总线名一致,唯一即可
            .bus(1)
            .device(0x08) // 替换为i2cdetect扫描出的设备地址
            .build();
    I2C device = i2CProvider.create(i2cConfig);

    // 读取寄存器0x18的值
    int registerValue = device.readRegister(0x18);
    System.out.println("寄存器0x18的值:" + registerValue);
} finally {
    // 必须释放总线资源,否则会导致总线冻结
    context.shutdown();
}

3. 额外注意事项

  • id字段作用:只是Pi4J内部用于区分设备的标识,随便起个唯一名字就行,和总线名(i2c-1)无关。
  • 提供者选择:优先用linuxfs-i2c,它直接调用Linux内核I2C设备文件,兼容性最好;其他提供者本质逻辑差异不大,核心问题还是资源释放和地址配置。
  • 验证流程:
    • 用i2cdetect确认设备地址
    • 用i2cget验证寄存器读取正常
    • 运行修正后的代码,执行完后再用i2cget测试,确认总线无需重启即可正常使用

内容的提问来源于stack exchange,提问作者Son

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 14:52:52