树莓派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,步骤如下:
写一个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在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
- 拖一个
验证MQTT消息
在树莓派终端执行命令:mosquitto_sub -h localhost -t sensor/bmp180/data,就能看到每秒(或你设置的间隔)输出的温压数据了。
方案二:用已安装的I2C节点+MQTT
如果你想直接用Node-RED的I2C节点,需要手动处理传感器的指令序列,步骤如下:
先读取校准数据(只需要一次)
- 拖一个
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的上下文中。
- 拖一个
定时读取温压数据
- 拖
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
相关产品推荐
相关产品推荐

