Keresés

Új hozzászólás Aktív témák

  • fecus

    őstag

    válasz Yoshida #482 üzenetére

    Be kell a sketchben állítani, hogy csak változáskor küldjön adatot és azt is csak 5 percenként vizsgálja.

    "Szörnyek léteznek, de túl kevesen vannak ahhoz, hogy igazán veszélyesek legyenek. Sokkal veszélyesebbek az átlagemberek, a funkcionáriusok, akik készek hinni és cselekedni anélkül, hogy kérdéseket tennének fel." (fordította DeepL ) - Primo Levi

  • balibatyo78

    csendes tag

    válasz Yoshida #482 üzenetére

    Nekem ez a kód van a BME280 szenzorban:
    Arduino 1.8.2 felület alatt MySensors 2.1.1 library és a hardver konfig pedig a MySensors AVR boards. Abból a Sensebender micro 8Mhz-es bootloader van beégetve. Ezt telepíteni az Arduino IDE-n:
    Tools - Board - Boards Manager ott megkeresed a MySensors AVR boards by MySensors-t Nekem most az 1.0.1 van telepítve. Aztán ki tudod választani a hardverek között a Sensebender boardot. Bootloader feltölt, és mehet rá soroson a sketch. Bootloaderhez viszont kell valami ISP-s kütyü amivel feltöltöd. Én USBASP-t használok.

    /**
    * The MySensors Arduino library handles the wireless radio link and protocol
    * between your home built sensors/actuators and HA controller of choice.
    * The sensors forms a self healing radio network with optional repeaters. Each
    * repeater and gateway builds a routing tables in EEPROM which keeps track of the
    * network topology allowing messages to be routed to nodes.
    *
    * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
    * Copyright (C) 2013-2015 Sensnology AB
    * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
    *
    * Documentation: http://www.mysensors.org
    * Support Forum: http://forum.mysensors.org
    *
    * This program is free software; you can redistribute it and/or
    * modify it under the terms of the GNU General Public License
    * version 2 as published by the Free Software Foundation.
    *
    *******************************
    *
    * REVISION HISTORY
    * Version 1.0 - Henrik Ekblad
    *
    * DESCRIPTION
    * Pressure sensor example using BMP085 module
    * http://www.mysensors.org/build/pressure
    *
    */

    // Enable debug prints to serial monitor
    #define MY_DEBUG
    #define MY_NODE_ID 32
    #define MY_RF24_PA_LEVEL RF24_PA_LOW

    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    #define MY_RF24_CE_PIN 9
    #define MY_RF24_CS_PIN 10
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    #define MY_RADIO_NRF24

    #include <SPI.h>
    #include <MySensor.h>
    #include <Wire.h>

    // BME280 libraries and variables
    // Bosch BME280 Embedded Adventures MOD-1022 weather multi-sensor Arduino code
    // Written originally by Embedded Adventures
    // https://github.com/embeddedadventures/BME280
    #include <BME280_MOD-1022.h>

    #define BARO_CHILD 0
    #define TEMP_CHILD 1
    #define HUM_CHILD 2

    const float ALTITUDE = 23; // <-- adapt this value to your location's altitude (in m). Use your smartphone GPS to get an accurate value!

    // Sleep time between reads (in ms). Do not change this value as the forecast algorithm needs a sample every minute.
    const unsigned long SLEEP_TIME = 60000;

    const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
    enum FORECAST
    {
    STABLE = 0, // "Stable Weather Pattern"
    SUNNY = 1, // "Slowly rising Good Weather", "Clear/Sunny "
    CLOUDY = 2, // "Slowly falling L-Pressure ", "Cloudy/Rain "
    UNSTABLE = 3, // "Quickly rising H-Press", "Not Stable"
    THUNDERSTORM = 4, // "Quickly falling L-Press", "Thunderstorm"
    UNKNOWN = 5 // "Unknown (More Time needed)
    };

    float lastPressure = -1;
    float lastTemp = -1;
    float lastHum = -1;
    int lastForecast = -1;

    const int LAST_SAMPLES_COUNT = 5;
    float lastPressureSamples[LAST_SAMPLES_COUNT];


    // this CONVERSION_FACTOR is used to convert from Pa to kPa in the forecast algorithm
    // get kPa/h by dividing hPa by 10
    #define CONVERSION_FACTOR (1.0/10.0)

    int minuteCount = 0;
    bool firstRound = true;
    // average value is used in forecast algorithm.
    float pressureAvg;
    // average after 2 hours is used as reference value for the next iteration.
    float pressureAvg2;

    float dP_dt;
    boolean metric;
    MyMessage tempMsg(TEMP_CHILD, V_TEMP);
    MyMessage humMsg(HUM_CHILD, V_HUM);
    MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
    MyMessage forecastMsg(BARO_CHILD, V_FORECAST);


    float getLastPressureSamplesAverage()
    {
    float lastPressureSamplesAverage = 0;
    for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
    {
    lastPressureSamplesAverage += lastPressureSamples[i];
    }
    lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;

    return lastPressureSamplesAverage;
    }


    // Algorithm found here
    // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
    // Pressure in hPa --> forecast done by calculating kPa/h
    int sample(float pressure)
    {
    // Calculate the average of the last n minutes.
    int index = minuteCount % LAST_SAMPLES_COUNT;
    lastPressureSamples[index] = pressure;

    minuteCount++;
    if (minuteCount > 185)
    {
    minuteCount = 6;
    }

    if (minuteCount == 5)
    {
    pressureAvg = getLastPressureSamplesAverage();
    }
    else if (minuteCount == 35)
    {
    float lastPressureAvg = getLastPressureSamplesAverage();
    float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    if (firstRound) // first time initial 3 hour
    {
    dP_dt = change * 2; // note this is for t = 0.5hour
    }
    else
    {
    dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
    }
    }
    else if (minuteCount == 65)
    {
    float lastPressureAvg = getLastPressureSamplesAverage();
    float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    if (firstRound) //first time initial 3 hour
    {
    dP_dt = change; //note this is for t = 1 hour
    }
    else
    {
    dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
    }
    }
    else if (minuteCount == 95)
    {
    float lastPressureAvg = getLastPressureSamplesAverage();
    float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    if (firstRound) // first time initial 3 hour
    {
    dP_dt = change / 1.5; // note this is for t = 1.5 hour
    }
    else
    {
    dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
    }
    }
    else if (minuteCount == 125)
    {
    float lastPressureAvg = getLastPressureSamplesAverage();
    pressureAvg2 = lastPressureAvg; // store for later use.
    float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    if (firstRound) // first time initial 3 hour
    {
    dP_dt = change / 2; // note this is for t = 2 hour
    }
    else
    {
    dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
    }
    }
    else if (minuteCount == 155)
    {
    float lastPressureAvg = getLastPressureSamplesAverage();
    float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    if (firstRound) // first time initial 3 hour
    {
    dP_dt = change / 2.5; // note this is for t = 2.5 hour
    }
    else
    {
    dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
    }
    }
    else if (minuteCount == 185)
    {
    float lastPressureAvg = getLastPressureSamplesAverage();
    float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
    if (firstRound) // first time initial 3 hour
    {
    dP_dt = change / 3; // note this is for t = 3 hour
    }
    else
    {
    dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
    }
    pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
    firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
    }

    int forecast = UNKNOWN;
    if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
    {
    forecast = UNKNOWN;
    }
    else if (dP_dt < (-0.25))
    {
    forecast = THUNDERSTORM;
    }
    else if (dP_dt > 0.25)
    {
    forecast = UNSTABLE;
    }
    else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
    {
    forecast = CLOUDY;
    }
    else if ((dP_dt > 0.05) && (dP_dt < 0.25))
    {
    forecast = SUNNY;
    }
    else if ((dP_dt >(-0.05)) && (dP_dt < 0.05))
    {
    forecast = STABLE;
    }
    else
    {
    forecast = UNKNOWN;
    }

    // uncomment when debugging
    //Serial.print(F("Forecast at minute "));
    //Serial.print(minuteCount);
    //Serial.print(F(" dP/dt = "));
    //Serial.print(dP_dt);
    //Serial.print(F("kPa/h --> "));
    //Serial.println(weather[forecast]);

    return forecast;
    }


    void setup() {
    metric = getConfig().isMetric;
    Wire.begin(); // Wire.begin(sda, scl)
    }

    void presentation() {
    // Send the sketch version information to the gateway and Controller
    sendSketchInfo("BME280 Sensor", "1.6");

    // Register sensors to gw (they will be created as child devices)
    present(BARO_CHILD, S_BARO);
    present(TEMP_CHILD, S_TEMP);
    present(HUM_CHILD, S_HUM);
    }

    // Loop
    void loop() {

    // need to read the NVM compensation parameters
    BME280.readCompensationParams();

    /* After taking the measurement the chip goes back to sleep, use when battery powered.
    // Oversampling settings (os1x, os2x, os4x, os8x or os16x).
    BME280.writeFilterCoefficient(fc_16); // IIR Filter coefficient, higher numbers avoid sudden changes to be accounted for (such as slamming a door)
    BME280.writeOversamplingPressure(os16x); // pressure x16
    BME280.writeOversamplingTemperature(os8x); // temperature x8
    BME280.writeOversamplingHumidity(os8x); // humidity x8

    BME280.writeMode(smForced); // Forced sample. After taking the measurement the chip goes back to sleep
    */

    // Normal mode for regular automatic samples
    BME280.writeStandbyTime(tsb_0p5ms); // tsb = 0.5ms
    BME280.writeFilterCoefficient(fc_16); // IIR Filter coefficient 16
    BME280.writeOversamplingPressure(os16x); // pressure x16
    BME280.writeOversamplingTemperature(os8x); // temperature x8
    BME280.writeOversamplingHumidity(os8x); // humidity x8

    BME280.writeMode(smNormal);

    while (1) {
    // Just to be sure, wait until sensor is done mesuring
    while (BME280.isMeasuring()) {
    }

    // Read out the data - must do this before calling the getxxxxx routines
    BME280.readMeasurements();

    float temperature = BME280.getTemperatureMostAccurate(); // must get temp first
    float humidity = BME280.getHumidityMostAccurate();
    float pressure_local = BME280.getPressureMostAccurate(); // Get pressure at current location
    float pressure = pressure_local/pow((1.0 - ( ALTITUDE / 44330.0 )), 5.255); // Adjust to sea level pressure using user altitude
    int forecast = sample(pressure);

    if (!metric)
    {
    // Convert to fahrenheit
    temperature = temperature * 9.0 / 5.0 + 32.0;
    }

    Serial.println();
    Serial.print("Temperature = ");
    Serial.print(temperature);
    Serial.println(metric ? " �C" : " �F");
    Serial.print("Humidity = ");
    Serial.print(humidity);
    Serial.println(" %");
    Serial.print("Pressure = ");
    Serial.print(pressure);
    Serial.println(" hPa");
    Serial.print("Forecast = ");
    Serial.println(weather[forecast]);
    Serial.println();


    if (temperature != lastTemp)
    {
    send(tempMsg.set(temperature, 1));
    lastTemp = temperature;
    }


    if (humidity != lastHum)
    {
    send(humMsg.set(humidity, 1));
    lastHum = humidity;
    }

    if (pressure != lastPressure)
    {
    send(pressureMsg.set(pressure, 2));
    lastPressure = pressure;
    }

    if (forecast != lastForecast)
    {
    send(forecastMsg.set(weather[forecast]));
    lastForecast = forecast;
    }

    sleep(SLEEP_TIME);

    }
    }

Új hozzászólás Aktív témák