NeuronC y SHT11
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 programándolo 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 */
- //--------------------------------------------------------------------
- //float calc_dewpoint(float h,float t)
- //--------------------------------------------------------------------
- // 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}