John L Errington MSc

John Errington's Experiments with an Arduino

Using I2C and SPI devices: BMP280 & BME280: NodeMCU Weather Station


I looked for an inexpensive sensor to learn about I2C and SPI; The BME280 looked interesting so I ordered a couple.

The BMP280 (and BME280) devices are tiny so I bought them ready mounted with all the necessary stuff to implement an I2C or SPI connection. However the connections arent easy to work out, because of the way they are labelled.

I first tested them on my Arduino Uno - without success - neither as I2C nor SPI.

When I ran the BMEtest sketch I kept getting "Could not find a valid BME280 sensor, check wiring, address, sensor ID!"
Turned out my "Chinese" BME280 was actually a BMP280. So here is how I worked out how to get readings.



Before starting you need to install the Wire libary (if its not already installed) which supports I2C; the Adafruit Unified Sensor library, and the libraries for the devices(s) you will be using - eg BME280, BMP280. So e.g. the Adafruit BMP280 library; using the Arduino IDE's library manager.



bmp280 boardOn the UNO I connected as follows (for I2C)

  • Vcc - 5V;
  • Gnd - 0V;
  • SCL - A5;
  • SDA - A4;

For I2C the SDO pin controls the address; and MUST be pulled either to 0V 0r Vcc (via a pull-up resistor). On some boards you may also need to pull up CSB.

For SPI the default connections (you can change these by using "Software SPI") are

  • Digital Pin 13 (SPI/SCK) to SCK (Serial Clock)
  • Digital Pin 12 (SPI/MISO) to SDO (Serial Data Out)
  • Digital Pin 11 (SPI/MOSI) to SDI (Serial Data In) (labelled SDA)
  • Digital Pin 10 (SPI/SS) to CS (Chip Select) (labelled CSB)


Testing I2C

Before doing anything else (having connected the board to your Arduino of course) run the Wire- I2C Scanner sketch. That will tell you the address of the board you have connected. For a BMP280 its 0X77 (with SDO = Vcc) or 0X76 (SDO = 0V).

If all is well load the Adafruit BMP280test sketch from the examples and run it. You will likely need SDO pulled high.


Testing SPI

I've not found a similar sketch to test the SPI connection so I jump straight in with the Adafruit BMP280test sketch.
I've commented out the I2C option, and uncommented the next for "software SPI" but hardware SPI also worked.

Software SPI enables you to use different pins for the SPI interface, where hardware SPI needs you to use the predefined pins.

If you arent using an uno or nano the pin numbers may need to be changed in the defines - see below for the NodeMCU.

#define BMP_SCK (13)
#define BMP_MISO (12)
#define BMP_MOSI (11)
#define BMP_CS (10)
//Adafruit_BMP280 bmp; // I2C
//Adafruit_BMP280 bmp(BMP_CS); // hardware SPI

Here is the output on the serial monitor:

Temperature = 22.66 *C
Pressure = 98345.35 Pa
Approx altitude = 251.08 m


So - I2C or SPI?

Note - both these interfaces are intended for communicating between devices on the same board.

  • I2C is a two-wire interface, while SPI is 4 wire; (we dont count the power supplies).
  • SPI offers higher speeds, but needs a seperate SS wire to each connected peripheral;
  • I2C is better for connecting a large number of peripherals, as each will have its own 7 bit identifier code


Connecting the BMP280 / BME280 to a NodeMCU

Power supply: On the Node we connect Vcc+ to 3v; 0V to GND

I2C: connect SCL - D1; and SDA to D2.

Having selected the correct board (NodeMCU 1.0) and port (COM5) the Wire - I2C Scanner sketch found the BMP280 board at 0X76. Now we try the "bmp280test" example - making sure we have chosen the I2C option

Adafruit_BMP280 bmp; // I2C

Running the code I got "Could not find a valid BMP280 sensor, check wiring!"

The fix is to give the address of the sensor in setup, like this

if (!bmp.begin(0x76)) {


SPI: I found the BME280 module gave silly readings with I2C; however SPI worked. I chose to use pins D1 - D4

// order connections to match bme module layout: also connect GND - G & VCC - 3V

#define BME_MISO D1 //SDO
#define BME_CS D2 //CSB
#define BME_MOSI D3 //SDA
#define BME_SCK D4 //SCL

and in the code

Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI


Simple weather station

The "weather station" only has 4 components; the node and bme280 module, and a resistor & LED that flashes every 30 seconds - just to show its working. The code is adapted from the reference below, adding sections to record the 3 hour and 24 hour changes in pressure. Pressure is reported in hPa (hectoPascal) where 1 hPa = 1 milliBar. Here you can see the display.

weather station


References and additional information