Raspberry Pi BME280 sensor reader with optional MQTT publishing
npm install rpi-bme280-cliNode.js CLI for reading a Bosch BME280 sensor on a Raspberry Pi (I2C) and optionally publishing readings to an MQTT broker.
- Reads: pressure, humidity, temperature
- Output: human-readable (default) or JSON
- Modes: periodic polling (default: every 30s) or --once
- MQTT: publish each reading to subtopics (default) or publish a single JSON payload when --output json
This project currently uses the bme280-sensor npm package for the actual I2C sensor access.
If you want to read from a BME280 in your own Node.js app, you should import and use bme280-sensor directly. This package is intended to be a CLI utility / long-running daemon process.
Typical Raspberry Pi ↔ BME280 wiring (I2C):
- 3.3V → VIN (or 3V3)
- GND → GND
- SDA (GPIO2 / pin 3) → SDA
- SCL (GPIO3 / pin 5) → SCL
Note: Most BME280 breakout boards are 3.3V devices. Do not power with 5V unless your breakout explicitly supports it.
1) Enable I2C
- sudo raspi-config
- Interface Options → I2C → Enable
2) Install I2C tools (optional but recommended)
- sudo apt-get update
- sudo apt-get install -y i2c-tools
Then you can confirm the sensor is visible:
First, see which I2C buses exist:
- ls -l /dev/i2c-*
Common cases:
- /dev/i2c-1 exists (most Raspberry Pi setups)
- only /dev/i2c-0 exists (some older images / configurations)
Then scan the bus you have:
- sudo i2cdetect -y 1
Or, if you only have /dev/i2c-0:
- sudo i2cdetect -y 0
Expected result: you should see a device at address 0x76 or 0x77 (most commonly 0x76). Example (device at 0x76):
```
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --
3) Ensure your user can access /dev/i2c-*
On Raspberry Pi OS, adding your user to the i2c group is usually sufficient:
- sudo usermod -aG i2c $USER
- log out / reboot
If you run under a process manager (pm2 as a system service), ensure the service user has the same access.
`bash`
sudo npm install -g rpi-bme280-cli
After that, the bme280 command should be available.
`bash`
git clone https://github.com/cr0ybot/rpi-bme280-cli
cd rpi-bme280-cli
npm install
Install the CLI command globally from the local folder:
`bash`
sudo npm install -g .
After that, the bme280 command should be available.
You can run the CLI directly from this repo without installing it globally.
Without cloning (via npx):
`bash`
npx --yes --package rpi-bme280-cli bme280 --once
From the project folder:
`bash`
node bin/bme280.js --once
You can also use the npm script (args go after --):
`bash`
npm start -- --once
`bash`
bme280 --once
If you haven’t installed the CLI globally, use the “Run without global install” section above.
`bash`
bme280 --interval 10
`bash`
bme280 --output json
Defaults are °C and hPa.
`bash`
bme280 --temp-unit F --pressure-unit inHg
To reduce noise/precision (useful for dashboards/alerts), you can round and/or smooth values.
Round values to 1 decimal:
`bash`
bme280 --round 1
Apply exponential smoothing (EMA) with alpha 0.2:
`bash`
bme280 --smooth 0.2
Default I2C bus is auto-detected:
- uses bus 1 when /dev/i2c-1 exists0
- otherwise uses bus when /dev/i2c-0 exists
Default address is 0x76.
`bash`
bme280 --address 0x77
To force a specific bus:
`bash`
bme280 --i2c-bus 0
Use --mqtt with a single MQTT URI that includes broker URI, topic (in the URI path), and optionally credentials (user:pass@).
Examples:
1) Publish to rpi/BME280 on local broker without auth:
`bash`
bme280 --mqtt 'mqtt://localhost:1883'
2) Publish to sensors/bme280 on remote broker with auth:
`bash`
bme280 --mqtt 'mqtt://user:pass@localhost:1883/sensors/bme280'
Default base topic is rpi/BME280.
- Default output (--output human): publishes scalar values to subtopicsrpi/BME280/pressure
- → pressure in configured unit (default: hPa)rpi/BME280/humidity
- → %RHrpi/BME280/temperature
- → temperature in configured unit (default: °C)
- JSON output (--output json): publishes a single JSON object to the base topicrpi/BME280
- → {"timestamp":"...","temperature":...,"temperatureUnit":"C","humidity":...,"humidityUnit":"%","pressure":...,"pressureUnit":"hPa"}
All CLI options can be provided via a config file (YAML or JSON) and loaded with -c.bme280.config.yml
You can name the file anything (a common convention is or bme280.config).
Example:
`bash`
bme280 -c ./rpi-bme280.config.example.yml
Config keys:
- intervalSeconds (number)once
- (boolean)output
- (human or json)mqtt
- (string)temperatureUnit
- (C or F)pressureUnit
- (hPa or inHg)roundDecimals
- (integer 0-6)smoothAlpha
- (number > 0 and <= 1)i2cBusNo
- (number)i2cAddress
- (number or hex string like 0x76)
Precedence: defaults < config file < CLI args.
1) Install pm2
`bash`
sudo npm install -g pm2
2) Start the process
`bash`
pm2 start bme280 --name bme280 -- --config /home/pi/bme280.config.yml
If you did not install the CLI globally, you can also run pm2 with the local path:
`bash`
cd /home/pi/rpi-bme280-cli
pm2 start bin/bme280.js --name bme280 -- --config /home/pi/bme280.config.yml
3) Persist across reboots
`bash`
pm2 save
pm2 startup
Follow the command printed by pm2 startup (it will ask you to run one sudo` command).