Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Продвинутая метеостанция v2.0: мониторинг температуры, давления, влажности и высоты в реальном времени

Постройте компактную метеостанцию, точно измеряющую температуру, давление, влажность и высоту прямо в вашем жилом пространстве.

История

Используя Adafruit Starter Pack для Windows 10 IoT Core на Raspberry Pi 2, этот проект демонстрирует, как подключить датчик BME280 (или BMP280) для чтения экологических данных и публикации их в облачный сервис.

Если у вас BMP280, следуйте гайду Weather Station v1: Weather Station v1.

Железо

Подключите Raspberry Pi 2 к макетной плате и соедините датчик BME280 согласно Fritzing-диаграмме в разделе «Схемы» ниже.

Софт

Скачайте стартовый код с GitHub – ms-iot/adafruitsample. Мы пройдёмся по добавке кода для общения с датчиком и публикации показаний.

Откройте Lesson_203v2\StartSolution\lesson_203v2.sln и редактируйте mainpage.xaml.cs.

Полностью готовая версия доступна в Lesson_203v2\FullSolution\lesson_203v2.sln.

MainPage.xaml.cs

Добавьте ссылку на класс BME280:

public sealed partial class MainPage : Page {
    // Создаём объект для нашего класса датчика
    BME280 BME280;

Инициализируйте датчик в OnNavigatedTo:

// Создаём объект для нашего класса датчика
BME280 = new BME280Sensor();
// Инициализируем датчик
await BME280.Initialize();

Далее добавьте код для сбора и логирования данных:

// Инициализируем их нулями.
float temp = 0;
float pressure = 0;
float altitude = 0;
float humidity = 0;
// Константа давления на уровне моря.
const float seaLevelPressure = 1022.00f;
// Читаем 10 сэмплов данных
for (int i = 0; i < 10; i++) {
    temp = await BME280.ReadTemperature();
    pressure = await BME280.ReadPreasure();
    altitude = await BME280.ReadAltitude(seaLevelPressure);
    humidity = await BME280.ReadHumidity();
    // Пишем значения в консоль отладки
    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

Откройте BME280.cs и добавьте после enum адресов регистров:

// Строка для дружественного имени I2C-шины
const string I2CControllerName = "I2C1";
// Создаём I2C-устройство
private I2cDevice bme280 = null;
// Новые калибровочные данные датчика
BME280_CalibrationData CalibrationData;
// Флаг инициализации устройства
bool init = false;

Расширьте метод Initialize для настройки I2C-соединения:

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;
    }
}

Добавьте рутину Begin для проверки сигнатуры датчика и загрузки калибровки:

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();
}

Помощники контрольных регистров:

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);
}

Утилиты чтения регистров:

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;
}

Функции калибровки и компенсации взяты напрямую из даташита BMP280 и уже предоставлены.

Реализуйте ReadTemperature для возврата температуры в градусах Цельсия:

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;
}

Завершите ReadPreasure (опечатка в оригинале сохранена для совместимости):

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;
}

Наконец, реализуйте ReadAltitude для расчёта высоты по бариметрической формуле:

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));
}

Ваш проект готов к развёртыванию!

Ожидаемый вывод

Temperature: 24.46189 deg C

Humidity: 54.372 %

Pressure: 99738.73 Pa

Altitude: 205.1726 m

Источник: Weather Station V 2.0

Производственный процесс

  1. DIY солнечная метеостанция на Raspberry Pi
  2. Сборка уличной метеостанции на Raspberry Pi 2 и ADS‑WS1
  3. Создание метеостанции на Raspberry Pi с ежедневными email-отчётами о погоде
  4. Удалённый мониторинг погоды на Raspberry Pi 3 с PubNub
  5. Интеграция метеостанции с CWOP: практическое руководство
  6. Weather Monitor — DIY метеостанция на Raspberry Pi с загрузкой в Dropbox
  7. Компактная метеостанция: Arduino Nano + ESP8266, BMP280, OLED / Nokia 5110 LCD
  8. Портативная метеостанция на Arduino Nano за $10: DHT22, BMP180 и LCD
  9. eDOT: точные Arduino-часы и метеостанция с встроенным ИК-пультом
  10. Метеостанция на Arduino и ThingSpeak: температура и влажность в облаке