All tutorials

4 · Displays & buses

Weather station + clock

Expert30 min

Goal

Combine the BMP280 (temperature, pressure) with the DS3231 clock.

Why it matters

Two peripherals on one bus: you must handle addresses and conflicts.

What you need

  • Arduino UNO board
  • MPU6050 IMU
  • BMP280 pressure/temperature sensor
  • DS3231 real-time clock

Nothing to buy: every component below is simulated in the browser.

Steps

  1. 01Add the BMP280 and DS3231 RTC components.
  2. 02Load the starter sketch: it reads calibration then compensates the raw values.
  3. 03Run it and change Temperature / Pressure / Clock offset in the Scenario panel.
  4. 04Note the DS3231 sits at 0x68, so a neighbouring MPU6050 moves to 0x69.

Starter sketch

// BMP280 temperature + pressure and DS3231 clock, straight over Wire.
#include <Wire.h>

const uint8_t BMP = 0x76;
const uint8_t RTC = 0x68;

uint16_t calT1; int16_t calT2; uint16_t calP1;

uint8_t readReg8(uint8_t addr, uint8_t reg) {
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.endTransmission(false);
  Wire.requestFrom(addr, (uint8_t)1);
  return Wire.read();
}

uint16_t readLE16(uint8_t reg) {
  Wire.beginTransmission(BMP);
  Wire.write(reg);
  Wire.endTransmission(false);
  Wire.requestFrom(BMP, (uint8_t)2);
  uint8_t lo = Wire.read();
  uint8_t hi = Wire.read();
  return (uint16_t)((hi << 8) | lo);
}

long read20(uint8_t reg) {
  Wire.beginTransmission(BMP);
  Wire.write(reg);
  Wire.endTransmission(false);
  Wire.requestFrom(BMP, (uint8_t)3);
  long msb = Wire.read();
  long lsb = Wire.read();
  long xlsb = Wire.read();
  return ((msb << 16) | (lsb << 8) | xlsb) >> 4;
}

uint8_t fromBcd(uint8_t v) { return (v >> 4) * 10 + (v & 0x0F); }

void setup() {
  Serial.begin(9600);
  Wire.begin();
  calT1 = readLE16(0x88);
  calT2 = (int16_t)readLE16(0x8A);
  calP1 = readLE16(0x8E);
  Serial.print("BMP280 id 0x");
  Serial.println(readReg8(BMP, 0xD0), HEX);
}

void loop() {
  long adcT = read20(0xFA);
  long adcP = read20(0xF7);
  float tFine = ((adcT / 16384.0) - (calT1 / 1024.0)) * calT2;
  float tempC = tFine / 5120.0;
  float pa = (1048576.0 - adcP) * 6250.0 / calP1;

  Serial.print("T ");
  Serial.print(tempC);
  Serial.print(" C   P ");
  Serial.print(pa / 100.0);
  Serial.println(" hPa");

  uint8_t h = fromBcd(readReg8(RTC, 0x02));
  uint8_t m = fromBcd(readReg8(RTC, 0x01));
  uint8_t s = fromBcd(readReg8(RTC, 0x00));
  Serial.print("RTC ");
  Serial.print(h); Serial.print(":");
  Serial.print(m); Serial.print(":");
  Serial.println(s);

  delay(1000);
}

This tutorial runs inside the Circuitly simulator: your wiring and your code are checked automatically at every step.

Frequently asked questions

Do I need to buy hardware for this tutorial?
No. Everything runs in the browser: Circuitly simulates the board, the components and the code. Real hardware is optional if you want to rebuild the circuit afterwards.
Which components are used?
Arduino UNO board, MPU6050 IMU, BMP280 pressure/temperature sensor, DS3231 real-time clock. They are already available in the simulator library.
How long does it take?
About 30 minutes, expert level, in 4 guided steps.
What should I know before starting?
The previous tutorial in the series, “Compute tilt (roll/pitch)”, is enough preparation. No software install is required.
Is the code provided and checked?
Yes: a starter sketch is provided, and the simulator checks your wiring and your code automatically at every step.

For teachers

Get the teaching pack: 6 ready-to-run sessions

Full progression, objectives, student steps and an assessment grid — printable, free.

One address, no spam: just the pack and classroom updates.

In the same series

Explore other topics