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.

  1. /////////////////////////////////////////////////////////////////////////////
  2. #define noACK 0
  3. #define ACK 1
  4. #define STATUS_REG_W 0x06 //000 0011 0
  5. #define STATUS_REG_R 0x07 //000 0011 1
  6. #define MEASURE_TEMP 0x03 //000 0001 1
  7. #define MEASURE_HUMI 0x05 //000 0010 1
  8. #define RESET 0x1e //000 1111 0
  9. float_type C1={1,0x40,1,0x00,0x0000}; /* -4.0 */ // for 12 Bit
  10. float_type C2={0,0x3d,0,0x25,0xe354}; /* +0.0405 */ // for 12 Bit
  11. float_type C3={1,0x36,0,0x3b,0xe7a2}; /* -0.0000028 */ // for 12 Bit
  12. float_type T1={0,0x3c,0,0x23,0xd70a}; /* +0.01 */ // for 14 Bit
  13. float_type T2={0,0x38,1,0x27,0xc5ac}; /* +0.00008 */ // for 14 Bit
  14. float_type centi={0,0x3c,0,0x23,0xd70a}; /* 0.01 */
  15. float_type f40={0,0x42,0,0x20,0x0000}; /* 40 */
  16. float_type f25={0,0x41,1,0x48,0x0000}; /* 25 */
  17. float_type f200={0,0x43,0,0x48,0x0000}; /* 200 */
  18. float_type f100={0,0x42,0x01,0x48,0 }; // 100.0
  19. // Calculo de entalpia
  20. float_type C9 = {0,0x3f,1,0x32,0x1ca6} /* 1.3914993 */;
  21. // float_type C10 = {1,0x3d,0,0x47,0x3afd} /* -4.8640239E-02 */;
  22. // float_type C11 = {0,0x38,0,0x2f,0x2c94} /* 4.1764768E-05 */;
  23. // float_type C12 = {1,0x32,0,0x78,0x48fa} /* -1.4452093E-08 */;
  24. // float_type C13 = {0,0x40,1,0x51,0x7890} /* 6.5459673 */;
  25. // Calculo de entalpia - fin trozo enum {TEMP,HUMI};
  26. // Variables generales de control de la información y refresco
  27. network input SCPTmaxSendTime config_prop nciMaxSendTime = 3000; // 3000 -> 300 sg. (5 minutos)
  28. network input SCPTminSendTime config_prop nciMinSendTime = 50; // 50 -> 5 sg.
  29. // Variables de Temperatura para diferentes usos y tipos
  30. network output sd_string("Temp. HVAC") SNVT_temp_p nvoHVACTemp;
  31. network output sd_string("Temp. Fix Pt") SNVT_temp nvoFixPtTemp;
  32. network output sd_string("Temp. Float") SNVT_temp_f nvoFloatTemp;
  33. // Variables de Configuración de Temperatura
  34. network input SCPToffsetTemp config_prop nciTmpOffset = 0; // 0 -> 0º , 100->1º
  35. network input SCPTminDeltaTemp config_prop nciMinDelta = 100; // 100 -> 1º
  36. // Variables de Humedad
  37. network output SNVT_lev_percent nvoHVACRH;
  38. network output SNVT_lev_cont nvo8bitRH;
  39. network output SNVT_lev_cont_f nvoFloatRH;
  40. // Variables de Configuración de Humedad
  41. network input SCPTminDeltaRH config_prop nciRHMinDelta = 200; // 200 -> 1%
  42. // Variables depuración estado sensor tem./hum.
  43. network output sd_string("Readout chip Hum.") SNVT_count nvoRaw1;
  44. network output sd_string("Readout chip Tem.") SNVT_count nvoRaw2;
  45. network output sd_string("Sensor Error") SNVT_count nvoError;
  46. ////////////////////////////////////////////////////////////////
  47. // Variables internas para gestión de comunicaciones Lonworks //
  48. ////////////////////////////////////////////////////////////////
  49. SNVT_temp_p Temperatura; // Temperatura leida interna
  50. SNVT_lev_cont_f Humedad; // Humedad leida interna
  51. SNVT_lev_percent HumedadPC; // Humedad en formato SNVT_lev_percent (para Delta)
  52. unsigned long SegSinTxT; // Tiempo sin comunicar Temp
  53. unsigned long SegSinTxH; // Tiempo sin comunicar H
  54. // float_type Entalpia;
  55. // Entalpia calculada
  56. //////////////////////////////////////////////////////////////////
  57. void ProNVsT(void); void ProNVsH(void);
  58. void PropagaNVs(void);
  59. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);
  60. // char s_write_statusreg(unsigned char *p_value); // Para ahorrar código y espacio en programa
  61. // char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum); // Para ahorrar código y espacio en programa
  62. char s_softreset(void);
  63. void s_connectionreset(void);
  64. void s_transstart(void);
  65. char s_read_byte(unsigned char ack);
  66. char s_write_byte(unsigned char value);
  67. ////////////////////////////////////////////////////////
  68. //////////////////////
  69. // Calculo entalpia //
  70. unsigned long normaliza(const float_type *numero, float_type *res);
  71. // void eleva10(const float_type *numero, float_type *res );
  72. // void log10(float_type *d2, float_type *d4);
  73. // Calculo entalpia
  74. /////////////////////////////// I/O Objects /////////////////////////////////
  75. IO_0 output bit sck;
  76. IO_1 output bit dato;
  77. IO_1 input nibble data;
  78. //
  79. /////////////////////////////////////////////////////////////////////////////
  80. stimer repeating minutero = 5 ; // Pone en marcha segundero lecturas
  81. /////////////////////////////////// Tasks ///////////////////////////////////
  82. // ¡¡¡¡¡ RESET !!!!!
  83. when (reset){ io_out(sck, 0);
  84. s_connectionreset();
  85. }
  86. //************************ // Temporizador lecturas //************************
  87. when(timer_expires(minutero)) {
  88. unsigned char error,checksum;
  89. unsigned long te, hu;
  90. float_type rh_lin;
  91. // rh_lin: Humidity linear
  92. float_type rh_true; // rh_true: Temperature compensated humidity
  93. float_type rh; // rh: Lectura raw pasada a float
  94. float_type t_C; // t_C: Temperatura raw
  95. float_type Dmy1, Dmy2, Dmy3;
  96. error=0;
  97. // Leer SHT11
  98. error+=s_measure((unsigned char*) &hu,&checksum,HUMI);
  99. //measure humidity
  100. error+=s_measure((unsigned char*) &te,&checksum,TEMP);
  101. //measure temperature
  102. if(error!=0){
  103. s_connectionreset();
  104. nvoError=error;
  105. }
  106. else{
  107. nvoRaw1=hu;
  108. nvoRaw2=te;
  109. // Pasar los enteros leidos a float para cálculo
  110. // humi_f=(float)hu;
  111. // Calculo de temperatura en formato Echelon SNVT_temp
  112. // Fórmula original ejemplo Sensirion: t_C=t*0.01 - 40; // t_C(tºC) - t(lectura chip)
  113. // Temperatura = (te / 10) + 2340; (para tipo SNVT_temp)
  114. // Calc. temperatura raw a [°C] Temperatura = te - 4000;
  115. // Calc. temperatura raw a [°C] - tipo SNVT_temp_p
  116. // Calculo de la humedad en formato Echelon SNVT_lev_cont
  117. // Fórmula original ejemplo Sensirion
  118. // const float C1=-4.0; // for 12 Bit
  119. // const float C2=+0.0405; // for 12 Bit
  120. // const float C3=-0.0000028; // for 12 Bit
  121. // const float T1=+0.01; // for 14 Bit @ 5V
  122. // const float T2=+0.00008; // for 14 Bit @ 5V
  123. //
  124. // float rh=*p_humidity;
  125. // rh: Humidity [Ticks] 12 Bit
  126. // float rh_lin;
  127. // rh_lin: Humidity linear
  128. // float rh_true;
  129. // rh_true: Temperature compensated humidity
  130. //
  131. // rh_lin=C3*rh*rh + C2*rh + C1;
  132. //calc. humidity from ticks to [%RH]
  133. // rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;
  134. //calc. temperature compensated humidity [%RH]
  135. // if(rh_true>100)rh_true=100;
  136. //cut if the value is outside of
  137. // if(rh_true<0.1)rh_true=0.1;
  138. //the physical possible range
  139. // p_humidity=rh_true;
  140. //return humidity[%RH]
  141. // Implementar fórmula: rh_lin=C3*rh*rh + C2*rh + C1
  142. fl_from_ulong(hu,&rh);
  143. // Pasamos la lectura a float
  144. fl_mul(&rh,&rh,&Dmy1);
  145. // rh * rh
  146. fl_mul(&Dmy1,&C3,&Dmy2);
  147. // C3*rh*rh
  148. fl_mul(&rh,&C2,&Dmy1);
  149. // C2*rh
  150. fl_add(&Dmy1,&Dmy2,&Dmy3);
  151. // C3*rh*rh + C2*rh
  152. fl_add(&Dmy3,&C1,&rh_lin);
  153. // C3*rh*rh + C2*rh + C1 en rh_lin
  154. // Implementar fórmula: rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;
  155. // Calc. humedad compensada por temperatura [%RH]
  156. fl_from_ulong(te ,&Dmy1);
  157. // Pasamos la lectura a float
  158. fl_mul(&Dmy1, &centi, &Dmy2);
  159. fl_sub(&Dmy2, &f40, &t_C);
  160. // t_C=t*0.01 - 40;
  161. fl_sub(&t_C, &f25, &Dmy1);
  162. // (t_C-25) en Dmy1
  163. fl_mul(&T2, &rh, &Dmy2);
  164. fl_add(&Dmy2, &T1, &Dmy3);
  165. // (T1+T2*rh) en Dmy3
  166. fl_mul(&Dmy1, &Dmy3, &Dmy2);
  167. // (t_C-25)*(T1+T2*rh) en Dmy2
  168. fl_add(&Dmy2, &rh_lin, &rh_true);
  169. // rh_true=(t_C-25)*(T1+T2*rh)+rh_lin
  170. // Adaptar el valor float a la variable Interna de Humedad
  171. *(&Humedad)=*(&rh_true);
  172. // Asignamos Humedad a variable interna
  173. // HumedadPC = (Humedad * 200) pasado a signed long
  174. fl_mul(&rh_true, &f200, &Dmy1);
  175. HumedadPC=fl_to_slong(&Dmy1);
  176. // dew_point=calc_dewpoint(humi_val.f,temp_val.f);
  177. // Calcula 'dew point'
  178. SegSinTxH+=50;
  179. SegSinTxT+=50;
  180. }
  181. ///////////////////////// // Propagar por tiempo // /////////////////////////
  182. if(SegSinTxH >= nciMaxSendTime){
  183. SegSinTxH=0;
  184. // Tiempo sin transmitir H a '0'
  185. ProNVsH();
  186. // PropagaNVs();
  187. // Llamar función de propagación NVs implicadas
  188. }
  189. if(SegSinTxT >= nciMaxSendTime){
  190. SegSinTxT=0;
  191. // Tiempo sin transmitir T a '0'
  192. ProNVsT(); // PropagaNVs();
  193. // Llamar función de propagación NVs implicadas
  194. }
  195. /////////////////////////
  196. // Propagar por Deltas //
  197. /////////////////////////
  198. if ((abs(Temperatura - nvoFixPtTemp) > nciMinDelta) && (SegSinTxT >=nciMinSendTime)){
  199. SegSinTxT=0;
  200. ProNVsT();
  201. }
  202. ////////////////////////
  203. if ( (abs(HumedadPC-nvoHVACRH) > nciRHMinDelta) && (SegSinTxH >=nciMinSendTime)){
  204. SegSinTxH=0;
  205. ProNVsH();
  206. }
  207. ////////////////////////
  208. }
  209. //*****************************************************************************************
  210. //**********************//
  211. // FUNCIONES NODO
  212. //**********************//
  213. void ProNVsT(void){
  214. float_type Dmy1, Dmy2;
  215. nvoHVACTemp = Temperatura + nciTmpOffset;
  216. // Actualización en formato SNVT_temp_p
  217. nvoFixPtTemp= (nvoHVACTemp / 10) + 2740;
  218. fl_from_slong(nvoHVACTemp,&Dmy1);
  219. fl_div(&Dmy1, &f100, &Dmy2);
  220. nvoFloatTemp = *(SNVT_temp_f *) &Dmy2;
  221. }
  222. ///////////////////////////////////////////////////////////////////////////////////////////////
  223. void ProNVsH(void){
  224. nvoFloatRH = *(SNVT_lev_cont_f *) &Humedad;
  225. nvoHVACRH = HumedadPC ;
  226. nvo8bitRH = (short)(HumedadPC/100);
  227. }
  228. ///////////////////////////////////////////////////////////////////////////////////////////////
  229. void PropagaNVs(void){
  230. float_type Dmy1, Dmy2, Dmy3;
  231. // Según las variables internas, propagar a las externas en formato adecuado
  232. // Variables de Temperatura para diferentes usos y tipos
  233. // network output sd_string("Temp. HVAC") SNVT_temp_p nvoHVACTemp;
  234. // network output sd_string("Temp. Fix Pt") SNVT_temp nvoFixPtTemp;
  235. // network output sd_string("Temp. Float") SNVT_temp_f nvoFloatTemp;
  236. // Variables de Configuración de Temperatura
  237. // network input SCPToffsetTemp config_prop nciTmpOffset = 0; // 0 -> 0º , 100->1º
  238. // Variables de Humedad
  239. // network output SNVT_lev_percent nvoHVACRH;
  240. // network output SNVT_lev_cont nvo8bitRH;
  241. // network output SNVT_lev_cont_f nvoFloatRH;
  242. // Tener en cuenta Offset de Temperatura !!!!!!!!!!!!!!!!!!!
  243. // Dmy3=C9; // Le asigno C9 para sumarlo despues
  244. nvoHVACTemp = Temperatura + nciTmpOffset;
  245. // Actualización en formato SNVT_temp_p
  246. nvoFixPtTemp= (nvoHVACTemp / 10) + 2740;
  247. fl_from_slong(nvoHVACTemp,&Dmy1);
  248. fl_div(&Dmy1, &f100, &Dmy2);
  249. nvoFloatTemp = *(SNVT_temp_f *) &Dmy2;
  250. nvoFloatRH = *(SNVT_lev_cont_f *) &Humedad;
  251. nvoHVACRH = HumedadPC ;
  252. nvo8bitRH = (short)(HumedadPC/100);
  253. // Calculo entalpia - comienzo trozo
  254. /* La presión de saturación sobre agua líquida entre 0º y 200°C viene dada por:
  255. ln(pws) = (C8/T) + C9 + (C10*T) + (C11*T*T) + (C12*T*T*T) + (C13*ln(T)) */
  256. // log10(&Dmy2,&Dmy1);
  257. // Esta formula no es la correcta, solo es para ver cuanto ocupa en código !!!!!!!!!*******
  258. // fl_mul(&Dmy1,&C13,&Dmy2);
  259. // (C13*ln(T))
  260. // fl_add(&Dmy3,&Dmy2,&Dmy3);
  261. // (C13*ln(T))+C9
  262. // fl_mul(&C10,&Dmy2,&Dmy1);
  263. // Esta formula no es la correcta, solo es para ver cuanto ocupa en código !!!!!!!!!*******
  264. // Calculo entalpia - fin trozo
  265. }
  266. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  267. //****************************// // FUNCIONES SHT11 // //****************************//
  268. //----------------------------------------------------------------------------------
  269. char s_write_byte(unsigned char value){
  270. //----------------------------------------------------------------------------------
  271. // escribe byte en Sensibus y verifica un 'ack'
  272. unsigned char i,error;
  273. error=0;
  274. io_set_direction(dato,IO_DIR_OUT);
  275. for (i=0x80; i>0; i/=2){ // desplaza bit para enmascaramiento
  276. if (i & value){
  277. io_out(dato,1);
  278. }
  279. // DATA=1 - enmascara valor con i , escribe a SENSI-BUS
  280. else {
  281. io_out(dato,0);
  282. }
  283. // DATA=0
  284. io_out(sck, 1);
  285. // SCK=1 - clk para SENSI-BUS
  286. ;;;
  287. // 3 NOP - quizás sean necesarios 9 para pulswith approx. 5 us
  288. io_out(sck, 0); // SCK=0
  289. }
  290. io_out(dato,1); // DATA=1 - liberar DATA-line
  291. io_set_direction(dato,IO_DIR_IN);
  292. io_out(sck, 1); // SCK=1 - clk #9 para ack
  293. error=(io_in(data) & 0x01);
  294. // check ack (DATA hará 'pull down' por el SHT11)
  295. io_out(sck, 0); // SCK=0
  296. return error; // error = 1 en caso de no existir 'ack'
  297. }
  298. //----------------------------------------------------------------------------------
  299. char s_read_byte(unsigned char ack){
  300. //----------------------------------------------------------------------------------
  301. // lee byte desde Sensibus y da 'ack' en caso de "ack=1"
  302. unsigned char i,val;
  303. val=0;
  304. io_set_direction(dato,IO_DIR_OUT);
  305. io_out(dato,1); // DATA=1 - libera DATA-line
  306. io_set_direction(dato,IO_DIR_IN);
  307. for (i=0x80;i>0;i/=2){ // desplazar bit para enmascaramiento
  308. io_out(sck, 1); // SCK=1 - clk para SENSI-BUS
  309. if (io_in(data) & 0x01) val=(val | i); // lee bit
  310. io_out(sck, 0); // SCK=0
  311. }
  312. io_set_direction(dato,IO_DIR_OUT);
  313. io_out(dato,!ack); // en caso de "ack==1" 'pull down' DATA-Line
  314. io_out(sck, 1); // SCK=1 - clk #9 para 'ack'
  315. ;;; // 3 NOP - quizás sean necesarios 9 para pulswith approx. 5 us
  316. io_out(sck, 0); // SCK=0 io_out(dato,1); // DATA=1 - libera DATA-line
  317. return val;
  318. }
  319. //----------------------------------------------------------------------------------
  320. void s_transstart(void){
  321. //----------------------------------------------------------------------------------
  322. // Genera comienzo de Tx // _____ ________ // DATA: |_______| // ___ ___ // SCK : ___| |___| |______
  323. io_set_direction(dato,IO_DIR_OUT);
  324. io_out(dato,1); // DATA=1 - Estado inicial
  325. io_out(sck, 0); // SCK=0 - Initial state
  326. ; // nop()
  327. io_out(sck, 1); // SCK=1
  328. ; // nop()
  329. io_out(dato,0); // DATA=0
  330. ; // nop()
  331. io_out(sck, 0); // SCK=0
  332. ;;; // 3 NOP - quizás sean necesarios 9 para pulswith approx. 5 us
  333. io_out(sck, 1); // SCK=1
  334. ; // nop(
  335. io_out(dato,1); // DATA=1
  336. ; // nop()
  337. io_out(sck, 0); // SCK=0
  338. }
  339. //----------------------------------------------------------------------------------
  340. void s_connectionreset(void){
  341. //----------------------------------------------------------------------------------
  342. // Reset comms.: DATA-line=1 y al menos 9 SCK ciclos seguidos por 'transstart'
  343. // _____________________________________________________ ________ // DATA: |_______|
  344. // _ _ _ _ _ _ _ _ _ ___ ___ // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
  345. unsigned char i;
  346. io_set_direction(dato,IO_DIR_OUT);
  347. io_out(dato,1); // DATA=1 - Estado inicial
  348. io_out(sck, 0); // SCK=0 - Estado inicial
  349. for(i=0;i<9;i++){ // 9 SCK cciclos
  350. io_out(sck, 1); // SCK=1
  351. ;
  352. io_out(sck, 0); // SCK=0
  353. ;
  354. }
  355. s_transstart();
  356. // Tx start
  357. }
  358. //----------------------------------------------------------------------------------
  359. char s_softreset(void){
  360. //----------------------------------------------------------------------------------
  361. // Softreset del sensor
  362. unsigned char error;
  363. error=0;
  364. s_connectionreset(); // Reset comms.
  365. error+=s_write_byte(RESET); // Envia RESET-command a sensor
  366. return error; // error=1 en caso de no respuesta del sensor
  367. }
  368. //----------------------------------------------------------------------------------
  369. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode){
  370. //----------------------------------------------------------------------------------
  371. // Realizar medida (humedad/temperatura) con checksum
  372. unsigned error;
  373. unsigned long i;
  374. error=0;
  375. s_transstart();
  376. // Comenzar Tx
  377. switch(mode){
  378. // Tx comanda a sensor
  379. case TEMP :
  380. error+=s_write_byte(MEASURE_TEMP);
  381. break;
  382. case HUMI :
  383. error+=s_write_byte(MEASURE_HUMI);
  384. break;
  385. default:
  386. break;
  387. }
  388. io_set_direction(dato,IO_DIR_IN);
  389. for (i=0; i<65535; i++){
  390. if((io_in(data) & 0x01)==0){ break; }
  391. //Esperar a que el sensor termine...
  392. }
  393. if(io_in(data) & 0x01) error+=1;
  394. // o timeout (~2 sg.)
  395. *(p_value) =s_read_byte(ACK); //Leer first byte (MSB)
  396. *(p_value+1)=s_read_byte(ACK); //Leer second byte (LSB)
  397. *p_checksum =s_read_byte(noACK); //Leer checksum
  398. return error;
  399. }
  400. //*****************************************************************************************
  401. // Para ahorrar código y espacio en programa, se comenta esta función
  402. // //----------------------------------------------------------------------------------
  403. // char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum){
  404. // //----------------------------------------------------------------------------------
  405. // // Leer registro de estado con checksum (8-bit)
  406. // unsigned char error;
  407. // error=0;
  408. // s_transstart();
  409. // Tx start
  410. // error=s_write_byte(STATUS_REG_R);
  411. // Tx comando a sensor
  412. // *p_value=s_read_byte(ACK);
  413. // Leer registro de estado (8-bit)
  414. // *p_checksum=s_read_byte(noACK);
  415. // Leer checksum (8-bit)
  416. // return error;
  417. // Error=1 en caso de no respuesta del sensor
  418. // }
  419. // Para ahorrar código y espacio en programa, se comenta esta función
  420. // //----------------------------------------------------------------------------------
  421. // char s_write_statusreg(unsigned char *p_value){
  422. // //----------------------------------------------------------------------------------
  423. // // Escribe registro de estado con checksum (8-bit)
  424. // unsigned char error; // error=0; // s_transstart();
  425. // Tx start // error+=s_write_byte(STATUS_REG_W);
  426. // Tx comando a sensor // error+=s_write_byte(*p_value);
  427. // Enviar valor a registro estado
  428. // return error;
  429. // error>=1 en caso de no respuesta desde el sensor
  430. // }
  431. // Calculo entalpia
  432. //================================================================
  433. // // Funcion para extraer la característica de un logaritmo base 10
  434. // // Solo es válida para números positivos !!!!!!!!!!!!!!!!!
  435. // //================================================================
  436. // // unsigned long normaliza(const float_type *numero, float_type *res){
  437. // unsigned long n;
  438. // float_type d1;
  439. // n=0;
  440. // d1 = *(float_type *)№
  441. // while(fl_ge( &d1,&fl_ten)){
  442. // Hacer mientras numero sea mayor o igual a 10
  443. // fl_div(&d1, &fl_ten, &d1);
  444. // Dividir por DIEZ para averiguar logaritmo
  445. // n++;
  446. // }
  447. // res = (float_type *)&d1;
  448. // return n;
  449. // }
  450. //================================================================
  451. //
  452. //================================================================
  453. // // Funcion para elevar a DIEZ un resto, calculo de lob base 10
  454. // // Se ha elevado numero a diez, el resultado estaba en dummy2,
  455. // // pero aqui lo ponemos en numero ya que las operaciones con
  456. // // float no admiten return de nada...
  457. // //================================================================
  458. // // void eleva10(const float_type *numero, float_type *res ){
  459. // float_type dummy1, dummy2, d1;
  460. // d1 = *(float_type *) №
  461. // fl_mul(&d1,&d1,&dummy1);
  462. // dummy1=numero*numero;
  463. // fl_mul(&dummy1,&dummy1,&dummy2);
  464. // dummy2=dummy1*dummy1;
  465. // fl_mul(&dummy2,&dummy1,&dummy2);
  466. // dummy2=dummy2*dummy1;
  467. // fl_mul(&dummy2,&dummy1,&dummy2);
  468. // dummy2=dummy2*dummy1;
  469. // fl_mul(&dummy2,&dummy1,&d1);
  470. // dummy2=dummy2*dummy1;
  471. // res = (float_type *)&d1;
  472. // }
  473. //================================================================
  474. //
  475. //================================================================
  476. // // Determina un logaritmo en base 10, en d2 se envia el numero
  477. // // La funcion asigna a d4 el resultado y destruye d2 - ojo
  478. // //================================================================
  479. // // void log10(float_type *d2, float_type *d4){
  480. // float_type d1,d3,z;
  481. // unsigned int t;
  482. // unsigned long y;
  483. // z = fl_one;
  484. // y = normaliza(d2,d2);
  485. // fl_from_ulong(y,&d3);
  486. // // Después de primera aproximación del entero
  487. // for(t=0;t<6;t++){
  488. // fl_mul(&z,&fl_ten,&z);
  489. // z=z*10;
  490. // // Aproximación de decimales
  491. // eleva10(d2,d2);
  492. // d2=eleva10(d2);
  493. // y=normaliza(d2,d2);
  494. // fl_from_ulong(y,&d1);
  495. // pasamos el dato 'y' a float (d1) para dividir
  496. // fl_div(&d1,&z,&d1);
  497. // Hacemos y/z de la formula y ponemos en d1 -> d3=d3+(y/z);
  498. // fl_add(&d3,&d1,&d3);
  499. // Completamos la formula -> d3=d3+(y/z);
  500. // }
  501. // // Despues de 6 aproximaciones, damos por bueno el log10 y asignamos a d4
  502. // d4 = (float_type *) &d3;
  503. // //================================================================
  504. //
  505. // }
  506. // Calculo entalpia
  507. /* La presión de saturación sobre agua líquida entre 0º y 200°C viene dada por:
  508. ln(pws) = (C8/T) + C9 + (C10*T) + (C11*T*T) + (C12*T*T*T) + (C13*ln(T)) donde:
  509. C8 = -5.8002206 E+03
  510. C9 = 1.3914993 E+00
  511. C10 = -4.8640239 E-02
  512. C11 = 4.1764768 E-05
  513. C12 = -1.4452093 E-08
  514. C13 = 6.5459673 E+00
  515. ln = logaritmo natural pws = presión saturación, Pa T = temperatura absoluta, K = °C + 273.15 */
  516. //--------------------------------------------------------------------
  517. //float calc_dewpoint(float h,float t)
  518. //--------------------------------------------------------------------
  519. // calcular punto de rocio
  520. //float
  521. // input: humedad [%RH], temperatura [°C]
  522. //float
  523. // output: temp. punto rocio [°C]
  524. //float{ float logEx,dew_point;
  525. //float logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
  526. //float dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
  527. //float return dew_point;
  528. //float}

Podría también gustarte...

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *