
BME280 Sensor Library for Proteus V1.1 (I2C + SPI + Arduino)

Hello friends, I hope you all are doing great. Today, I am going to share the new BME280 Sensor Library for Proteus V1.1. The BME280 is Bosch's small environmental sensor: one chip measures the temperature, the humidity and the air pressure, and the purple GY-BME280 board has made it a favourite for Arduino weather stations. With this BME280 Sensor Library for Proteus, you set the weather with sliders or one-click presets, and your Arduino reads it over I2C (or SPI) with the same Adafruit BME280 library you use on real hardware.
Version 1.1 replaces the first version of this post. You now get two devices: BME280 Simple, with a weather panel on the schematic, and BME280 Advance, with a pop-up weather station and four measured sensor test tools. The model now follows the data sheet's timing, oversampling and IIR filter, and the new BME280 Arduino Proteus demo runs on two Arduino UNOs with a weather alert LED, shown in the compact Simple interface of our TEP Serial Monitor. Have you read version 1.0? Then jump to "What's New" below.
NOTICE: This library is very special to our team. Our BME280 model has the chip's registers, its trimming bytes, the data sheet's measurement timing and its IIR filter, and it speaks I2C and SPI to the unmodified Adafruit library. It took our team a lot of hard work, many test runs and many design changes. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the BME280 Library board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the BME280 Sensor Library for Proteus:
What is the BME280 Sensor?
The BME280 is a combined temperature, humidity and pressure sensor made by Bosch Sensortec. Besides its three sensing elements, every chip stores its own factory trimming (calibration) values. Your Arduino reads raw numbers and turns them into degrees, percent and hectopascals with the compensation formulas of the data sheet; the Adafruit library does that for you. The chip talks over I2C (two wires) or SPI (four wires, or three).
The most common board is the purple GY-BME280: the square metal BME280 with its tiny vent hole, four "103" resistors, two capacitors, a mounting hole and a 6-pin header. One small board replaces three sensors, so it turns up in weather stations, altimeters and room-climate loggers.
The BME280 at a Glance
| Feature | Value |
|---|---|
| Measures | Temperature, relative humidity and air pressure (our sliders: -40 to 85 C, 0 to 100 %, 300 to 1100 hPa) |
| Interfaces | I2C at 0x76 (SDO LOW) or 0x77 (SDO HIGH); SPI 4-wire (modes 00 and 11) or 3-wire, chosen by CSB |
| Chip ID | 0x60 in register D0 (a BMP280, without humidity, answers 0x58) |
| Modes | Sleep, forced (one measurement, then sleep) and normal (measure, standby, repeat) |
| Oversampling | Skip, x1, x2, x4, x8 or x16, set separately for T, P and H |
| Measurement time | Typical 1 + 2T + (2P + 0.5) + (2H + 0.5) ms: 8 ms at x1, 98 ms at x16 (maximum 9.3 / 112.8 ms) |
| Standby (normal mode) | 0.5, 10, 20, 62.5, 125, 250, 500 or 1000 ms |
| IIR filter | Off, 2, 4, 8 or 16, on temperature and pressure (not humidity) |
| Supply | A 3.3 V chip; the purple GY-BME280 has no regulator, so 3.3 V only |
BME280 Terms You Will See in This Article
| Term | Meaning |
|---|---|
| hPa | Hectopascal, 100 Pa; the standard sea-level pressure is 1013.25 hPa |
| Relative humidity | The water vapour in the air, in % of the most it can hold at that temperature |
| Dew point | The temperature at which that air would start to form dew |
| Oversampling (OSR) | The chip takes 1 to 16 samples per value and averages them; more samples take longer |
| t_measure | How long one measurement of T, P and H takes; the status register's "measuring" bit is set meanwhile |
| Standby, period, ODR | The rest between two measurements in normal mode; t_measure + standby is the period, and 1 / period the output data rate |
| IIR filter | A smoothing filter inside the chip: a sudden change creeps in over several measurements |
| Trimming (calibration) bytes | The 32 factory bytes of each chip that the compensation formulas need |
| Sea-level pressure | The reference pressure p0 of the altitude formula (1013.25 hPa by default) |
| SDO, CSB | SDO sets the I2C address (0x76 or 0x77); CSB LOW selects SPI |
How the BME280 Measures: Modes, Oversampling and the IIR Filter
Sleep, Forced and Normal Mode
After power-up, the BME280 needs 2 ms to start, then it sleeps. In sleep mode it measures nothing, and the data registers keep the last values. Forced mode takes one measurement and goes back to sleep, so your sketch asks for every one with takeForcedMeasurement(). In normal mode, the chip measures by itself, rests for the standby time and measures again.
The demo uses normal mode, x1 oversampling and a 125 ms standby, like v1.0. One measurement takes 8 ms, so a new one is ready every 133 ms (7.52 Hz). The sketch prints one line a second, so it reads about one measurement in seven.
Oversampling and the Measurement Time
Oversampling means the chip takes 1, 2, 4, 8 or 16 samples of a value and averages them, which lowers the noise of a real chip. Every sample costs time. The BME280 data sheet gives the typical time, with T, P and H the three oversampling factors (a skipped value adds nothing):
t_measure = 1 + 2 T + (2 P + 0.5) + (2 H + 0.5) ms
At x1, that is 1 + 2 + 2.5 + 2.5 = 8 ms; at x16, 1 + 32 + 32.5 + 32.5 = 98 ms, and with the 125 ms standby, a measurement comes every 223 ms (4.48 Hz). Version 1.0 used the data sheet's maximum time, 9.3 ms at x1; v1.1 runs the typical time. The simulation has no noise, so a higher oversampling makes the readings slower here, not better.
The IIR Filter: Smooth Readings with a Delay
A real sensor sees short pressure spikes, for example when a door slams. The BME280's IIR filter smooths them: with coefficient 16, every new measurement moves the output only a sixteenth of the way to the new value. The data sheet says filter 16 reaches 75 % of a step after 22 measurements, and our model does exactly that. The filter works on the temperature and the pressure only; the humidity has no filter on the real chip either. The price is a delay, which the Step response and Altitude tools below measure.
Trimming Bytes and Compensation
No two real chips are identical, so Bosch stores 32 trimming bytes in every BME280 (registers 88 to 9F, A1 and E1 to E7) for the compensation formulas. That is why Adafruit's begin() soft-resets the chip (B6 to register E0), checks the chip ID 0x60 and reads all 32 bytes. Our model holds one fixed set, which the formulas turn back into exactly the values on your sliders.
Altitude and Dew Point
The air pressure falls as you climb, so the BME280 can estimate the altitude with the Adafruit formula, where p0 is the sea-level pressure:
Altitude = 44330 x (1 - (p / p0)^0.1903) m
With p0 = 1013.25 hPa, 795 hPa gives 2000 m, our MOUNTAIN preset, and one count of the pressure reading is about 1.4 cm. The weather moves the pressure too, so an altimeter must know today's sea-level pressure: that is what SEALEVEL and ALTITUDE in our demo are for. The demo also prints the dew point, from the temperature and the humidity (Magnus formula).
I2C Address and SPI: the SDO and CSB Pins
On I2C, the SDO pin sets the address: LOW gives 0x76, HIGH gives 0x77, so two BME280s can share one bus. The GY-BME280 pulls SDO down (open = 0x76) and CSB up (open = I2C). Pull CSB LOW, and the chip switches to SPI and stays there until it is powered up again, as the data sheet says.
What's New in BME280 Sensor Library for Proteus V1.1
If you used version 1.0, here is what has changed:
- Two devices in
TEPBME280.LIB: BME280 Simple (BME280TEP, the v1.0 device) and BME280 Advance (BME280ADVTEP) with a pop-up window. - A redrawn, live board: the purple GY-BME280 instead of v1.0's blue board, with a thermometer, a humidity drop, a barometer, a glowing vent, a weather window and PWR / I2C LEDs (a TEP addition).
- A weather panel with six presets and a status box with what your Arduino really read; a red X closes it.
- Data sheet timing: the typical measurement time instead of the maximum, the measuring bit, normal mode with the eight standby times, forced and sleep mode, the 2 ms start-up and the soft reset.
- The IIR filter as the data sheet describes it (filter 16: 75 % after 22 measurements).
- The address by the SDO pin as on the real board: open or LOW = 0x76, HIGH = 0x77.
- SPI: 4-wire (modes 00 and 11) and 3-wire, with the CSB latch; v1.0 spoke I2C only.
- A bus log: every I2C or SPI operation decoded, every measurement, and which one each read of your sketch returned.
- A new property, SEALEVEL (1013.25 hPa), for the altitude.
- Four measured test tools on the Advance.
- A two-UNO demo with the TEP Serial Monitor instead of the Virtual Terminal: both addresses, a weather alert LED and 12 commands; every v1.0 output line is kept.
- Lighter package: about 1.49 MB, without the C++ source code and the AVR core archive.
And your old designs keep working. A design with the v1.0 symbol runs with the new model and shows the old ENVIRONMENT CONTROLS panel; here, the v1.0 demo with the v1.1 DLL:
Re-pick the part from the library to get the v1.1 board and the red X.
BME280 Sensor Library for Proteus: Simple vs Advance
Both devices run the same model with the same properties; only the panel differs:
| Feature | Simple | Advance |
|---|---|---|
| Full BME280 model (I2C 0x76 / 0x77, SPI, modes, oversampling, IIR filter, data sheet timing) | ✔ | ✔ |
| Purple GY-BME280 board: thermometer, drop, barometer, vent, weather window, PWR / I2C LEDs | ✔ | ✔ |
| Weather panel on the schematic (three sliders, six presets, status box) | ✔ | ✘ |
| Pop-up window you can move, resize and minimise | ✘ | ✔ |
| Weather page: gauges, presets, altitude, dew point, trend and bus log | ✘ | ✔ |
| Register check, Timing, Step response and Altitude | ✘ | ✔ |
| TEP Dark / Light theme, text size, Help page with Copy diagnostics | ✘ | ✔ |
| Same device name as v1.0 (old designs keep working) | ✔ | ✘ |
Choose Simple to keep the weather beside your circuit, and Advance when your sheet is full or you want hard numbers about your sketch. The demo has one of each.
Download BME280 Sensor Library for Proteus
Click the button below to download BME280-Sensor-Library-for-Proteus-v1.1.zip (about 1.49 MB, without the C++ source code):
BME280 Sensor Library for Proteus V1.1- README.txt: a detailed guide to the files, the wiring, the model, the test tools and real hardware.
- Proteus Library Files:
TEPBME280.LIB(both devices),TEPSERIALMON.LIBand our Arduino UNO libraryArduinoV3TEP.LIB/ArduinoV3TEP.IDX. - Proteus Model Files:
TEPBME280.DLLandTEPSERIALMON.DLL. - Proteus Simulation:
BME280-ArduinoUnoV3.pdsprj,BME280_Demo.hex(both UNOs run it) and copies of both DLLs. - Arduino Code:
BME280_Demo.inoand three unmodified libraries by Adafruit Industries: the Adafruit BME280 Library 2.3.0 with its examples (BSD licence, LICENSE), Adafruit Unified Sensor 1.1.15 (Apache License 2.0, LICENSE.txt) and Adafruit BusIO 1.17.4 (MIT licence, LICENSE).
No Proteus yet? Read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.
How to Install BME280 Sensor Library for Proteus
- Close Proteus and extract the whole zip file.
- Copy the four files from Proteus Library Files into the LIBRARY folder, usually
C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY(on some PCsC:\ProgramData\Labcenter Electronics\Proteus 8 Professional\LIBRARY). - Copy
TEPBME280.DLLandTEPSERIALMON.DLLinto the MODELS folder. - Start Proteus, press P and search for BME280. You get the Simple and the Advance device (category Sensors > Environmental, as in v1.0).
Updating from v1.0? Replace TEPBME280.LIB and TEPBME280.DLL, and delete TEPBME280.IDX if there is one in LIBRARY. The DLL keeps its v1.0 name, so a v1.0 design keeps its v1.0 symbol and runs with the new model, with the v1.0 panel (no new board, no red X); re-pick the part to get the v1.1 board. Tested in Proteus 8.5; Proteus 7 is not supported.
The GY-BME280 Board in Proteus
We drew the sensor as a clean TEP board in the purple of the GY-BME280: the metal BME280 with its vent hole, the four "103" resistors, the two capacitors, the gold mounting hole and the 6-pin header. Here is U1, the Simple device, right after Run, at the start values of its properties:
The thermometer shows 25.0 C, the drop is half full at 50.0 %, and the barometer needle stands at 1013.25 hPa, the standard sea-level pressure, so the weather window reads ALT 0 m. The vent of the chip glows cyan while a measurement runs; at the demo's 7.52 Hz, it blinks all the time.
Pinout
The six Proteus pins keep the v1.0 names, order and places. Careful: the header of a real GY-BME280 reads VCC GND SCL SDA CSB SDO, so SDO and CSB are swapped against the Proteus part. Always wire by the names:
| Pin | On I2C | On SPI | Demo connection |
|---|---|---|---|
| VCC | Power | Power | Supply terminal |
| GND | Ground | Ground | GND |
| SCL | I2C clock | SCK, the clock | Arduino A5 |
| SDA | I2C data | SDI, data into the chip (MOSI) | Arduino A4 |
| SDO | Address bit: open or LOW = 0x76, HIGH = 0x77 | Data out of the chip (MISO) | U1: open; U2: VCC (0x77) |
| CSB | Open or HIGH = I2C | Chip select, LOW = SPI | Open on both |
Gauges, Weather Window and LEDs
| Indicator | What it shows |
|---|---|
| Thermometer | The red column follows the temperature, with the value below it |
| Humidity drop | Filled blue up to the relative humidity |
| Barometer dial | The needle on the pressure in hPa |
| Vent on the BME280 | Glows cyan while a measurement runs |
| Weather window | Sun, clouds, rain, storm, snow or mountain, the weather's name and the altitude (ALT) against the SEALEVEL property |
| PWR LED (red) | Lit while VCC and GND are connected |
| I2C LED (green) | Lights for 150 ms after every bus operation addressed to this chip |
| PANEL / OPEN PANEL, SIMPLE / ADVANCE | The panel button and the device badge |
The PWR and I2C LEDs are a TEP addition: the real GY-BME280 has no LED.
Component Properties
| Property | Meaning | Default |
|---|---|---|
| TEMPERATURE | The temperature at the start, -40 to 85 C | 25 |
| HUMIDITY | The relative humidity at the start, 0 to 100 % | 50 |
| PRESSURE | The pressure at the start, 300 to 1100 hPa | 1013.25 |
| SEALEVEL (new) | The sea-level pressure for the altitude on the board and the panels, 800 to 1100 hPa; your sketch uses its own | 1013.25 |
Every Run starts again from these properties, as in v1.0.
BME280 Simple: The Weather Panel on the Sheet
Beside the Simple board sits the BME280 WEATHER panel (on the right of the image above):
| Part | What it does |
|---|---|
| Header, red X | BME280 WEATHER; the X closes the panel |
| TEMPERATURE, HUMIDITY, PRESSURE | Three sliders: -40 to 85 C, 0 to 100 % and 300 to 1100 hPa |
| Six presets | SUNNY, RAINY, STORM, SNOW, MOUNTAIN and SEA LEVEL; the active one gets a thick navy frame |
| Green bar | What your sketch set, for example NORMAL T X1 P X1 H X1 FILTER OFF 7.52 HZ (or NO POWER, STARTING, WAITING FOR THE SKETCH) |
| ARDUINO READ | The values your sketch really read last, for example 25.00 C 50.0 % 1013.25 hPa |
| Bus line | I2C 0x76 (SDO LOW) 100 kHz with the clock measured on the pin (SPI 4-WIRE and its clock on SPI), then ALT and DEW |
ARDUINO READ is the line to watch: it is not what the sliders say, but what your sketch got from the chip.
Six Weather Presets
One click sets all three values at once. The altitude and the dew point follow from them:
| Preset | Temperature | Humidity | Pressure | Altitude | Dew point |
|---|---|---|---|---|---|
| SUNNY | 30 C | 35 % | 1020 hPa | -56 m | 12.9 C |
| RAINY | 16 C | 92 % | 1002 hPa | 94 m | 14.7 C |
| STORM | 22 C | 95 % | 975 hPa | 323 m | 21.2 C |
| SNOW | -5 C | 85 % | 1005 hPa | 69 m | -7.1 C |
| MOUNTAIN | 5 C | 40 % | 795 hPa | 2000 m | -7.5 C |
| SEA LEVEL | 15 C | 50 % | 1013.25 hPa | 0 m | 4.7 C |
A negative altitude is no error: 1020 hPa is more than the 1013.25 hPa reference, as if you stood 56 m below the sea. Here is STORM:
The drop is almost full, the needle has fallen to 975 hPa, and the status box says ARDUINO READ 22.00 C 95.0 % 975.00 hPa and DEW 21.2 C: at 95 %, the dew point is close to the air temperature. With the demo's settings (filter off), the next measurement has the new values. SNOW drops the thermometer below zero:
Snowflakes fall in the window, and this time the vent glows cyan: I caught the chip in the middle of a measurement. MOUNTAIN is a lesson in pressure:
795 hPa is what the air weighs at about 2000 m, so the window shows the peaks with ALT 2000 m. With ALT switched on, the demo sketch prints "Altitude: 1999.9 m | Dew point: -7.5 C" under each reading.
RAINY and the Weather Alert LED
Now the demo's new trick. Click RAINY (16 C, 92 %, 1002 hPa): the humidity is above 80 %, so UNO 1 prints a weather alert and lights the LED D1 on A0:
Here you see the whole node: U1 on A4 / A5 of ARD1 with SDO and CSB open, D1 with its 220 Ω resistor on A0, and the Serial Monitor part U3 on D0 / D1. The LED comes on at 80 % humidity (rain likely) or 35 C (heat).
Closing the Panel
Need room on the sheet? Click the red X: the board button says PANEL: CLOSED with a grey dot, and the sensor keeps running. PANEL brings the panel back. Here, U1 is at SUNNY:
BME280 Advance: The Pop-Up Weather Station
The Advance device keeps only the board on the schematic. Here is U2, wired with SDO to VCC, so it answers at 0x77:
At Run, the "TEP BME280 Advance" pop-up opens with the look of our TEP Serial Monitor and no Windows title bar: move it by its header, resize or minimise it, and reopen it with OPEN PANEL. The header shows the state (for example U2 · NORMAL), the Weather and Test tabs and the theme, Settings and Help icons.
The Weather Page
The Weather page is a small weather station. In the featured image at the top, U2 runs with the demo's settings (x1, filter off, 7.52 Hz): I clicked STORM, the Arduino read 22.00 C, 95.0 % and 975.00 hPa at once, and U4 jumped from RAINY to STORM in one line. Now look at the same STORM after I typed OSR 16 and FILTER 16 on U4:
- Toolbar chips: NORMAL, 4.48 Hz, I2C 0x77, 536 measurements, "Read 0.6 s ago".
- SENSOR: chip ID 60 at I2C 0x77 (SDO HIGH), T x16 P x16 H x16, filter 16, standby 125 ms, and t_measure 98.0 ms (max 112.80).
- Three gauges: the value you set and, in green, what the Arduino read; click the track or - / + to change it.
- WEATHER: the altitude (323 m), the sea level (1013.25 hPa), the dew point and the absolute humidity (21.2 C, 18.4 g/m³); -1 / +1 hPa, 0 m here (the altitude becomes 0 m at the pressure now) and 1013.25.
- Below: the six presets, the TREND of the last 60 measurements and the LAST BUS OPERATIONS, decoded, newest first.
And here is the IIR filter at work. You set 22.0 C and 975.00 hPa, but the Arduino read 23.00 C and 987.73 hPa. The trend shows the temperature sliding down from 25.00 C, and the bus log shows the pressure falling read by read: 997.78, 992.58, 987.73 hPa. The raw humidity, 38073, is the same in every read: it is not filtered. No bug: a real BME280 with filter 16 does the same.
The Test Page: Four Measured Sensor Test Tools
The four tools on the Test tab only change the environment and read the BME280's own logs; they never talk to your Arduino. So every number is what the chip and your sketch really did, timed with the simulation clock. Each tool ends with a bold "Good for:" line. All results below come from U2 after OSR 16 and FILTER 16 on U4, except the second Altitude run.
1. Register Check: Did Your Sketch Set Up the Chip?
Good for: "checking that your sketch found the chip, read all its trimming bytes and set what it wanted." It works live, without a Run button. Read it like a checklist:
- Interface: I2C 0x77, SDO HIGH, CSB open; SCL 100.0 kHz, measured on the pin.
- Chip ID D0 = 60, read once, and 1 soft reset: Adafruit's
begin()at work. - Calibration: 32 of the 32 bytes read, complete.
- ctrl_hum F2 = 05: humidity x16. ctrl_meas B7, binary 101 101 11: temperature x16, pressure x16, mode 11 = NORMAL.
- config F5 = 50: standby 125 ms and filter 16. status F3 = 08: measuring.
- Ignored writes: none (config in normal mode, during the start-up, to read-only registers).
Below come the counters, the trimming values T1 to H6, the data registers now against what your sketch read last, and the decoded bus operations.
2. Timing: How Long Does One Measurement Take?
Choose 5, 10 or 20 measurements and click Run test. Ten measurements at x16:
Good for: "seeing how long one measurement takes at your oversampling and if your sketch reads each one." Every measurement took 98.000 ms, the data sheet's typical value (maximum 112.80 ms), and a new one started every 223.0 ms: 98 ms plus the 125 ms standby. Amber bars were never read; the blue ones were read at the green lines. The sketch read 2 of 10 (measurements 3 and 8), because it prints one line a second. With the demo's x1, the tool gives 8.000 ms and 133.000 ms.
3. Step Response: How Long Does the IIR Filter Delay a Change?
Choose a step (temperature +10 C, humidity +30 % or pressure -10 hPa) and click Run test; afterwards, the tool gives the environment back. Here, the temperature jumps from 30 to 40 C with filter 16:
| Share of the step | The chip (data registers) | Your sketch |
|---|---|---|
| 50 % | 2523.8 ms, 12 samples | 2678.0 ms |
| 63 % | 3638.8 ms | - |
| 90 % | 8098.8 ms, 37 samples | 8678.6 ms |
| 99 % | 15903.8 ms, 72 samples | - |
Good for: "seeing how the IIR filter and your read rate delay a sudden change before your sketch prints it." The first measurement came 70.8 ms after the step, but the 10 C jump needed 8.1 s to reach 90 % and almost 16 s to reach 99 %. The blue curve is the chip, one dot per measurement; the green dots are your sketch's reads, trailing a little. "48 reads": for every printed line, the bus log shows the temperature read three times, because Adafruit's readHumidity() and readPressure() read it again. With the filter off, the first measurement has the whole step.
4. Altitude: What Does Your Sketch Report While Climbing?
The pressure follows a climb of 10, 100 or 500 m in 10 s, then holds for 3 s. The chart compares the true altitude (grey) with the altitude of every pressure your sketch read (green). First, +100 m from SUNNY (-56.0 m) with filter 16 and one reading a second:
The green dots fall far behind the climb: 13 reads, a maximum error of 32.42 m and an average lag of 2413 ms. At the end, the sketch's altitude was 26 m instead of 44 m, not settled within the 3 s hold. Then I typed DEFAULTS and RATE 200 on U4 (x1, filter off, a reading every 200 ms) and ran the same climb again:
Now the dots sit on the line: 65 reads, 1.33 m maximum error, 73 ms lag, settled 86 ms after the stop, and the last altitude is 44 m. One pressure count is 1.42 cm here. Good for: "seeing what altitude your sketch reports while the sensor climbs, and how much the filter lags." So choose the filter for your project: filter 16 suits a weather station, where a calm value matters more than speed; an altimeter needs a small filter or none, and faster reads.
Settings and Help
The gear opens Settings: theme (TEP Dark or Light), text size, open the panel at Run and the window size, saved for your Windows user.
The ? icon opens Help & Support: eight cards with their links (the BME280 forum board, this article, donate, website, forum) and Copy diagnostics for a bug report. A links.ini next to the DLL can change the links.
BME280 Weather Station with Arduino in Proteus
Open BME280-ArduinoUnoV3.pdsprj from the Proteus Simulation folder, with BME280_Demo.hex and both DLLs beside it. Its two Arduino UNOs from our Arduino Library for Proteus V3.0 run the same HEX file, because the sketch finds the sensor's address by itself:
- NODE 1 - SIMPLE: UNO 1 (ARD1) with the BME280 Simple (U1) at 0x76 (SDO and CSB open), the alert LED D1 on A0 and Serial Monitor U3.
- NODE 2 - ADVANCE: UNO 2 (ARD2) with the BME280 Advance (U2) at 0x77 (SDO to VCC, CSB open), the alert LED D2 on A0 and Serial Monitor U4.
Wiring
| From | To | Why |
|---|---|---|
| BME280 VCC / GND | Supply / ground | Power (the PWR LED lights) |
| BME280 SCL / SDA | Arduino A5 / A4 | I2C clock and data |
| BME280 SDO | U1: open; U2: VCC | Address 0x76 or 0x77 |
| BME280 CSB | Open | Open = I2C (the board's pull-up) |
| LED + 220 Ω | A0 to GND | The weather alert LED |
| Serial Monitor RXD / TXD / GND | Arduino D1 / D0 / ground | Shows what the Arduino prints, sends what you type |
| Serial Monitor RXD2 | Not connected | I2C has no serial line to watch |
A4 and A5 are the UNO's I2C pins (see our Introduction to Arduino UNO). The Wire library turns on the UNO's internal pull-ups, so the simulation needs no external pull-up resistors; a real I2C bus does, and the GY-BME280 has them on board.
Using SPI Instead of I2C
No demo uses SPI, but the model speaks it (tested on a PC). Wire CSB to D10, SCL (SCK) to D13, SDA (SDI) to D11 and SDO to D12, and use Adafruit_BME280 bme(10); with bme.begin();, or bme(10, 11, 12, 13) for software SPI.
The Arduino Code
The sketch uses the unmodified Adafruit BME280 Library (with Adafruit Unified Sensor and Adafruit BusIO), like v1.0:
#include <Wire.h>
#include <Adafruit_BME280.h>
The settings start at the v1.0 values, and the DEFAULTS command brings them back:
// the v1.0 settings (DEFAULTS restores them)
Adafruit_BME280::sensor_mode mode = Adafruit_BME280::MODE_NORMAL;
uint8_t osr[3] = {1, 1, 1}; // T, P, H codes: 0 skip, 1 x1, 2 x2, 3 x4, 4 x8, 5 x16
uint8_t filterCode = 0; // 0 off, 1 = 2, 2 = 4, 3 = 8, 4 = 16
uint8_t standbyCode = 2; // 125 ms
unsigned long rate = 1000; // a reading line every 1 s
float seaLevel = 1013.25;
In setup(), Wire runs at 100 kHz, the clock the Register check measured:
Wire.begin();
Wire.setClock(100000);
Wire.setWireTimeout(25000, true);
Then begin() tries 0x76 first and 0x77 second, which is why both UNOs can run the same HEX:
address = 0x76;
ready = sensor.begin(0x76, &Wire);
if (!ready) { address = 0x77; ready = sensor.begin(0x77, &Wire); }
if (!ready) {
Serial.println(F("Sensor not found. Check power, SDA, SCL, SDO and CSB."));
return;
}
applySettings() sends the mode, the three oversampling values, the filter and the standby time in one call:
void applySettings() {
sensor.setSampling(mode, (Adafruit_BME280::sensor_sampling)osr[0], (Adafruit_BME280::sensor_sampling)osr[1],
(Adafruit_BME280::sensor_sampling)osr[2], (Adafruit_BME280::sensor_filter)filterCode,
(Adafruit_BME280::standby_duration)standbyCode);
}
measureMs() is the data sheet formula from above; the OSR command prints its result:
float measureMs() { // the data sheet's typical measurement time (9.1)
float t = 1.0 + 2.0 * OSR_TIMES[osr[0]];
if (osr[1]) t += 2.0 * OSR_TIMES[osr[1]] + 0.5;
if (osr[2]) t += 2.0 * OSR_TIMES[osr[2]] + 0.5;
return t;
}
In FORCED mode, every reading first starts a measurement. The pressure comes in pascals, so it is divided by 100:
if (mode == Adafruit_BME280::MODE_FORCED) sensor.takeForcedMeasurement();
lastT = sensor.readTemperature();
lastH = sensor.readHumidity();
lastP = sensor.readPressure() / 100.0F;
The weather alert switches at 80 % humidity or 35 C, and the LED and the message change only when the alert does:
bool now = (lastH >= 80.0) || (lastT >= 35.0);
if (now != alert) {
alert = now;
digitalWrite(LED_PIN, alert ? HIGH : LOW);
The altitude uses the Adafruit formula with the sketch's own sea-level pressure, and the dew point the Magnus formula:
float altitude(float hPa) { // the Adafruit library's formula (no -0.0 for a tiny negative)
float a = 44330.0 * (1.0 - pow(hPa / seaLevel, 0.1903));
return (a > -0.05 && a < 0.05) ? 0.0 : a;
}
float dewPoint(float t, float h) { // Magnus formula (no dew point at 0 % humidity)
if (!(h > 0.0)) return NAN;
float g = log(h / 100.0) + 17.62 * t / (243.12 + t);
return 243.12 * g / (17.62 - g);
}
ALTITUDE works the other way round: you say how high you are, and the library's seaLevelForAltitude() finds the sea-level pressure:
seaLevel = sensor.seaLevelForAltitude(m, sensor.readPressure() / 100.0F);
The loop prints a line every RATE ms; if it falls behind, it starts again from now instead of printing a burst:
if (mode != Adafruit_BME280::MODE_SLEEP && millis() - lastReading >= rate) {
lastReading += rate;
if (millis() - lastReading >= rate) lastReading = millis();
reading();
}
The settings live in RAM, so a reset brings back the v1.0 values. To change the sketch, export a new HEX file and load it into both UNOs; see How to get the HEX file from Arduino. New to Arduino? Start with our Arduino Tutorial for Beginners.
Serial Monitor Commands
| Command | What it does |
|---|---|
| HELP | The command list (two lines) |
| STATUS | Four lines: address, chip ID, mode, rate; oversampling, filter, standby, t_measure; the last reading with the dew point and the alert; the altitude and the sea level |
| READ | One reading now (in SLEEP: the last measurement) |
| MODE NORMAL / FORCED / SLEEP | NORMAL: the chip measures by itself; FORCED: one measurement per reading; SLEEP: none |
| OSR n | Oversampling 1, 2, 4, 8 or 16 for all three |
| OSR t p h | Each on its own, 0 = skip (OSR 2 16 0: T x2, P x16, no humidity) |
| FILTER n | The IIR filter: 0 (off), 2, 4, 8 or 16 |
| STANDBY ms | 0.5, 10, 20, 62.5, 125, 250, 500 or 1000 |
| RATE ms | A reading line every 100 to 60000 ms (default 1000) |
| SEALEVEL hPa | The sea-level pressure for the altitude (800 to 1100) |
| ALTITUDE m | You know your altitude: sets the sea-level pressure |
| ALT | An indented altitude / dew point line under every reading (on / off) |
| DEFAULTS | Back to the v1.0 settings: NORMAL, x1, filter off, standby 125 ms, a reading a second |
How to Run the Demo
- Press Run. Both Serial Monitors (9600 baud) and U2's pop-up open; the PWR LEDs light, and the I2C LEDs flash with every reading.
- On U1's panel, drag a slider, then click RAINY (D1 lights), SUNNY, STORM, SNOW and MOUNTAIN.
- Type ALT and STATUS in U3's send box.
- On U4, type OSR 16 and FILTER 16, then click STORM on U2's Weather page and watch the values creep.
- Run the four tools on U2's Test tab, then type DEFAULTS and RATE 200 on U4 and run Altitude again.
BME280 Proteus Simulation Results
The Serial Monitor in Its Simple Interface
Both monitors in this demo run in the Simple interface of our TEP Serial Monitor, as in every monitor screenshot here. Only the log, the send box and one slim toolbar row stay visible (baud rate, follow, pause, search and clear), so the window stays small.
- Switch to it: right-click the log and choose Simple interface, or press Ctrl+Shift+U.
- Back to the full view: click the corner button (the expand arrows at the top right), press Esc or Ctrl+Shift+U, or right-click and choose Full interface.
- Your choice is remembered.
Type commands such as STATUS or ALT in the send box and press Enter; the quick buttons (STATUS, OSR 16, FILTER 16, ALT) come back with the full view. Every line of the v1.1 sketch is 81 characters or less, so it fits this small window. Read all about the monitor in TEP Serial Monitor Advance for Proteus.
Start-Up
After Run, U3 prints the v1.0 banner, the address it found and the commands, then one reading a second:
TEP BME280 - Temperature / Humidity / Pressure
Demo v1.1 - BME280 found at 0x76 (SDO low / open), chip ID 0x60
Drag the three sensor sliders to change the environment.
Serial Monitor: HELP, STATUS, READ, MODE NORMAL|FORCED|SLEEP, OSR n|t p h,
FILTER n, STANDBY ms, RATE ms, SEALEVEL hPa, ALTITUDE m, ALT, DEFAULTS
Temperature: 25.0 C | Humidity: 50.0 % | Pressure: 1013.2 hPa
Temperature: 25.0 C | Humidity: 50.0 % | Pressure: 1013.2 hPa
Chip ID 0x60 proves that I2C works and that the sensor is a BME280; U4 says "found at 0x77 (SDO high)". Why 1013.2? The sketch prints one decimal, and 1013.25 hPa sits on the rounding edge, so the last bit of the measurement decides between 1013.2 and 1013.3, as in v1.0.
RAINY: The Weather Alert
Temperature: 16.0 C | Humidity: 92.0 % | Pressure: 1002.0 hPa
Weather alert: humidity 92.0 % - rain likely (LED A0 on)
Temperature: 16.0 C | Humidity: 92.0 % | Pressure: 1002.0 hPa
Temperature: 16.0 C | Humidity: 92.0 % | Pressure: 1002.0 hPa
The first RAINY reading already has 16.0 C, 92.0 % and 1002.0 hPa, and the alert follows once. D1 stays lit, and no reminder fills the log.
ALT and STATUS
Next, I typed ALT and STATUS:
ALT
Altitude and dew point under each reading: on
Temperature: 16.0 C | Humidity: 92.0 % | Pressure: 1002.0 hPa
Altitude: 94.1 m | Dew point: 14.7 C
STATUS
Status: BME280 at 0x76 (chip ID 0x60), mode NORMAL, a reading every 1000 ms
oversampling T x1 P x1 H x1, filter OFF, standby 125.0 ms, t_measure 8.0 ms
last: 16.00 C, 92.00 %, 1002.00 hPa, dew point 14.7 C, alert on
altitude 94.1 m at sea level 1013.25 hPa
The v1.0 reading line stays as it was, and ALT adds an indented line: 94.1 m (1002 hPa against 1013.25 hPa) and a dew point of 14.7 C, only 1.3 C below the air temperature. STATUS sums everything up in four short lines, with the last values to two decimals and "alert on".
SUNNY: Alert Over
ALT
Altitude and dew point under each reading: off
Temperature: 16.0 C | Humidity: 92.0 % | Pressure: 1002.0 hPa
Temperature: 30.0 C | Humidity: 35.0 % | Pressure: 1020.0 hPa
Weather alert over (LED A0 off)
A second ALT switches the extra line off. One click on SUNNY, and the next reading jumps to 30.0 C, 35.0 % and 1020.0 hPa: no more rain, so the sketch prints "Weather alert over" and turns D1 off. At 35 C or more, it would print a heat alert instead.
OSR 16 and FILTER 16 on U4
Temperature: 25.0 C | Humidity: 50.0 % | Pressure: 1013.2 hPa
OSR 16
Oversampling T x16 P x16 H x16 (t_measure 98.0 ms typical)
Temperature: 25.0 C | Humidity: 50.0 % | Pressure: 1013.2 hPa
FILTER 16
IIR filter 16 (temperature and pressure)
Temperature: 25.0 C | Humidity: 50.0 % | Pressure: 1013.2 hPa
OSR 16 prints the new measurement time from measureMs(), and FILTER 16 reminds you that the filter works on temperature and pressure only. The readings stay the same: the filter shows only when something changes, as on the Weather page.
DEFAULTS and RATE 200
Temperature: 30.0 C | Humidity: 35.0 % | Pressure: 1015.8 hPa
Temperature: 30.0 C | Humidity: 35.0 % | Pressure: 1016.7 hPa
DEFAULTS
Defaults (v1.0 demo): NORMAL, x1, filter OFF, standby 125 ms, a reading every 1 s
Temperature: 30.0 C | Humidity: 35.0 % | Pressure: 1020.0 hPa
RATE 200
Reading every 200 ms
Temperature: 30.0 C | Humidity: 35.0 % | Pressure: 1020.0 hPa
Temperature: 30.0 C | Humidity: 35.0 % | Pressure: 1020.0 hPa
Watch the pressure: after SUNNY, filter 16 was still pulling it up, 1015.8 and then 1016.7 hPa. DEFAULTS turns the filter off, and the very next line has the full 1020.0 hPa. RATE 200 then prints five lines a second, the setting of the second Altitude run.
Troubleshooting
- "Sensor not found. Check power, SDA, SCL, SDO and CSB.": check VCC / GND (the PWR LED must be lit), SCL to A5, SDA to A4, and that CSB is open or HIGH; a CSB that was LOW once selects SPI until the next Run.
- A slider change does not show at once: correct; the sketch sees it after the chip's next measurement (every 133 ms with the demo's settings), and with the IIR filter it creeps in over several measurements. FILTER 0 turns the filter off.
- Humidity "nan": the humidity oversampling is 0 (skip); type OSR 1 or DEFAULTS.
- No reading lines: MODE SLEEP stops them; type MODE NORMAL or READ.
- The altitude is not 0 m at your place: set the sea-level pressure with SEALEVEL or ALTITUDE m; on the Advance Weather page, use 0 m here; for the board, the SEALEVEL property.
- The Test tab says "Cannot start: ...": the message gives the reason (no power, still starting, no measurement yet, another test running).
- No panel or no monitor window: TEPBME280.DLL or TEPSERIALMON.DLL is missing from MODELS and the project folder; click OPEN PANEL or OPEN MONITOR, or turn "Open the panel at Run" back on.
- No red X, or the board looks like v1.0: the design still holds the v1.0 symbol; replace TEPBME280.LIB, delete TEPBME280.IDX and re-pick the part.
- Wires: start them at the ends of the pins below the board.
Things to Know Before Using a Real GY-BME280
The demo sketch uses only the Adafruit libraries, so it runs on a real UNO and GY-BME280, too. Keep in mind:
- 3.3 V only: the 6-pin purple GY-BME280 (often sold as GY-BME280-3.3) has no regulator, so feed VCC from the UNO's 3.3V pin, NOT from 5 V. Some other BME280 boards have a regulator and take 5 V: check yours. In the simulation, VCC goes to a supply terminal, because the model only checks that VCC and GND are connected.
- Logic levels: the BME280 is a 3.3 V chip. On I2C, the board's pull-ups go to 3.3 V, and the UNO reads that as HIGH. For SPI from a 5 V UNO, put a level shifter on CSB, SCK and SDI.
- Check the header: the silk reads VCC GND SCL SDA CSB SDO, while the Proteus part has SDO before CSB; wire by the names.
- CSB and SDO: the board pulls CSB up (10 k), so leave it open for I2C. SDO sets the address: GND = 0x76, 3.3 V = 0x77. Some boards pull SDO up and answer at 0x77; the demo sketch tries both.
- BMP280 or BME280? A BMP280 has no humidity sensor, looks the same and has chip ID 0x58, so the Adafruit BME280 library refuses it. Our model is always a BME280 (0x60).
- Self-heating: a real sensor in normal mode with high oversampling warms itself a little; the simulation has no self-heating, noise or drift.
Limitations of the Simulation
- Not modelled: noise and the resolution gain of oversampling, self-heating, tolerances and drift, a trimming set per chip, the supply current, the I2C high-speed timing limits and the voltage levels.
- The model is our own implementation, written from Bosch Sensortec's published BME280 data sheet (BST-BME280-DS002); it contains no Bosch code. Bosch's BME280 SensorAPI was used on a PC to test the model and is not part of the DLL or the firmware.
- Licences: BSD for the Adafruit BME280 Library 2.3.0, Apache License 2.0 for Adafruit Unified Sensor 1.1.15 and MIT for Adafruit BusIO 1.17.4. The HEX file also contains the Arduino AVR core 1.8.6, which includes LGPL-licensed code; its source code is on GitHub.
- Tested in Proteus 8.5 SP0 on 8 Oct 2026 (the demo, both panels, the four tools, a v1.0 design and every screenshot here) and with 3,628 automatic PC checks, all passed: 61 of them with real drivers (the unmodified Adafruit BME280 2.3.0 over I2C, hardware SPI and software SPI, and Bosch's SensorAPI) and 44 with the real demo sketch on two UNOs; the unchanged v1.0 test passed too. SPI was tested on the PC only, because no demo uses it. Proteus 7 is not supported.
Want to see another Adafruit library at work in Proteus? Try our PN532 NFC Library for Proteus. To send your weather readings to another Arduino by radio, add our HC-12 Library for Proteus or nRF24L01 Library for Proteus.
So, that was all about the BME280 Sensor Library for Proteus V1.1. I hope the weather presets, the live board, the four test tools and the FILTER 16 experiment make the BME280 much easier to understand, so your weather station or altimeter works the first time you wire a real sensor. If you use the BME280 Sensor Library for Proteus in a project, please share your feedback in the comments or in our forum, and if you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!
























Comments
0