Shaktale

*
Sol
Mensajes: 10
En línea
Hola ante todo. Me presento: Soy un estudiante de ciclo formativo de grado superior de electrónica y estamos ahora con el proyecto terminando el 2º año. El proyecto consiste en una estación meteorológica. Los sensores de los que disponemos son Barómetro, pluviómetro, piranómetro (global), termómetro e higrómetro, veleta y anemómetro.

La mayoría de las dudas hemos conseguido resolverlas buscando información, pero se nos había ocurrido: ¿podemos mostrar alguna ionformación más aparte de la información directa que proporcionan los sensores? como por ejemplo mostrar un icono del estado del cielo (si está despejado, nublado... etc). O lo que sea. básicamente lo que tenemos hasta ahora es poder mostrar en la web a tiempo real los datos, y que el usuario pueda realizar una consulta sobre "cuánto llovió el día tal..." o "gráfica de la radación solar del mes X", etc.

La cuestión era esa. Cualquier comentario será muy agradecido. Mientras intentaré buscar por la web que he visto información muy útil. Gracias!

Shaktale

*
Sol
Mensajes: 10
En línea
se me olvidaba decir que soy de Cantabria y la estación va a estar situada en Peñacastillo, en el Centro Integrado de Formación Profesional.

CHINCHU

Kaniki
**
Cumulus Húmilis
Mensajes: 274
www.meteoalmargen.es
  1. draconian1983@hotmail.com
Ubicación: Almargen (Málaga)
En línea
Muy buenas compàñero. interesante proyecto el tuyo. No te puedo ayudar en el aspecto tecnico, pero te recomiendo que hables con "Frentefrio", el tiene su estacion en Ojáiz-Peñacastillo, asi que creo que te puede ser util, al menos en el aspecto tecnico de los aparatos. Saludos, y ya nos cuentas que tal.
Observatorio Termo-Pluviométrico colaborador con AEMET num. 6112-C. Termos Máx-Min Oficial; Psicrómetro Oficial; MicroBarógrafo Oficial AEMET Thies Clima; TH Lambrecht 82TH, Evaporímetro Piché, Hellmann 200; Davis VP2

Shaktale

*
Sol
Mensajes: 10
En línea
muy bien, intentaré contactar con él. para la comprobación de la recogida de datos de algunos sensores hemos comparado con la estación de Ojaiz porque nos queda aquí al lado.

El proyecto tiene que estar en la red para dentro de dos semanas así que no queda nada. Ya pondré el link por aquí para que la gente eche un vistazo. a ver que tal queda jeje. gracias!

FRENTEFRIO

*****
Cb Incus
Mensajes: 4,980
Ojáiz-Peñacastillo (Cantabria)
  1. ojaizmet@hotmail.com
En línea
Buenos dias.
Bienvenido, paisano.
Casi por casualidad he topado con este tópic.
Si te puedo ayudar en algo, sobre todo en el aspecto de instalación...ya sabes. Yo de electrónica estoy "pez"... ;)



Estación Meteorológica de Ojáiz-Peñacastillo (Cantabria) Página web: OJAIZMETEO
DETECTOR DE RAYOS
                                                   Vigilando el tiempo

Vaqueret di Rondó

un Zarathustra insidioso
******
Supercélula
Mensajes: 5,077
Eppur si calfa....
Ubicación: Castalla, Casco urbano 695 msnm
En línea
Bueno, en cuanto a la capacidad de consulta, basta con ir metiendo los datos en una base de datos SQL.

Y, si lo que te hace falta es la forma de calcular otras vaiables, igual ésto te sirve (està en Pascal que es lo que suelo utilizar:

unit UWUtils;
{
    Notes about pressure
      Sensor Pressure           raw pressure indicated by the barometer instrument
      Station Pressure          Sensor Pressure adjusted for any difference between sensor elevation and official station elevation
      Field Pressure     (QFE)  Usually the same as Station Pressure
      Altimeter Setting  (QNH)  Station Pressure adjusted for elevation (assumes standard atmosphere)
      Sea Level Pressure (QFF)  Station Pressure adjusted for elevation, temperature and humidity

    Notes about input parameters:
      currentTemp -   current instantaneous station temperature
      meanTemp -      average of current temp and the temperature 12 hours in
                      the past. If the 12 hour temp is not known, simply pass
                      the same value as currentTemp for the mean temp.
      humidity -      Value should be 0 to 100. For the pressure conversion
                      functions, pass a value of zero if you do not want to
                      the algorithm to include the humidity correction factor
                      in the calculation. If you provide a humidity value
                      > 0, then humidity effect will be included in the
                      calculation.
     elevation -     This should be the geometric altitude of the station
                      (this is the elevation provided by surveys and normally
                      used by people when they speak of elevation). Some
                      algorithms will convert the elevation internally into
                      a geopotential altitude.
      sensorElevation - This should be the geometric altitude of the actual
                      barometric sensor (which could be different than the
                      official station elevation).

    Notes about Sensor Pressure vs. Station Pressure:
      SensorToStationPressure and StationToSensorPressure functions are based
      on an ASOS algorithm. It corrects for a difference in elevation between
      the official station location and the location of the barometetric sensor.
      It turns out that if the elevation difference is under 30 ft, then the
      algorithm will give the same result (a 0 to .01 inHg adjustment) regardless
      of temperature. In that case, the difference can be covered using a simple
      fixed offset. If the difference is 30 ft or greater, there is some effect
      from temperature, though it is small. For example, at a 100ft difference,
      the adjustment will be .13 inHg at -30F and .10 at 100F. The bottom line
      is that while ASOS stations may do this calculation, it is likely unneeded
      for home weather stations, and the station pressure and the sensor pressure
      can be treated as equivalent.
    **********************************************}
    interface

    type
    // by changing this you can change the precision of the floating point calculations
      TWxReal = double;
      TWxHumidity = single; // humidities expressed as integer percentage, i.e. 88 = 88%

    // formulas/algorithms
      // Sea Level Pressure reduction algorithms
      TSLPAlgorithm = (
        paDavisVP,  // algorithm closely approximates SLP calculation used inside Davis Vantage Pro weather equipment console (http://www.davisnet.com/weather/)
        paUnivie,   // http://www.univie.ac.at/IMG-Wien/daquamap/Parametergencom.html
        paManBar    // from Manual of Barometry (1963)
        );

      // Altimeter algorithms
      TAltimeterAlgorithm = (
        aaASOS,     // formula described in the ASOS training docs
        aaASOS2,    // metric formula that was likely used to derive the aaASOS formula
        aaMADIS,    // apparently the formula used by the MADIS system
        aaNOAA,     // essentially the same as aaSMT with any result differences caused by unit conversion rounding error and geometric vs. geopotential elevation
        aaWOB,      // Weather Observation Handbook (algorithm similar to aaASOS & aaASOS2 - main differences being precision of constants used)
        aaSMT       // Smithsonian Meteorological Tables (1963)
        );

      TVapAlgorithm = (
        vaDavisVp,  // algorithm closely approximates calculation used by Davis Vantage Pro weather stations and software
        vaBuck,     // this and the remaining algorithms described at http://cires.colorado.edu/~voemel/vp.html
        vaBuck81,
        vaBolton,
        vaTetenNWS,
        vaTetenMurray,
        vaTeten
        );

    const
      DefaultSLPAlgorithm = paManBar;
      DefaultAltimeterAlgorithm = aaMADIS;
      DefaultVapAlgorithm = vaBolton;

    type
      TWUtils = class(TObject)
      private
      public
        // basic pressure functions - all take metric params (hectoPascals(hPa), celsius, meters)
        class function StationToSensorPressure(pressureHPa: TWxReal;
                            sensorElevationM: TWxReal; stationElevationM: TWxReal;
                            currentTempC: TWxReal): TWxReal;
        class function StationToAltimeter(pressureHPa: TWxReal; elevationM: TWxReal;
                            algorithm: TAltimeterAlgorithm = DefaultAltimeterAlgorithm): TWxReal;
        class function StationToSeaLevelPressure(pressureHPa: TWxReal; elevationM: TWxReal;
                            currentTempC: TWxReal; meanTempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TSLPAlgorithm = DefaultSLPAlgorithm): TWxReal;
        class function SensorToStationPressure(pressureHPa: TWxReal;
                            sensorElevationM: TWxReal; stationElevationM: TWxReal;
                            currentTempC: TWxReal): TWxReal;
     //   class function AltimeterToStationPressure(pressureHPa: TWxReal; elevationM: TWxReal;
     //                       algorithm: TAltimeterAlgorithm = DefaultAltimeterAlgorithm): TWxReal;
        class function SeaLevelToStationPressure(pressureHPa: TWxReal; elevationM: TWxReal;
                            currentTempC: TWxReal; meanTempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TSLPAlgorithm = DefaultSLPAlgorithm): TWxReal;
        // low level pressure related functions
        class function PressureReductionRatio(pressureHPa: TWxReal; elevationM: TWxReal;
                            currentTempC: TWxReal; meanTempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TSLPAlgorithm = DefaultSLPAlgorithm): TWxReal;
        class function ActualVaporPressure(tempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TVapAlgorithm = DefaultVapAlgorithm): TWxReal;
        class function SaturationVaporPressure(tempC: TWxReal;
                            algorithm: TVapAlgorithm = DefaultVapAlgorithm): TWxReal;
        class function MixingRatio(pressureHPa: TWxReal; tempC: TWxReal; humidity: TWxHumidity): TWxReal;
        class function VirtualTempK(pressureHPa: TWxReal; tempC: TWxReal; humidity: TWxHumidity): TWxReal;
        class function HumidityCorrection(tempC: TWxReal; elevationM: TWxReal; humidity: TWxHumidity;
                            algorithm: TVapAlgorithm = DefaultVapAlgorithm): TWxReal;

        // temperature related functions
        class function DewPoint(tempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TVapAlgorithm = DefaultVapAlgorithm): TWxReal;
        class function WindChill(tempC: TWxReal; windSpeedKmph: TWxReal): TWxReal;
        class function HeatIndex(tempC: TWxReal; humidity: TWxHumidity): TWxReal;
        class function Humidex(tempC: TWxReal; humidity: TWxHumidity): TWxReal;
        // simplified algorithm for geopotential altitude from US Standard Atmosphere 1976
        // assumes latitude 45.5 degrees
        class function GeopotentialAltitude(geometricAltitudeM: TWxReal): TWxReal;

        // basic unit conversion functions
        class function FToC(value: TWxReal): TWxReal;       // Fahrenheit to Celsius
        class function CToF(value: TWxReal): TWxReal;       // Celsius to Fahrenheit
        class function CToK(value: TWxReal): TWxReal;       // Celsius to Kelvin
        class function KToC(value: TWxReal): TWxReal;       // Kelvin to Celsius
        class function FToR(value: TWxReal): TWxReal;       // Fahrenheit to Rankine
        class function RToF(value: TWxReal): TWxReal;       // Rankine to Fahrenheit
        class function InToHPa(value: TWxReal): TWxReal;    // Inches Mercury to HectoPascals/millibars
        class function HPaToIn(value: TWxReal): TWxReal;    // HectoPascals/millibars to Inches Mercury
        class function FtToM(value: TWxReal): TWxReal;      // Feet to Meters
        class function MToFt(value: TWxReal): TWxReal;      // Meters to Feet
        class function InToMm(value: TWxReal): TWxReal;     // Inches to Millimeters
        class function MmToIn(value: TWxReal): TWxReal;     // Millimeters to Inches
        class function MToKm(value: TWxReal): TWxReal;      // Miles to Kilometers
        class function KmToM(value: TWxReal): TWxReal;      // Kilometers to Miles

        // general math functions
        class function Power(const Base, Exponent: TWxReal): TWxReal;
        class function Power10(const exponent: TWxReal): TWxReal;
      end;

    implementation

    const
    // U.S. Standard Atmosphere (1976) constants
      gravity = 9.80665;          // g at sea level at latitude 45.5 degrees in m/sec^2
      uGC = 8.31432;              // universal gas constant in J/mole-K
      moleAir = 0.0289644;        // mean molecular mass of air in kg/mole
      moleWater = 0.01801528;     // molecular weight of water in kg/mole
      gasConstantAir = uGC/moleAir; // (287.053) gas constant for air in J/kgK
      standardSLP = 1013.25;      // standard sea level pressure in hPa
      standardSlpInHg = 29.921;   // standard sea level pressure in inHg
      standardTempK = 288.15;     // standard sea level temperature in Kelvin
      earthRadius45 = 6356.766;   // radius of the earth at latitude 45.5 degrees in km

      standardLapseRate = 0.0065; // standard lapse rate (6.5C/1000m i.e. 6.5K/1000m)

      standardLapseRateFt = standardLapseRate * 0.3048; // (0.0019812) standard lapse rate per foot (1.98C/1000ft)
      vpLapseRateUS = 0.00275;    // lapse rate used by Davis VantagePro (2.75F/1000ft)
      manBarLapseRate = 0.0117;   // lapse rate from Manual of Barometry (11.7F/1000m, which = 6.5C/1000m)

    class function TWUtils.StationToSensorPressure(pressureHPa: TWxReal;
                            sensorElevationM: TWxReal; stationElevationM: TWxReal;
                            currentTempC: TWxReal): TWxReal;
    begin
      // from ASOS formula specified in US units
      Result := InToHPa(HPaToIn(pressureHPa) / Power10(0.00813 * MToFt(sensorElevationM - stationElevationM)
                                           / FToR(CToF(currentTempC))));
    end;

    class function TWUtils.StationToAltimeter(PressureHPa: TWxReal; elevationM: TWxReal;
                            algorithm: TAltimeterAlgorithm = DefaultAltimeterAlgorithm): TWxReal;
    var
      geopEl: TWxReal;
      k1, k2: TWxReal;
    begin
      case algorithm of
        aaASOS:
          // see ASOS training at http://www.nwstc.noaa.gov
          // see also http://wahiduddin.net/calc/density_altitude.htm
          begin
            Result := InToHPa(Power(Power(HPaToIn(pressureHPa), 0.1903) + (1.313E-5 * MToFt(elevationM)), 5.255));
          end;
        aaASOS2:
          begin
            geopEl := GeopotentialAltitude(elevationM);
            k1 := standardLapseRate * gasConstantAir / gravity; // approx. 0.190263
            k2 := 8.41728638E-5; // (standardLapseRate / standardTempK) * (Power(standardSLP,  k1)
            Result := Power(Power(pressureHPa, k1) + (k2 * geopEl), 1/k1);
          end;
        aaMADIS:
          // from MADIS API by NOAA Forecast Systems Lab, see http://madis.noaa.gov/madis_api.html
          begin
            k1 := 0.190284; // discrepency with calculated k1 probably because Smithsonian used less precise gas constant and gravity values
            k2 := 8.4184960528E-5; // (standardLapseRate / standardTempK) * (Power(standardSLP, k1)
            Result := Power(Power(pressureHPa - 0.3, k1) + (k2 * elevationM), 1/k1);
          end;
        aaNOAA:
          // see http://www.srh.noaa.gov/elp/wxcalc/formulas/altimeterSetting.html
          begin
            k1 := 0.190284; // discrepency with k1 probably because Smithsonian used less precise gas constant and gravity values
            k2 := 8.42288069E-5; // (standardLapseRate / 288) * (Power(standardSLP, k1SMT);
            Result := (pressureHPa - 0.3) * Power(1 + (k2 * (elevationM / Power(pressureHPa - 0.3, k1))), 1/k1);
          end;
        aaWOB:
          // see http://www.wxqa.com/archive/obsman.pdf
          begin
            k1 := standardLapseRate * gasConstantAir / gravity; // approx. 0.190263
            k2 := 1.312603E-5; //(standardLapseRateFt / standardTempK) * Power(standardSlpInHg, k1);
            Result := InToHPa(Power(Power(HPaToIn(pressureHPa), k1) + (k2 * MToFt(elevationM)), 1/k1));
          end;
        aaSMT:
          // see WMO Instruments and Observing Methods Report No.19 at http://www.wmo.int/pages/prog/www/IMOP/publications/IOM-19-Synoptic-AWS.pdf
          begin
            k1 := 0.190284; // discrepency with calculated value probably because Smithsonian used less precise gas constant and gravity values
            k2 := 4.30899E-5; // (standardLapseRate / 288) * (Power(standardSlpInHg, k1SMT));
            geopEl := GeopotentialAltitude(elevationM);
            Result := InToHPa((HPaToIn(pressureHPa) - 0.01)
                      * Power(1 + (k2 * (geopEl / Power(HPaToIn(pressureHPa) - 0.01, k1))), 1/k1));
          end;
        else Result := pressureHPa; // unknown algorithm
      end;
    end;

    class function TWUtils.StationToSeaLevelPressure(pressureHPa: TWxReal; elevationM: TWxReal;
                            currentTempC: TWxReal; meanTempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TSLPAlgorithm = DefaultSLPAlgorithm): TWxReal;
    begin
      Result := pressureHPa * PressureReductionRatio(pressureHPa, elevationM, currentTempC,
                                                    meanTempC, humidity, algorithm);
    end;

    class function TWUtils.SensorToStationPressure(pressureHPa: TWxReal;
                               sensorElevationM: TWxReal; stationElevationM: TWxReal;
                               currentTempC: TWxReal): TWxReal;
    // see ASOS training at http://www.nwstc.noaa.gov
    begin
      // from US units ASOS formula
      Result := InToHPa(HPaToIn(pressureHPa) * Power10(0.00813 * MToFt(sensorElevationM - stationElevationM)
                                           / FToR(CToF(currentTempC))));
    end;
    {
    // still to do
    class function TWxUtils.AltimeterToStationPressure(pressureHPa: TWxReal; elevationM: TWxReal;
                            algorithm: TAltimeterAlgorithm = DefaultAltimeterAlgorithm): TWxReal;
    begin
    end;
    }
    class function TWUtils.SeaLevelToStationPressure(pressureHPa: TWxReal; elevationM: TWxReal;
                            currentTempC: TWxReal; meanTempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TSLPAlgorithm = DefaultSLPAlgorithm): TWxReal;
    begin
      Result := pressureHPa / PressureReductionRatio(pressureHPa, elevationM, currentTempC,
                                                    meanTempC, humidity, algorithm);
    end;

    class function TWUtils.PressureReductionRatio(pressureHPa: TWxReal; elevationM: TWxReal;
                            currentTempC: TWxReal; meanTempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TSLPAlgorithm = DefaultSLPAlgorithm): TWxReal;
    var
      geopElevationM: TWxReal;
      hCorr: TWxReal;
    begin
      case algorithm of
        paUnivie:
          //  see http://www.univie.ac.at/IMG-Wien/daquamap/Parametergencom.html
          begin
            geopElevationM := GeopotentialAltitude(elevationM);
            Result := Exp(((gravity/gasConstantAir) * geopElevationM)
               / (VirtualTempK(pressureHPa, meanTempC, humidity) + (geopElevationM * standardLapseRate/2)));
          end;
        paDavisVp:
          // see http://www.exploratorium.edu/weather/barometer.html
          begin
            if (humidity > 0) then begin
              hCorr := (9/5) * HumidityCorrection(currentTempC, elevationM, humidity, vaDavisVP);
            end else begin
              hCorr := 0;
            end;
            // In the case of DavisVp, take the constant values literally.
            Result := Power(10, (MToFt(elevationM) / (122.8943111 * (CToF(meanTempC) + 460 + (MToFt(elevationM) * vpLapseRateUS/2) + hCorr))));
          end;
        paManBar:
          // see WMO Instruments and Observing Methods Report No.19 at http://www.wmo.int/pages/prog/www/IMOP/publications/IOM-19-Synoptic-AWS.pdf
          begin
            if (humidity > 0) then begin
              hCorr := (9/5) * HumidityCorrection(currentTempC, elevationM, humidity, vaBuck);
            end else begin
              hCorr := 0;
            end;
            geopElevationM := GeopotentialAltitude(elevationM);
            Result := Exp(geopElevationM * 6.1454E-2 / (CToF(meanTempC) + 459.7 + (geopElevationM * manBarLapseRate / 2) + hCorr));
          end;
        else Result := 1; // unknown algorithm
      end;
    end;

    class function TWUtils.ActualVaporPressure(tempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TVapAlgorithm = DefaultVapAlgorithm): TWxReal;
    begin
      result := (humidity * SaturationVaporPressure(tempC, algorithm)) / 100;
    end;

    class function TWUtils.SaturationVaporPressure(tempC: TWxReal;
                            algorithm: TVapAlgorithm = DefaultVapAlgorithm): TWxReal;
    begin
      // see http://cires.colorado.edu/~voemel/vp.html   comparison of vapor pressure algorithms
      // see (for DavisVP) http://www.exploratorium.edu/weather/dewpoint.html
      case algorithm of
        vaDavisVp: Result := 6.112 * Exp((17.62 * tempC)/(243.12 + tempC)); // Davis Calculations Doc
        vaBuck: Result := 6.1121 * Exp((18.678 - (tempC/234.5)) * tempC / (257.14 + tempC)); // Buck(1996)
        vaBuck81: Result := 6.1121 * Exp((17.502 * tempC)/(240.97 + tempC)); // Buck(1981)
        vaBolton: Result := 6.112 * Exp(17.67 * tempC / (tempC + 243.5)); // Bolton(1980)
        vaTetenNWS: Result := 6.112 * Power(10,(7.5 * tempC / (tempC + 237.7))); // Magnus Teten see www.srh.weather.gov/elp/wxcalc/formulas/vaporPressure.html
        vaTetenMurray: Result := Power(10, (7.5 * tempC / (237.5 + tempC)) + 0.7858); // Magnus Teten (Murray 1967)
        vaTeten: Result := 6.1078 * Power(10, (7.5 * tempC / (tempC + 237.3))); // Magnus Teten see www.vivoscuola.it/US/RSIGPP3202/umidita/attivita/relhumONA.htm
        else Result := 0; // unknown algorithm
      end;
    end;

    class function TWUtils.MixingRatio(pressureHPa: TWxReal; tempC: TWxReal;
                        humidity: TWxHumidity): TWxReal;
    var
      vapPres: TWxReal;
    const
      k1 = moleWater / moleAir; // 0.62198
    begin
      // see http://www.wxqa.com/archive/obsman.pdf
      // see also http://www.vivoscuola.it/US/RSIGPP3202/umidita/attivita/relhumONA.htm
      vapPres := ActualVaporPressure(tempC, humidity, vaBuck);
      Result := 1000 * ((k1 * vapPres) / (pressureHPa - vapPres));
    end;

    class function TWUtils.VirtualTempK(pressureHPa: TWxReal; tempC: TWxReal;
                                   humidity: TWxHumidity): TWxReal;
    var
      vapPres: TWxReal;
    const
      epsilon = 1 - (moleWater / moleAir); // 0.37802
    begin
      // see http://www.univie.ac.at/IMG-Wien/daquamap/Parametergencom.html
      // see also http://www.vivoscuola.it/US/RSIGPP3202/umidita/attivita/relhumONA.htm
      // see also http://wahiduddin.net/calc/density_altitude.htm
      vapPres := ActualVaporPressure(tempC, humidity, vaBuck);
      Result := (CtoK(tempC)) / (1-(epsilon * (vapPres/pressureHPa)));
    end;

    class function TWUtils.HumidityCorrection(tempC: TWxReal; elevationM: TWxReal; humidity: TWxHumidity;
                            algorithm: TVapAlgorithm = DefaultVapAlgorithm): TWxReal;
    var
      vapPress: TWxReal;
    begin
      vapPress := ActualVaporPressure(tempC, humidity, algorithm);
      Result := (vappress * ((2.8322E-9 * Sqr(elevationM)) + (2.225E-5 * elevationM) + 0.10743));
    end;

    class function TWUtils.DewPoint(tempC: TWxReal; humidity: TWxHumidity;
                            algorithm: TVapAlgorithm = DefaultVapAlgorithm): TWxReal;
    var
      lnVapor: TWxReal;
    begin
      lnVapor := Ln(ActualVaporPressure(tempc, humidity, algorithm));
      case algorithm of
        vaDavisVp: Result := ((243.12 * LnVapor) - 440.1) / (19.43 - LnVapor);
      else
        Result := ((237.7 * LnVapor) - 430.22) / (19.08 - LnVapor);
      end;
    end;

    class function TWUtils.WindChill(tempC: TWxReal; windSpeedKmph: TWxReal): TWxReal;
// see American Meteorological Society Journal
// see http://www.msc.ec.gc.ca/education/windchill/science_equations_e.cfm
// see http://www.weather.gov/os/windchill/index.shtml
    var
      windPow: TWxReal;
    begin
      if ((tempC >= 10.0) or (windSpeedKmph <= 4.8)) then begin
        Result := tempC;
      end else begin
        windPow := Power(windSpeedKmph, 0.16);
        Result := 13.12 + (0.6215 * tempC) - (11.37 * windPow) + (0.3965 * tempC * windPow);
      end;
      if (Result > tempC) then Result := tempC;
    end;

    class function TWUtils.HeatIndex(tempC: TWxReal; humidity: TWxHumidity): TWxReal;
    // see http://www.hpc.ncep.noaa.gov/heat_index/hi_equation.html
    var
      tempF: TWxReal;
      tSqrd: TWxReal;
      hum: TWxReal;
      hSqrd: TWxReal;
    begin
      tempF := CToF(tempC);
      if (tempF < 80) then begin
        // heat index algorithm is only valid for temps above 80F
        Result := tempF;
      end else begin
        tSqrd := tempF * tempF;
        hum := humidity;
        hSqrd := hum * hum;
        Result := 0 - 42.379 + (2.04901523 * tempF) + (10.14333127 * humidity)
                  - (0.22475541 * tempF * humidity) - (0.00683783 * tSqrd)
                  - (0.05481717 * hSqrd) + (0.00122874 * tSqrd * humidity)
                  + (0.00085282 * tempF * hSqrd) - (0.00000199 * tSqrd * hSqrd);
        // Rothfusz adjustments
        if ((humidity < 13) and (tempF >= 80) and (tempF <= 112)) then begin
          Result := Result - ((13 - humidity)/4) * Sqrt((17 - Abs(tempf - 95))/17);
        end else if ((humidity > 85) and (tempF >= 80) and (tempF <= 87)) then begin
          Result := Result + ((humidity - 85)/10) * ((87 - tempF)/5);
        end;
      end;
      Result := FToC(Result);
    end;

    class function TWUtils.Humidex(tempC: TWxReal; humidity: TWxHumidity): TWxReal;
    begin
      Result := tempC + ((5/9) * (ActualVaporPressure(tempC, humidity, vaTetenNWS) - 10.0));
    end;

    class function TWUtils.GeopotentialAltitude(geometricAltitudeM: TWxReal): TWxReal;
    begin
      Result := (earthRadius45 * 1000 * geometricAltitudeM) / ((earthRadius45 * 1000) + geometricAltitudeM);
    end;

    //************** Conversion Functions ******************

    class function TWUtils.FtoC(value: TWxReal): TWxReal;
    begin
      Result := ((value - 32) * 5) / 9;
    end;

    class function TWUtils.CtoF(value: TWxReal): TWxReal;
    begin
      Result :=  ((value * 9) / 5) + 32;
    end;

    class function TWUtils.CtoK(value: TWxReal): TWxReal;
    begin
      Result := 273.15 + value;
    end;

    class function TWUtils.KtoC(value: TWxReal): TWxReal;
    begin
      Result := value - 273.15;
    end;

    class function TWUtils.FToR(value: TWxReal): TWxReal;
    begin
      Result := value + 459.67;
    end;

    class function TWUtils.RToF(value: TWxReal): TWxReal;
    begin
      Result := value - 459.67;
    end;

    class function TWUtils.InToHPa(value: TWxReal): TWxReal;
    begin
      Result := value / 0.02953;
    end;

    class function TWUtils.HPaToIn(value: TWxReal): TWxReal;
    begin
      Result := value * 0.02953;
    end;

    class function TWUtils.FtToM(value: TWxReal): TWxReal;
    begin
      Result := value * 0.3048;
    end;

    class function TWUtils.MToFt(value: TWxReal): TWxReal;
    begin
      Result := value / 0.3048;
    end;

    class function TWUtils.InToMm(value: TWxReal): TWxReal;
    begin
      Result := value * 25.4;
    end;

    class function TWUtils.MmToIn(value: TWxReal): TWxReal;
    begin
      Result := value / 25.4;
    end;

    class function TWUtils.MToKm(value: TWxReal): TWxReal;
    begin
      Result := value * 1.609344;
    end;

    class function TWUtils.KmToM(value: TWxReal): TWxReal;
    begin
      Result := value / 1.609344;
    end;

    //************* General Math Functions ****************

    // raise base to the given power (i.e. base**exponent
    class function TWUtils.Power(const base, exponent: TWxReal): TWxReal;
    begin
      if exponent = 0.0 then begin
        Result := 1.0; // n**0 = 1
      end else if (base = 0.0) and (exponent > 0.0) then begin
        Result := 0.0; // 0**n = 0, n > 0
      end else begin
        Result := Exp(exponent * Ln(base));
      end;
    end;

    class function TWUtils.Power10(const exponent: TWxReal): TWxReal;
    const
      ln10 = 2.302585093; // Ln(10);
    begin
      if (exponent = 0.0) then begin
        Result := 1.0;
      end else begin
        Result := Exp(exponent * ln10);
      end;
    end;
    end.
   

Shaktale

*
Sol
Mensajes: 10
En línea
Cita de: FRENTEFRIO en Martes 17 Marzo 2009 11:42:46 AM
Buenos dias.
Bienvenido, paisano.
Casi por casualidad he topado con este tópic.
Si te puedo ayudar en algo, sobre todo en el aspecto de instalación...ya sabes. Yo de electrónica estoy "pez"... ;)




muy buenas. al final nos hemos acercado a la Agencia Estatal de Meteorología, y con eso y la ayuda de un profesor del centro que está estudiando algo de meteorología hemos resuelto practicamente todas las dudas.

La parte electrónica no es problema puesto que los sensores transforman el dato a una escala lineal de corriente así que es muy sencillo calcularlo, y la programación no es complicada.

La parte de instalación ya tenemos las alturas y colocaciones de los sensores: temperatura a 2m. del suelo, anemómetro y veleta a 10 metros... etc.

Y también nos comentaron en la Agencia que para poder asegurar que el cielo está despejado o cubierto solamente con un piranómetro global, una posible forma sería tener un modelo de esa época del año y compararlo. algo así como comparar con un día totalmente despejado de esa época. pero claro para eso tenemos que dejar funcionando la estación un año entero jejej. Nos comentaron que sino necesitaríamos de un heliómetro (del que no disponemos).

y eso es todo de momento.gracias por vuestro interés, si nos sale alguna dudilla más ya os comentaremos ::)
ah y se aceptan sugerencias para la web. me refiero a si alguna vez habéis dicho "ah pues qué bien estaría que la página me mostrara además esto o esto", porque no tenemos ni idea de si hay otros datos (que seguro que sí) de interés, aparte de los que directamente ofrecen los sensores. gracias de nuevo  ;)






FRENTEFRIO

*****
Cb Incus
Mensajes: 4,980
Ojáiz-Peñacastillo (Cantabria)
  1. ojaizmet@hotmail.com
En línea
#7
Cita de: Shaktale en Martes 17 Marzo 2009 15:06:14 PM
Cita de: FRENTEFRIO en Martes 17 Marzo 2009 11:42:46 AM
Buenos dias.
Bienvenido, paisano.
Casi por casualidad he topado con este tópic.
Si te puedo ayudar en algo, sobre todo en el aspecto de instalación...ya sabes. Yo de electrónica estoy "pez"... ;)




muy buenas. al final nos hemos acercado a la Agencia Estatal de Meteorología, y con eso y la ayuda de un profesor del centro que está estudiando algo de meteorología hemos resuelto practicamente todas las dudas.

La parte electrónica no es problema puesto que los sensores transforman el dato a una escala lineal de corriente así que es muy sencillo calcularlo, y la programación no es complicada.

La parte de instalación ya tenemos las alturas y colocaciones de los sensores: temperatura a 2m. del suelo, anemómetro y veleta a 10 metros... etc.

Y también nos comentaron en la Agencia que para poder asegurar que el cielo está despejado o cubierto solamente con un piranómetro global, una posible forma sería tener un modelo de esa época del año y compararlo. algo así como comparar con un día totalmente despejado de esa época. pero claro para eso tenemos que dejar funcionando la estación un año entero jejej. Nos comentaron que sino necesitaríamos de un heliómetro (del que no disponemos).

y eso es todo de momento.gracias por vuestro interés, si nos sale alguna dudilla más ya os comentaremos ::)
ah y se aceptan sugerencias para la web. me refiero a si alguna vez habéis dicho "ah pues qué bien estaría que la página me mostrara además esto o esto", porque no tenemos ni idea de si hay otros datos (que seguro que sí) de interés, aparte de los que directamente ofrecen los sensores. gracias de nuevo  ;)







Saludos de nuevo.

Esa altura no es la correcta; los termómetros tienen que estar colocados dentro de una garita protectora (sin protección pueden volverse locos) y a 1,20 metros del suelo que sea de césped (hierba corta)

Para el tema de la nubosidad, hay en el comercio algunos sensores que a lo mejor los puedes integrar dentro de vuestra estación. Uno de los más conocidos (y baratos, dentro de lo que cabe) es el CloudWatcher. Aquí te dejo un enlace a las gráficas que genera el sensor (el horario está en UTC  ...una hora menos que la oficial):

http://www.ojaizmeteo.net/AAG_ImageCloudCondition.png

Será mejor tener un "cacharro" de estos (que es bastante fiable) a un piranómetro. La calidad entre uno y otro salta a la vista, pero en cuestión de soltar euros...no hay color.

Lo que os comentaron en la Delegación de AEMET en Cantabria, es correcto, pero con algunas puntualizaciones: Un Helógrafo (o heliómetro) mide las horas de sol. Se utiliza casi exclusivamente para eso. Por supuesto, que cuando hay nubes, el aparato no deja ningún registro, pero es más difícil de cuantificar las horas de nubes. Por ejemplo: En un dia con cielo cubierto de Cirroestratos, el sol puede pasar a través de ésas nubes que son muy finas, pero el cielo (en teoría) estará cubierto. Ese día no podría contabilizarse como dia de cielo despejado (por que no ha sido así) y sin embargo el heliógrafo sí puede haber dado registros de horas de sol.

El cloudwather sí que determina si en el cielo hay nubes o no las hay. Utiliza la comparación entre la temperatura del cielo y la del ambiente. Cuanto menor sea la temperatura del cielo, menos nubes habrá. Si el cielo está cubierto, parte de la radiación que emite la tierra hacia el espacio es reflejada por la capa de nubes, con lo que la temperatura del cielo será mayor.

Tiene un pequeño inconveniente (al igual que los ceilómetros , o pinchanubes, que hay en los aeropuertos): Aunque el cielo esté despejado y pase una sola nube por delante de su campo de detección, lo cifrará como día cubierto. Este caso suele ocurrir frecuentemente con nubes del tipo cúmulos que se reparten irregularmente por el cielo. Por eso, aparte de consultar los registros que nos deje el aparato, una vigilancia personalizada del cielo nos sacará de cualquier duda. Y lo que está claro es que una estación, por muy automática que sea, nunca dirá si lo que está encima de nosotros son cirros, altocúmulos o cumulonimbos... :)

De todas formas, adelante con vuestro proyecto, que me parece sensacional....pero cuidad muy bien el cómo y dónde instalaís los sensores para que puedan ofrecer lecturas coherentes. De nada sirve tener una buena estación si ésta no ofrece datos reales debido, precisamente, a los errores cometidos cuando se instala.

Saludos.
Estación Meteorológica de Ojáiz-Peñacastillo (Cantabria) Página web: OJAIZMETEO
DETECTOR DE RAYOS
                                                   Vigilando el tiempo

Shaktale

*
Sol
Mensajes: 10
En línea
Uufffff! eso se me escapa de las manos ahora mismo Vaqueret. Para la programación estamos usando un software de National Instruments, que la verdad simplifica bastante la programación porque es lenguaje gráfico. de Pascal no tengo ni idea (nunca había visto un código de pascal aunque me estoy fijando y la verdad que es muy parecido al C) y no disponemos de tiempo para meternos ahora mismo con ello pero, gracias por la ayuda!

Shaktale

*
Sol
Mensajes: 10
En línea
Cita de: FRENTEFRIO en Martes 17 Marzo 2009 15:11:34 PM
Cita de: Shaktale en Martes 17 Marzo 2009 15:06:14 PM
Cita de: FRENTEFRIO en Martes 17 Marzo 2009 11:42:46 AM
Buenos dias.
Bienvenido, paisano.
Casi por casualidad he topado con este tópic.
Si te puedo ayudar en algo, sobre todo en el aspecto de instalación...ya sabes. Yo de electrónica estoy "pez"... ;)




muy buenas. al final nos hemos acercado a la Agencia Estatal de Meteorología, y con eso y la ayuda de un profesor del centro que está estudiando algo de meteorología hemos resuelto practicamente todas las dudas.

La parte electrónica no es problema puesto que los sensores transforman el dato a una escala lineal de corriente así que es muy sencillo calcularlo, y la programación no es complicada.

La parte de instalación ya tenemos las alturas y colocaciones de los sensores: temperatura a 2m. del suelo, anemómetro y veleta a 10 metros... etc.

Y también nos comentaron en la Agencia que para poder asegurar que el cielo está despejado o cubierto solamente con un piranómetro global, una posible forma sería tener un modelo de esa época del año y compararlo. algo así como comparar con un día totalmente despejado de esa época. pero claro para eso tenemos que dejar funcionando la estación un año entero jejej. Nos comentaron que sino necesitaríamos de un heliómetro (del que no disponemos).

y eso es todo de momento.gracias por vuestro interés, si nos sale alguna dudilla más ya os comentaremos ::)
ah y se aceptan sugerencias para la web. me refiero a si alguna vez habéis dicho "ah pues qué bien estaría que la página me mostrara además esto o esto", porque no tenemos ni idea de si hay otros datos (que seguro que sí) de interés, aparte de los que directamente ofrecen los sensores. gracias de nuevo  ;)







Me refería al termómetro, si esa es la razón de ponerlo en negrita jejeje; o está mal esa altura?

FRENTEFRIO

*****
Cb Incus
Mensajes: 4,980
Ojáiz-Peñacastillo (Cantabria)
  1. ojaizmet@hotmail.com
En línea
Sí.....está mal.....
Ya te comento que los termos deben estar a 1,20 metros del suelo y éste mejor si es de césped.
Estación Meteorológica de Ojáiz-Peñacastillo (Cantabria) Página web: OJAIZMETEO
DETECTOR DE RAYOS
                                                   Vigilando el tiempo

Shaktale

*
Sol
Mensajes: 10
En línea
Cita de: FRENTEFRIO en Martes 17 Marzo 2009 15:35:53 PM
Sí.....está mal.....
Ya te comento que los termos deben estar a 1,20 metros del suelo y éste mejor si es de césped.


perdona antes no me salia tu respuesta, solo la cita.

cierto, error mío al comentar lo de la altura; había leído mal.

otro error que he cometido, el termómetro e higrómetro van integrados. osea que es un termohigrómetro  (en concreto uno como estos http://www.lsi-lastem.it/pdf/MW8007.pdf ).
en la Agencia nos dijeron lo de la garita, pero después vi un sensor con la forma de nuestro termohigrómetro anclado a la garita pero fuera de ella. el señor al principio no parecía seguro pero al final nos comentó que realmente con esa forma está protegido del sol y bien ventilado, así que no haría falta garita. es cierto esto?

y otra más: es imprescindible el suelo de cesped? porque teníamos pensado poner el mástil en el tejado del edificio, que es llano (tampoco tenemos muchas más opciones). El tejado es transitable, pero el piso es de cemento. Esto falseará mcuho las mediciones??
supongo que esté relacionado con que reboten mas rayos de luz por ejemplo  o que el suelo absorba más calor de lo debido