01
01
Microcontrollers
02
02
Control systems, open systems
03
03
Electronic world, sites
04
04
Electronic components, parts, etc...

e-micronica

NeuronC y SHT11

Imprimir
Escrito por Paikan

El sensor SHT11 de la firma Sensirion permite de una forma sencilla y rápida obtener la temperatura y la humedad desde cualquier microprocesador. En este artículo se incluye el código fuente necesario para incorporar el sensor SHT11 en un nodo Lonworks con un microprocesador FT3120 o FT3150 programandolo en lenguaje NeuronC. Se incluyen las SNVT de diferentes tipos que pueden ser necesarias para propagar los nuevos valores. Hay partes del código comentadas ya que al compilar con NodeBuilder 3.1 no cabían en la memoria del FT3120. Además se incluyen funciones que pueden ser útiles para otras aplicaciones.

El esquema de conexión está en otro artículo (Display A3), en el se usa este dispositivo como sensor de humedad y temperatura.

/////////////////////////////////////////////////////////////////////////////

#define noACK 0
#define ACK 1

#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0

float_type C1={1,0x40,1,0x00,0x0000}; /* -4.0 */              // for 12 Bit 
float_type C2={0,0x3d,0,0x25,0xe354}; /* +0.0405 */           // for 12 Bit 
float_type C3={1,0x36,0,0x3b,0xe7a2}; /* -0.0000028 */        // for 12 Bit 
float_type T1={0,0x3c,0,0x23,0xd70a}; /* +0.01 */             // for 14 Bit 
float_type T2={0,0x38,1,0x27,0xc5ac}; /* +0.00008 */          // for 14 Bit 
float_type centi={0,0x3c,0,0x23,0xd70a}; /* 0.01 */
float_type f40={0,0x42,0,0x20,0x0000}; /* 40 */
float_type f25={0,0x41,1,0x48,0x0000}; /* 25 */
float_type f200={0,0x43,0,0x48,0x0000}; /* 200 */
float_type f100={0,0x42,0x01,0x48,0 };  // 100.0 

// Calculo de entalpia
float_type  C9 = {0,0x3f,1,0x32,0x1ca6}     /* 1.3914993 */;
// float_type C10 = {1,0x3d,0,0x47,0x3afd} /* -4.8640239E-02 */;
// float_type C11 = {0,0x38,0,0x2f,0x2c94} /* 4.1764768E-05 */;
// float_type C12 = {1,0x32,0,0x78,0x48fa} /* -1.4452093E-08 */;
// float_type C13 = {0,0x40,1,0x51,0x7890} /* 6.5459673 */;
// Calculo de entalpia - fin trozo

enum {TEMP,HUMI};

// Variables generales de control de la información y refresco
network input SCPTmaxSendTime config_prop nciMaxSendTime = 3000;    // 3000 -> 300 sg. (5 minutos)
network input SCPTminSendTime config_prop nciMinSendTime = 50;        // 50 -> 5 sg.

// Variables de Temperatura para diferentes usos y tipos
network output sd_string("Temp. HVAC")   SNVT_temp_p nvoHVACTemp;
network output sd_string("Temp. Fix Pt") SNVT_temp      nvoFixPtTemp;
network output sd_string("Temp. Float")  SNVT_temp_f nvoFloatTemp;
// Variables de Configuración de Temperatura 
network input SCPToffsetTemp   config_prop nciTmpOffset = 0;    // 0 -> 0º , 100->1º
network input SCPTminDeltaTemp config_prop nciMinDelta = 100;     // 100 -> 1º

// Variables de Humedad
network output SNVT_lev_percent nvoHVACRH;
network output SNVT_lev_cont     nvo8bitRH;
network output SNVT_lev_cont_f  nvoFloatRH;
// Variables de Configuración de Humedad
network input SCPTminDeltaRH config_prop nciRHMinDelta = 200;     // 200 -> 1%

// Variables depuración estado sensor tem./hum.
network output sd_string("Readout chip Hum.")     SNVT_count nvoRaw1;
network output sd_string("Readout chip Tem.")     SNVT_count nvoRaw2;
network output sd_string("Sensor Error")         SNVT_count nvoError;

////////////////////////////////////////////////////////////////
// Variables internas para gestión de comunicaciones Lonworks //
////////////////////////////////////////////////////////////////
SNVT_temp_p            Temperatura;    // Temperatura leida interna
SNVT_lev_cont_f     Humedad;        // Humedad leida interna
SNVT_lev_percent    HumedadPC;        // Humedad en formato SNVT_lev_percent (para Delta)
unsigned long       SegSinTxT;        // Tiempo sin comunicar Temp
unsigned long       SegSinTxH;        // Tiempo sin comunicar H
// float_type Entalpia; // Entalpia calculada

//////////////////////////////////////////////////////////////////
void ProNVsT(void);
void ProNVsH(void);
void PropagaNVs(void);
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
// char s_write_statusreg(unsigned char *p_value); // Para ahorrar código y espacio en programa
// char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum); // Para ahorrar código y espacio en programa
char s_softreset(void);
void s_connectionreset(void);
void s_transstart(void);
char s_read_byte(unsigned char ack);
char s_write_byte(unsigned char value);
///////////////////////////////////////////////////////////////////////////

// Calculo entalpia
// unsigned long normaliza(const float_type *numero, float_type *res);
// void eleva10(const float_type *numero, float_type *res );
// void log10(float_type *d2, float_type *d4);
// Calculo entalpia


/////////////////////////////// I/O Objects /////////////////////////////////
IO_0 output bit sck;
IO_1 output bit dato;
IO_1 input  nibble data; 
//
/////////////////////////////////////////////////////////////////////////////
stimer repeating minutero = 5 ;         // Pone en marcha segundero lecturas

/////////////////////////////////// Tasks ///////////////////////////////////
// ¡¡¡¡¡ RESET !!!!!
when (reset){
  io_out(sck, 0);
  s_connectionreset(); 
  }



//************************
// Temporizador lecturas
//************************
when(timer_expires(minutero)) {
  unsigned char error,checksum;
  unsigned long te, hu;
  float_type rh_lin;                             // rh_lin: Humidity linear
  float_type rh_true;                            // rh_true: Temperature compensated humidity
  float_type rh;                                // rh: Lectura raw pasada a float
  float_type t_C;                                // t_C: Temperatura raw 
  float_type Dmy1, Dmy2, Dmy3;
  error=0;
  // Leer SHT11
  error+=s_measure((unsigned char*) &hu,&checksum,HUMI);  //measure humidity
  error+=s_measure((unsigned char*) &te,&checksum,TEMP);  //measure temperature
  if(error!=0){
    s_connectionreset();
    nvoError=error; }
  else{  
    nvoRaw1=hu;
    nvoRaw2=te;
    // Pasar los enteros leidos a float para cálculo
    // humi_f=(float)hu;
    // Calculo de temperatura en formato Echelon SNVT_temp
    // Fórmula original ejemplo Sensirion: t_C=t*0.01 - 40; // t_C(tºC) - t(lectura chip)
    // Temperatura = (te / 10) + 2340; (para tipo SNVT_temp) // Calc. temperatura raw a [°C]
    Temperatura = te - 4000;                                        // Calc. temperatura raw a [°C] - tipo SNVT_temp_p
    // Calculo de la humedad en formato Echelon SNVT_lev_cont 
    // Fórmula original ejemplo Sensirion
    // const float C1=-4.0; // for 12 Bit
    // const float C2=+0.0405; // for 12 Bit
    // const float C3=-0.0000028; // for 12 Bit
    // const float T1=+0.01; // for 14 Bit @ 5V
    // const float T2=+0.00008; // for 14 Bit @ 5V 
    //
    // float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit 
    // float rh_lin; // rh_lin: Humidity linear
    // float rh_true; // rh_true: Temperature compensated humidity
    //
    // rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
    // rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH]
    // if(rh_true>100)rh_true=100; //cut if the value is outside of
    // if(rh_true<0.1)rh_true=0.1; //the physical possible range
    // p_humidity=rh_true; //return humidity[%RH]
    // Implementar fórmula: rh_lin=C3*rh*rh + C2*rh + C1
    fl_from_ulong(hu,&rh);                    // Pasamos la lectura a float 
    fl_mul(&rh,&rh,&Dmy1);        // rh * rh
    fl_mul(&Dmy1,&C3,&Dmy2);      // C3*rh*rh
    fl_mul(&rh,&C2,&Dmy1);        // C2*rh
    fl_add(&Dmy1,&Dmy2,&Dmy3);    // C3*rh*rh + C2*rh
    fl_add(&Dmy3,&C1,&rh_lin);    // C3*rh*rh + C2*rh + C1 en rh_lin
    // Implementar fórmula: rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; // Calc. humedad compensada por temperatura [%RH]
    fl_from_ulong(te ,&Dmy1);                    // Pasamos la lectura a float
    fl_mul(&Dmy1, &centi, &Dmy2);
    fl_sub(&Dmy2, &f40, &t_C);                    // t_C=t*0.01 - 40; 
    fl_sub(&t_C, &f25, &Dmy1);                    // (t_C-25) en Dmy1
    fl_mul(&T2, &rh, &Dmy2);
    fl_add(&Dmy2, &T1, &Dmy3);                    // (T1+T2*rh) en Dmy3
    fl_mul(&Dmy1, &Dmy3, &Dmy2);                // (t_C-25)*(T1+T2*rh) en Dmy2
    fl_add(&Dmy2, &rh_lin, &rh_true);            // rh_true=(t_C-25)*(T1+T2*rh)+rh_lin
    // Adaptar el valor float a la variable Interna de Humedad
    *(&Humedad)=*(&rh_true);                        // Asignamos Humedad a variable interna
    // HumedadPC = (Humedad * 200) pasado a signed long
    fl_mul(&rh_true, &f200, &Dmy1);                
    HumedadPC=fl_to_slong(&Dmy1);    
    // dew_point=calc_dewpoint(humi_val.f,temp_val.f); // Calcula 'dew point' 
    SegSinTxH+=50;
    SegSinTxT+=50;
    }
    /////////////////////////
    // Propagar por tiempo // 
    ///////////////////////// 
    if(SegSinTxH >= nciMaxSendTime){
      SegSinTxH=0;    // Tiempo sin transmitir H a '0'
      ProNVsH();
      // PropagaNVs(); // Llamar función de propagación NVs implicadas
      }
    if(SegSinTxT >= nciMaxSendTime){
      SegSinTxT=0;    // Tiempo sin transmitir T a '0'
      ProNVsT();
      // PropagaNVs(); // Llamar función de propagación NVs implicadas
      }
      
    /////////////////////////
    // Propagar por Deltas //
    ///////////////////////// 
    if ((abs(Temperatura - nvoFixPtTemp) > nciMinDelta) && (SegSinTxT >=nciMinSendTime)){
       SegSinTxT=0;
       ProNVsT();
       }
    ////////////////////////
    if ( (abs(HumedadPC-nvoHVACRH) > nciRHMinDelta) && (SegSinTxH >=nciMinSendTime)){
       SegSinTxH=0;
       ProNVsH();
       }
    ////////////////////////


}
//*****************************************************************************************



//**********************//
// FUNCIONES NODO //
//**********************//
void ProNVsT(void){
  float_type Dmy1, Dmy2;
  nvoHVACTemp = Temperatura + nciTmpOffset; // Actualización en formato SNVT_temp_p
  nvoFixPtTemp= (nvoHVACTemp / 10) + 2740;
  fl_from_slong(nvoHVACTemp,&Dmy1);
  fl_div(&Dmy1, &f100, &Dmy2);
  nvoFloatTemp = *(SNVT_temp_f *) &Dmy2;
}
///////////////////////////////////////////////////////////////////////////////////////////////
void ProNVsH(void){
  nvoFloatRH = *(SNVT_lev_cont_f *) &Humedad;  
  nvoHVACRH = HumedadPC ;
  nvo8bitRH = (short)(HumedadPC/100);
}
///////////////////////////////////////////////////////////////////////////////////////////////
void PropagaNVs(void){
  float_type Dmy1, Dmy2, Dmy3;
  // Según las variables internas, propagar a las externas en formato adecuado
  // Variables de Temperatura para diferentes usos y tipos
  // network output sd_string("Temp. HVAC") SNVT_temp_p nvoHVACTemp;
  // network output sd_string("Temp. Fix Pt") SNVT_temp nvoFixPtTemp;
  // network output sd_string("Temp. Float") SNVT_temp_f nvoFloatTemp;
  // Variables de Configuración de Temperatura 
  // network input SCPToffsetTemp config_prop nciTmpOffset = 0; // 0 -> 0º , 100->1º
  // Variables de Humedad
  // network output SNVT_lev_percent nvoHVACRH;
  // network output SNVT_lev_cont nvo8bitRH;
  // network output SNVT_lev_cont_f nvoFloatRH; 
  // Tener en cuenta Offset de Temperatura !!!!!!!!!!!!!!!!!!!
  // Dmy3=C9; // Le asigno C9 para sumarlo despues
  nvoHVACTemp = Temperatura + nciTmpOffset; // Actualización en formato SNVT_temp_p
  nvoFixPtTemp= (nvoHVACTemp / 10) + 2740;
  fl_from_slong(nvoHVACTemp,&Dmy1);
  fl_div(&Dmy1, &f100, &Dmy2);
  nvoFloatTemp = *(SNVT_temp_f *) &Dmy2;
  nvoFloatRH = *(SNVT_lev_cont_f *) &Humedad;  
  nvoHVACRH = HumedadPC ;
  nvo8bitRH = (short)(HumedadPC/100);
  // Calculo entalpia - comienzo trozo 
  /* La presión de saturación sobre agua líquida entre 0º y 200°C viene dada por:
     ln(pws) = (C8/T) + C9 + (C10*T) + (C11*T*T) + (C12*T*T*T) + (C13*ln(T)) */
  // log10(&Dmy2,&Dmy1); // Esta formula no es la correcta, solo es para ver cuanto ocupa en código !!!!!!!!!*******
  // fl_mul(&Dmy1,&C13,&Dmy2); // (C13*ln(T))
  // fl_add(&Dmy3,&Dmy2,&Dmy3); // (C13*ln(T))+C9
  // fl_mul(&C10,&Dmy2,&Dmy1); // Esta formula no es la correcta, solo es para ver cuanto ocupa en código !!!!!!!!!*******
  // Calculo entalpia - fin trozo 
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//****************************//
// FUNCIONES SHT11 //
//****************************//

//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value){
//----------------------------------------------------------------------------------
// escribe byte en Sensibus y verifica un 'ack'
  unsigned char i,error;
  error=0;
  io_set_direction(dato,IO_DIR_OUT);
  for (i=0x80; i>0; i/=2){                // desplaza bit para enmascaramiento
    if (i & value){
       io_out(dato,1);}                    // DATA=1 - enmascara valor con i , escribe a SENSI-BUS
    else {
       io_out(dato,0);}                    // DATA=0
    io_out(sck, 1);                     // SCK=1 - clk para SENSI-BUS
    ;;;                                      // 3 NOP - quizás sean necesarios 9 para pulswith approx. 5 us
    io_out(sck, 0);                     // SCK=0
  }
  io_out(dato,1);                        // DATA=1 - liberar DATA-line
  io_set_direction(dato,IO_DIR_IN);
  io_out(sck, 1);                       // SCK=1 - clk #9 para ack
  error=(io_in(data) & 0x01);           // check ack (DATA hará 'pull down' por el SHT11)
  io_out(sck, 0);                        // SCK=0
  return error;                         // error = 1 en caso de no existir 'ack'
}

//----------------------------------------------------------------------------------
char s_read_byte(unsigned char ack){
//----------------------------------------------------------------------------------
// lee byte desde Sensibus y da 'ack' en caso de "ack=1"
  unsigned char i,val;
  val=0;
  io_set_direction(dato,IO_DIR_OUT);
  io_out(dato,1);                                // DATA=1 - libera DATA-line
  io_set_direction(dato,IO_DIR_IN);
  for (i=0x80;i>0;i/=2){                        // desplazar bit para enmascaramiento
    io_out(sck, 1);                                // SCK=1 - clk para SENSI-BUS
    if (io_in(data) & 0x01) val=(val | i);         // lee bit
    io_out(sck, 0);                        // SCK=0
    }
  io_set_direction(dato,IO_DIR_OUT);
  io_out(dato,!ack);                    // en caso de "ack==1" 'pull down' DATA-Line
  io_out(sck, 1);                        // SCK=1 - clk #9 para 'ack'
  ;;;                                    // 3 NOP - quizás sean necesarios 9 para pulswith approx. 5 us
  io_out(sck, 0);                        // SCK=0
  io_out(dato,1);                        // DATA=1 - libera DATA-line
  return val;
}


//----------------------------------------------------------------------------------
void s_transstart(void){
//----------------------------------------------------------------------------------
// Genera comienzo de Tx
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
   io_set_direction(dato,IO_DIR_OUT);
   io_out(dato,1);                // DATA=1 - Estado inicial
   io_out(sck, 0);                // SCK=0 - Initial state
   ;                            // nop()
   io_out(sck, 1);                // SCK=1
   ;                            // nop() 
   io_out(dato,0);                // DATA=0
   ;                            // nop() 
   io_out(sck, 0);                // SCK=0
   ;;;                              // 3 NOP - quizás sean necesarios 9 para pulswith approx. 5 us
   io_out(sck, 1);                // SCK=1
   ;                            // nop()
   io_out(dato,1);                // DATA=1 
   ;                            // nop() 
   io_out(sck, 0);                 // SCK=0
  }


//----------------------------------------------------------------------------------
void s_connectionreset(void){
//----------------------------------------------------------------------------------
// Reset comms.: DATA-line=1 y al menos 9 SCK ciclos seguidos por 'transstart'
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
  unsigned char i;
  io_set_direction(dato,IO_DIR_OUT);
  io_out(dato,1);                // DATA=1 - Estado inicial
  io_out(sck, 0);                // SCK=0 - Estado inicial
  for(i=0;i<9;i++){             // 9 SCK cciclos
    io_out(sck, 1);                // SCK=1
    ;
    io_out(sck, 0);                // SCK=0
    ;
    }
  s_transstart();               // Tx start
}

//----------------------------------------------------------------------------------
char s_softreset(void){
//----------------------------------------------------------------------------------
// Softreset del sensor
  unsigned char error;
  error=0;
  s_connectionreset();              // Reset comms.
  error+=s_write_byte(RESET);       // Envia RESET-command a sensor
  return error;                     // error=1 en caso de no respuesta del sensor
}


//----------------------------------------------------------------------------------
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode){
//----------------------------------------------------------------------------------
// Realizar medida (humedad/temperatura) con checksum
  unsigned error;
  unsigned long i;
  error=0;
  s_transstart();                   // Comenzar Tx
  switch(mode){                     // Tx comanda a sensor
    case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
    case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
    default     : break;
    }
  io_set_direction(dato,IO_DIR_IN);
  for (i=0; i<65535; i++){
      if((io_in(data) & 0x01)==0){ break; }    //Esperar a que el sensor termine...
      }
  if(io_in(data) & 0x01) error+=1;         // o timeout (~2 sg.)
  *(p_value)  =s_read_byte(ACK);    //Leer first byte (MSB)
  *(p_value+1)=s_read_byte(ACK);    //Leer second byte (LSB)
  *p_checksum =s_read_byte(noACK);  //Leer checksum
  return error;
}
//*****************************************************************************************

// Para ahorrar código y espacio en programa, se comenta esta función
// //----------------------------------------------------------------------------------
// char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum){
// //----------------------------------------------------------------------------------
// // Leer registro de estado con checksum (8-bit)
// unsigned char error;
// error=0;
// s_transstart(); // Tx start
// error=s_write_byte(STATUS_REG_R); // Tx comando a sensor
// *p_value=s_read_byte(ACK); // Leer registro de estado (8-bit)
// *p_checksum=s_read_byte(noACK); // Leer checksum (8-bit)
// return error; // Error=1 en caso de no respuesta del sensor
// }
// Para ahorrar código y espacio en programa, se comenta esta función
// //----------------------------------------------------------------------------------
// char s_write_statusreg(unsigned char *p_value){
// //----------------------------------------------------------------------------------
// // Escribe registro de estado con checksum (8-bit)
// unsigned char error;
// error=0;
// s_transstart(); // Tx start
// error+=s_write_byte(STATUS_REG_W);// Tx comando a sensor
// error+=s_write_byte(*p_value); // Enviar valor a registro estado
// return error; // error>=1 en caso de no respuesta desde el sensor
// }


// Calculo entalpia

//================================================================//
// Funcion para extraer la característica de un logaritmo base 10 //
// Solo es válida para números positivos !!!!!!!!!!!!!!!!! //
//================================================================//
// unsigned long normaliza(const float_type *numero, float_type *res){
// unsigned long n;
// float_type d1;
// n=0;
// d1 = *(float_type *)&numero;
// while(fl_ge( &d1,&fl_ten)){ // Hacer mientras numero sea mayor o igual a 10
// fl_div(&d1, &fl_ten, &d1); // Dividir por DIEZ para averiguar logaritmo
// n++;
// }
// res = (float_type *)&d1; 
// return n;
// }
//================================================================//


//================================================================//
// Funcion para elevar a DIEZ un resto, calculo de lob base 10 //
// Se ha elevado numero a diez, el resultado estaba en dummy2, //
// pero aqui lo ponemos en numero ya que las operaciones con //
// float no admiten return de nada... //
//================================================================// 
// void eleva10(const float_type *numero, float_type *res ){
// float_type dummy1, dummy2, d1;
// d1 = *(float_type *) &numero; 
// fl_mul(&d1,&d1,&dummy1); // dummy1=numero*numero;
// fl_mul(&dummy1,&dummy1,&dummy2); // dummy2=dummy1*dummy1;
// fl_mul(&dummy2,&dummy1,&dummy2); // dummy2=dummy2*dummy1;
// fl_mul(&dummy2,&dummy1,&dummy2); // dummy2=dummy2*dummy1;
// fl_mul(&dummy2,&dummy1,&d1); // dummy2=dummy2*dummy1;
// res = (float_type *)&d1; 
// }
//================================================================//


//================================================================//
// Determina un logaritmo en base 10, en d2 se envia el numero //
// La funcion asigna a d4 el resultado y destruye d2 - ojo //
//================================================================//
// void log10(float_type *d2, float_type *d4){
// float_type d1,d3,z;
// unsigned int t;
// unsigned long y;
// z = fl_one;
// y = normaliza(d2,d2);
// fl_from_ulong(y,&d3);
// // Después de primera aproximación del entero
// for(t=0;t<6;t++){
// fl_mul(&z,&fl_ten,&z); // z=z*10;
// // Aproximación de decimales
// eleva10(d2,d2); // d2=eleva10(d2);
// y=normaliza(d2,d2);
// fl_from_ulong(y,&d1); // pasamos el dato 'y' a float (d1) para dividir
// fl_div(&d1,&z,&d1); // Hacemos y/z de la formula y ponemos en d1 -> d3=d3+(y/z);
// fl_add(&d3,&d1,&d3); // Completamos la formula -> d3=d3+(y/z);
// }
// // Despues de 6 aproximaciones, damos por bueno el log10 y asignamos a d4
// d4 = (float_type *) &d3;
// //================================================================// 
// }
// Calculo entalpia


/* La presión de saturación sobre agua líquida entre 0º y 200°C viene dada por:
ln(pws) = (C8/T) + C9 + (C10*T) + (C11*T*T) + (C12*T*T*T) + (C13*ln(T))
donde: 
C8 = -5.8002206 E+03
C9 = 1.3914993 E+00
C10 = -4.8640239 E-02
C11 = 4.1764768 E-05
C12 = -1.4452093 E-08
C13 = 6.5459673 E+00
ln = logaritmo natural
pws = presión saturación, Pa
T = temperatura absoluta, K = °C + 273.15
*/

//--------------------------------------------------------------------
//floatfloat calc_dewpoint(float h,float t)
//float//--------------------------------------------------------------------
//float// calcular punto de rocio
//float// input: humedad [%RH], temperatura [°C]
//float// output: temp. punto rocio [°C]
//float{ float logEx,dew_point;
//float logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
//float dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
//float return dew_point;
//float}
hostgator coupon or play poker on party poker
Copyright 2011 NeuronC y SHT11 .
Joomla Templates by Wordpress themes free