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

树莓派Node-RED中通过I2C或MQTT访问BMP180传感器的方法问询

在Node-RED中通过MQTT读取BMP180温压传感器的完整方案

刚好你已经在树莓派上跑了Node-RED和Mosquitto,那咱们直接从配置MQTT连接开始,一步步实现传感器数据的采集与发布,优先用你想要的MQTT方式~

第一步:配置Node-RED的MQTT连接

因为Mosquitto是本地运行的,配置超级简单:

  • 打开Node-RED编辑器,拖一个mqtt out节点到画布,双击它。
  • 点击「服务器」右侧的铅笔图标,新建一个MQTT Broker配置:
    • 服务器填localhost,端口保持默认的1883,其他参数不用改,给这个配置起个名字比如「本地Mosquitto」,点击完成。
  • 主题可以自己定义,推荐用分层格式方便管理,比如sensor/bmp180/data(用来发温压合并的JSON数据),或者分开成sensor/bmp180/temperature和sensor/bmp180/pressure。

方案一:用Python脚本+MQTT(新手友好,无需额外复杂节点)

这个方法不用纠结I2C指令的细节,用Python脚本读取传感器数据,再通过Node-RED转发到MQTT,步骤如下:

  1. 写一个BMP180读取脚本
    在树莓派上新建一个脚本文件,比如/home/pi/scripts/bmp180_read.py,内容如下:

    import smbus
    import time
    
    # BMP180的I2C地址(用`i2cdetect -y 1`可确认,一般是0x77或0x76)
    address = 0x77
    
    # 传感器寄存器定义
    REG_CALIB = 0xAA
    REG_CONTROL = 0xF4
    REG_DATA = 0xF6
    
    # 读取校准数据(BMP180需要校准才能计算准确值)
    bus = smbus.SMBus(1)
    calib = bus.read_i2c_block_data(address, REG_CALIB, 22)
    AC1 = calib[0] << 8 | calib[1]
    AC2 = calib[2] << 8 | calib[3]
    AC3 = calib[4] << 8 | calib[5]
    AC4 = calib[6] << 8 | calib[7]
    AC5 = calib[8] << 8 | calib[9]
    AC6 = calib[10] << 8 | calib[11]
    B1 = calib[12] << 8 | calib[13]
    B2 = calib[14] << 8 | calib[15]
    MB = calib[16] << 8 | calib[17]
    MC = calib[18] << 8 | calib[19]
    MD = calib[20] << 8 | calib[21]
    
    # 读取温度
    bus.write_byte_data(address, REG_CONTROL, 0x2E)
    time.sleep(0.005)  # 等待转换完成
    data = bus.read_i2c_block_data(address, REG_DATA, 2)
    UT = data[0] << 8 | data[1]
    X1 = (UT - AC6) * AC5 / 32768
    X2 = MC * 2048 / (X1 + MD)
    B5 = X1 + X2
    temperature = (B5 + 8) / 160
    
    # 读取气压(精度模式0,最快)
    bus.write_byte_data(address, REG_CONTROL, 0x34)
    time.sleep(0.005)
    data = bus.read_i2c_block_data(address, REG_DATA, 3)
    UP = (data[0] << 16 | data[1] << 8 | data[2]) >> (8 - 0)
    B6 = B5 - 4000
    X1 = (B2 * (B6 * B6 / 4096)) / 2048
    X2 = AC2 * B6 / 2048
    X3 = X1 + X2
    B3 = ((AC1 * 4 + X3) << 0 + 2) / 4
    X1 = AC3 * B6 / 8192
    X2 = (B1 * (B6 * B6 / 4096)) / 65536
    X3 = ((X1 + X2) + 2) / 4
    B4 = AC4 * (X3 + 32768) / 32768
    B7 = (UP - B3) * (50000 >> 0)
    if B7 < 0x80000000:
        pressure = (B7 * 2) / B4
    else:
        pressure = (B7 / B4) * 2
    X1 = (pressure / 256) * (pressure / 256)
    X1 = (X1 * 3038) / 65536
    X2 = (-7357 * pressure) / 65536
    pressure = pressure + (X1 + X2 + 3791) / 16
    
    # 输出JSON格式数据
    print(f'{{"temperature": {temperature:.2f}, "pressure": {pressure:.2f}}}')
    

    记得先安装smbus库:sudo apt install python3-smbus

  2. 在Node-RED中搭建流

    • 拖一个inject节点:设置为「重复触发」,间隔比如5秒,用来定时读取传感器。
    • 拖一个exec节点:配置命令为python3 /home/pi/scripts/bmp180_read.py,其他默认。
    • 拖一个function节点:把脚本输出的字符串转成JSON对象,代码如下:
      msg.payload = JSON.parse(msg.payload);
      return msg;
      
    • 拖之前配置好的mqtt out节点:主题设为sensor/bmp180/data,格式选「JSON」。
    • 连接顺序:inject → exec → function → mqtt out
  3. 验证MQTT消息
    在树莓派终端执行命令:mosquitto_sub -h localhost -t sensor/bmp180/data,就能看到每秒(或你设置的间隔)输出的温压数据了。

方案二:用已安装的I2C节点+MQTT

如果你想直接用Node-RED的I2C节点,需要手动处理传感器的指令序列,步骤如下:

  1. 先读取校准数据(只需要一次)

    • 拖一个inject节点(手动触发一次),i2c read节点(地址0x77,寄存器0xAA,长度22),function节点(保存校准数据到上下文)。
    • function节点代码:
      // 解析校准数据
      const calib = msg.payload;
      context.set('AC1', calib[0] << 8 | calib[1]);
      context.set('AC2', calib[2] << 8 | calib[3]);
      context.set('AC3', calib[4] << 8 | calib[5]);
      context.set('AC4', calib[6] << 8 | calib[7]);
      context.set('AC5', calib[8] << 8 | calib[9]);
      context.set('AC6', calib[10] << 8 | calib[11]);
      context.set('B1', calib[12] << 8 | calib[13]);
      context.set('B2', calib[14] << 8 | calib[15]);
      context.set('MB', calib[16] << 8 | calib[17]);
      context.set('MC', calib[18] << 8 | calib[19]);
      context.set('MD', calib[20] << 8 | calib[21]);
      return null; // 不需要继续传递消息
      
    • 触发一次这个流,把校准数据存在Node-RED的上下文中。
  2. 定时读取温压数据

    • 拖inject节点(每5秒触发),i2c write节点(地址0x77,数据[0xF4, 0x2E],触发温度转换),delay节点(延迟5ms),i2c read节点(地址0x77,寄存器0xF6,长度2),function节点(计算温度),mqtt out节点(主题sensor/bmp180/temperature)。
    • 温度计算的function节点代码:
      const UT = msg.payload[0] << 8 | msg.payload[1];
      const AC6 = context.get('AC6');
      const AC5 = context.get('AC5');
      const MC = context.get('MC');
      const MD = context.get('MD');
      
      const X1 = (UT - AC6) * AC5 / 32768;
      const X2 = MC * 2048 / (X1 + MD);
      const B5 = X1 + X2;
      const temperature = (B5 + 8) / 160;
      
      msg.payload = temperature.toFixed(2);
      return msg;
      
    • 同理,复制这个流修改成读取气压:把i2c write的数据改成[0xF4, 0x34],i2c read长度改成3,然后用对应的气压计算公式处理数据,发布到sensor/bmp180/pressure主题。

主题配置小建议

MQTT主题采用分层结构会让后续管理更方便,比如:

  • sensor/bmp180/temperature:单独发布温度
  • sensor/bmp180/pressure:单独发布气压
  • sensor/bmp180/data:发布合并的JSON数据

这样不管是后续用MQTT客户端订阅,还是在Node-RED里处理,都能灵活选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:48:05