Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Manufacturing Technology >> Manufacturing process

Advanced Weather Station v2.0: Real‑Time Temperature, Pressure, Humidity & Altitude Monitoring

Build a compact weather station that accurately measures temperature, pressure, humidity, and altitude right in your living space.

Story

Using the Adafruit Starter Pack for Windows 10 IoT Core on a Raspberry Pi 2, this project demonstrates how to interface a BME280 sensor (or BMP280) to read environmental data and publish it to a cloud service.

If you own a BMP280, follow the Weather Station v1 guide instead: Weather Station v1.

Hardware

Connect the Raspberry Pi 2 to a breadboard and wire the BME280 sensor according to the Fritzing diagram in the “Schematics” section below.

Software

Download the starter code from GitHub – ms‑iot/adafruitsample. We’ll walk you through adding the necessary code to communicate with the sensor and publish your readings.

Open Lesson_203v2\StartSolution\lesson_203v2.sln and edit mainpage.xaml.cs.

A fully completed version is available at Lesson_203v2\FullSolution\lesson_203v2.sln.

MainPage.xaml.cs

Add a reference to the BME280 class:

public sealed partial class MainPage : Page
{
    // Create a new object for our sensor class
    BME280 BME280;

Initialize the sensor in OnNavigatedTo:

// Create a new object for our sensor class
BME280 = new BME280Sensor();
// Initialize the sensor
await BME280.Initialize();

Next, add code to gather and log data:

//Initialize them to 0.
float temp = 0;
float pressure = 0;
float altitude = 0;
float humidity = 0;
//Create a constant for pressure at sea level.
const float seaLevelPressure = 1022.00f;
//Read 10 samples of the data
for (int i = 0; i < 10; i++){
    temp = await BME280.ReadTemperature();
    pressure = await BME280.ReadPreasure();
    altitude = await BME280.ReadAltitude(seaLevelPressure);
    humidity = await BME280.ReadHumidity();
    //Write the values to your debug console
    Debug.WriteLine("Temperature: " + temp.ToString() + " deg C");
    Debug.WriteLine("Humidity: " + humidity.ToString() + " %");
    Debug.WriteLine("Pressure: " + pressure.ToString() + " Pa");
    Debug.WriteLine("Altitude: " + altitude.ToString() + " m");
    Debug.WriteLine("\n");
}

BME280.cs

Open BME280.cs and add the following after the register‑address enum:

//String for the friendly name of the I2C bus
const string I2CControllerName = "I2C1";
//Create an I2C device
private I2cDevice bme280 = null;
//Create new calibration data for the sensor
BME280_CalibrationData CalibrationData;
//Variable to check if device is initialized
bool init = false;

Enhance the Initialize method to set up the I2C connection:

public async Task Initialize()
{
    Debug.WriteLine("BME280::Initialize");
    try
    {
        I2cConnectionSettings settings = new I2cConnectionSettings(BME280_Address);
        settings.BusSpeed = I2cBusSpeed.FastMode;
        string aqs = I2cDevice.GetDeviceSelector(I2CControllerName);
        DeviceInformationCollection dis = await DeviceInformation.FindAllAsync(aqs);
        bme280 = await I2cDevice.FromIdAsync(dis[0].Id, settings);
        if (bme280 == null)
        {
            Debug.WriteLine("Device not found");
        }
    }
    catch (Exception e)
    {
        Debug.WriteLine("Exception: " + e.Message + "\n" + e.StackTrace);
        throw;
    }
}

Add the Begin routine to verify the sensor signature and load calibration data:

private async Task Begin()
{
    Debug.WriteLine("BME280::Begin");
    byte[] WriteBuffer = new byte[] { (byte)eRegisters.BMP280_REGISTER_CHIPID };
    byte[] ReadBuffer = new byte[] { 0xFF };
    bmp280.WriteRead(WriteBuffer, ReadBuffer);
    Debug.WriteLine("BME280 Signature: " + ReadBuffer[0].ToString());
    if (ReadBuffer[0] != BMP280_Signature)
    {
        Debug.WriteLine("BMP280::Begin Signature Mismatch.");
        return;
    }
    init = true;
    CalibrationData = await ReadCoefficeints();
    await WriteControlRegister();
    await WriteControlRegisterHumidity();
}

Control‑register helpers:

private async Task WriteControlRegisterHumidity()
{
    byte[] WriteBuffer = new byte[] { (byte)eRegisters.BMP280_REGISTER_CONTROLHUMID, 0x03 };
    bmp280.Write(WriteBuffer);
    await Task.Delay(1);
}

private async Task WriteControlRegister()
{
    byte[] WriteBuffer = new byte[] { (byte)eRegisters.BMP280_REGISTER_CONTROL, 0x3F };
    bmp280.Write(WriteBuffer);
    await Task.Delay(1);
}

Utility functions to read register data:

private UInt16 ReadUInt16_LittleEndian(byte register)
{
    UInt16 value = 0;
    byte[] writeBuffer = new byte[] { 0x00 };
    byte[] readBuffer = new byte[] { 0x00, 0x00 };
    writeBuffer[0] = register;
    bmp280.WriteRead(writeBuffer, readBuffer);
    int h = readBuffer[1] << 8;
    int l = readBuffer[0];
    value = (UInt16)(h + l);
    return value;
}

private byte ReadByte(byte register)
{
    byte value = 0;
    byte[] writeBuffer = new byte[] { 0x00 };
    byte[] readBuffer = new byte[] { 0x00 };
    writeBuffer[0] = register;
    bmp280.WriteRead(writeBuffer, readBuffer);
    value = readBuffer[0];
    return value;
}

Calibration and compensation functions are derived directly from the BMP280 datasheet and are already provided.

Implement ReadTemperature to return the sensor’s temperature in degrees Celsius:

public async Task<float> ReadTemperature()
{
    if (!init) await Begin();
    byte tmsb = ReadByte((byte)eRegisters.BMP280_REGISTER_TEMPDATA_MSB);
    byte tlsb = ReadByte((byte)eRegisters.BMP280_REGISTER_TEMPDATA_LSB);
    byte txlsb = ReadByte((byte)eRegisters.BMP280_REGISTER_TEMPDATA_XLSB);
    Int32 t = (tmsb << 12) + (tlsb << 4) + (txlsb >> 4);
    double temp = BMP280_compensate_T_double(t);
    return (float)temp;
}

Complete ReadPreasure (note the original typo; we retain it for compatibility):

public async Task<float> ReadPreasure()
{
    if (!init) await Begin();
    if (t_fine == Int32.MinValue) await ReadTemperature();
    byte tmsb = ReadByte((byte)eRegisters.BMP280_REGISTER_PRESSUREDATA_MSB);
    byte tlsb = ReadByte((byte)eRegisters.BMP280_REGISTER_PRESSUREDATA_LSB);
    byte txlsb = ReadByte((byte)eRegisters.BMP280_REGISTER_PRESSUREDATA_XLSB);
    Int32 t = (tmsb << 12) + (tlsb << 4) + (txlsb >> 4);
    Int64 pres = BMP280_compensate_P_Int64(t);
    return ((float)pres) / 256;
}

Finally, implement ReadAltitude to calculate altitude using the barometric formula:

public async Task<float> ReadAltitude(float seaLevel)
{
    if (!init) await Begin();
    float pressure = await ReadPreasure();
    pressure /= 100;
    return 44330.0f * (1.0f - (float)Math.Pow((pressure / seaLevel), 0.1903f));
}

Your project is now ready to deploy!

Expected Output

Temperature: 24.46189 deg C

Humidity: 54.372 %

Pressure: 99738.73 Pa

Altitude: 205.1726 m

Source: Weather Station V 2.0

Manufacturing process

  1. DIY Solar‑Powered Weather Station with Raspberry Pi
  2. Building an Outdoor Weather Station with Raspberry Pi 2 and ADS‑WS1
  3. Build a Raspberry Pi Weather Station that Emails Daily Weather Data
  4. Real‑Time Weather Monitoring with Arduino & ThingSpeak IoT
  5. Arduino Nano Weather Station: Sensor Kit & OLED Display
  6. Build a Reliable Arduino Weather Station with DHT Sensors
  7. Portable IoT Weather Station with Arduino Nano 33 IoT
  8. Build a Smart Weather Station with Arduino UNO and AWS Integration
  9. Build a Simple Weather Station with Arduino UNO, BMP280 Sensor & LCD
  10. Arduino Wireless Weather Station: DIY Portable Weather Monitoring Kit