Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. /*
  2.  * Humidity & Temperature sensor SHT7x. (71/75)
  3.  *
  4.  * Sensor: http://www.sensirion.com/en/02_sensors/03_humidity/00_humidity_temperature_sensor/06_humidity_sensor_sht75.htm
  5.  * Origin of code: http://www.avrfreaks.net/index.php?module=PNphpBB2&file=viewtopic&t=31562&highlight=
  6.  *
  7.  */
  8. #include <avr/io.h>
  9. #include <sht7x.h>
  10. #include <stdlib.h>
  11. #include <avr/wdt.h>
  12.  
  13. /*
  14. Name: void HumidityDelay(void)
  15.  
  16. Description: Delay for SCLK
  17.  
  18. Input: none
  19.  
  20. Output: none
  21.  
  22.  
  23. Misc:
  24. ******************************************************************************/
  25. void HumidityDelay(void)
  26. {
  27. int i;
  28.  
  29. for (i=0;i<40;i++) wdt_reset(); //WDR();
  30. }
  31.  
  32. /******************************************************************************
  33.  
  34. Name: void HumidityInit(void)
  35.  
  36. Description: Initialise port and constant used by
  37. the Humidity & Temp hardware
  38.  
  39.  
  40. Input: none
  41.  
  42. Output: none
  43.  
  44. Misc:
  45. ******************************************************************************/
  46. void HumidityInit(void)
  47. {
  48. HUMIDITY_DDR |= HUMIDITY_DATA + HUMIDITY_SCK;
  49. HUMIDITY_PORT |= HUMIDITY_DATA + HUMIDITY_SCK;
  50. HumiditySoftReset();
  51. }
  52.  
  53. /******************************************************************************
  54.  
  55. Name: unsigned char HumidityWriteByte(unsigned char value)
  56.  
  57. Description: writes a byte on the Sensibus and
  58. checks the acknowledge
  59.  
  60. Input: unsigned char value -> byte to write
  61.  
  62. Output: none
  63.  
  64.  
  65. Misc: If the device don't ACK set HumiError to TRUE;
  66. ******************************************************************************/
  67. void HumidityWriteByte(unsigned char value)
  68. {
  69. unsigned char i;
  70.  
  71. HUMIDITY_DDR |= HUMIDITY_DATA; //DATA-line in output
  72.  
  73. for (i=0x80;i>0;i/=2) //shift bit for masking
  74. {
  75. HumidityDelay();
  76. if (i & value) HUMIDITY_PORT |= HUMIDITY_DATA;
  77. else HUMIDITY_PORT &= ~HUMIDITY_DATA;
  78. HumidityDelay();
  79. HUMIDITY_PORT |= HUMIDITY_SCK;
  80. HumidityDelay();
  81. HUMIDITY_PORT &= ~HUMIDITY_SCK;
  82. }
  83.  
  84. HUMIDITY_PORT |= HUMIDITY_DATA; //release DATA-line
  85. HUMIDITY_DDR &= ~HUMIDITY_DATA; //DATA-line in input
  86. HumidityDelay();
  87. HUMIDITY_PORT |= HUMIDITY_SCK; //clk #9 for ack
  88. HumidityDelay();
  89. if (HUMIDITY_PIN & HUMIDITY_DATA) HumiError = TRUE;
  90. HUMIDITY_PORT &= ~HUMIDITY_SCK;
  91. HumidityDelay();
  92. }
  93.  
  94. /******************************************************************************
  95.  
  96. Name: unsigned char HumidityReadByte(unsigned char ack)
  97.  
  98. Description: reads a byte form the Sensibus and gives
  99. an acknowledge in case of "ack=1"
  100.  
  101. Input: unsigned char ack -> ack status
  102.  
  103. Output: unsigned char value readed
  104.  
  105. Misc:
  106. ******************************************************************************/
  107. unsigned char HumidityReadByte(unsigned char ack)
  108. {
  109. unsigned char i,val=0;
  110.  
  111. HUMIDITY_PORT |= HUMIDITY_DATA; //release DATA-line
  112. HUMIDITY_DDR &= ~HUMIDITY_DATA; //DATA-line in input
  113.  
  114. for (i=0x80;i>0;i/=2) //shift bit for masking
  115. {
  116. HumidityDelay();
  117. HUMIDITY_PORT |= HUMIDITY_SCK; //clk for SENSI-BUS
  118. HumidityDelay();
  119. if (HUMIDITY_PIN & HUMIDITY_DATA) val=(val | i); //read bit
  120. HUMIDITY_PORT &= ~HUMIDITY_SCK;
  121. }
  122.  
  123. if (ack == 1)
  124. {
  125. HUMIDITY_DDR |= HUMIDITY_DATA; //DATA-line in output
  126. HUMIDITY_PORT &= ~HUMIDITY_DATA; //"ack==1" pull down DATA-Line
  127. HumidityDelay();
  128. HUMIDITY_PORT |= HUMIDITY_SCK;
  129. HumidityDelay();
  130. HUMIDITY_PORT &= ~HUMIDITY_SCK;
  131. }
  132. else
  133. {
  134. HumidityDelay();
  135. HUMIDITY_PORT |= HUMIDITY_SCK;
  136. HumidityDelay();
  137. HUMIDITY_PORT &= ~HUMIDITY_SCK;
  138. }
  139. return val;
  140. }
  141.  
  142. /******************************************************************************
  143.  
  144. Name: unsigned char HumidityTransStart(void)
  145.  
  146. Description: Generates a transmission start
  147.  
  148. Input: none
  149.  
  150. Output: none
  151.  
  152. Misc:
  153. _____ ________
  154. DATA: |_______|
  155. ___ ___
  156. SCK : ___| |___| |______
  157. ******************************************************************************/
  158. void HumidityTransStart(void)
  159. {
  160. HUMIDITY_DDR |= HUMIDITY_DATA; //DATA-line in output
  161.  
  162. HUMIDITY_PORT |= HUMIDITY_DATA; //DATA=1
  163. HUMIDITY_PORT &= ~HUMIDITY_SCK; //SCK=0
  164. HumidityDelay();
  165. HUMIDITY_PORT |= HUMIDITY_SCK; //SCK=1
  166. HumidityDelay();
  167. HUMIDITY_PORT &= ~HUMIDITY_DATA; //DATA=0
  168. HumidityDelay();
  169. HUMIDITY_PORT &= ~HUMIDITY_SCK; //SCK=0
  170. HumidityDelay();
  171. HUMIDITY_PORT |= HUMIDITY_SCK; //SCK=1
  172. HumidityDelay();
  173. HUMIDITY_PORT |= HUMIDITY_DATA; //DATA=1
  174. HumidityDelay();
  175. HUMIDITY_PORT &= ~HUMIDITY_SCK; //SCK=0
  176. HumidityDelay();
  177. }
  178.  
  179. /******************************************************************************
  180.  
  181. Name: void HumidityConnectionReset(void)
  182.  
  183. Description: communication Reset: DATA-line=1 and at
  184. least 9 SCK cycles followed by transstart
  185.  
  186. Input: none
  187.  
  188. Output: none
  189.  
  190. Misc:
  191. _____________________________________________________ ________
  192. DATA: |_______|
  193. _ _ _ _ _ _ _ _ _ ___ ___
  194. SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
  195. ******************************************************************************/
  196. void HumidityConnectionReset(void)
  197. {
  198. unsigned char i;
  199.  
  200. HUMIDITY_DDR |= HUMIDITY_DATA; //DATA-line in output
  201. HUMIDITY_PORT |= HUMIDITY_DATA; //DATA=1
  202. HUMIDITY_PORT &= ~HUMIDITY_SCK; //SCK=0
  203.  
  204. for (i=0;i<9;i++) //9 SCK cycles
  205. {
  206. HumidityDelay();
  207. HUMIDITY_PORT |= HUMIDITY_SCK; //SCK=1
  208. HumidityDelay();
  209. HUMIDITY_PORT &= ~HUMIDITY_SCK; //SCK=0
  210. }
  211. HumidityTransStart(); //transmission start
  212. HumiError = FALSE;
  213. }
  214.  
  215. /******************************************************************************
  216.  
  217. Name: void HumiditySoftReset(void)
  218.  
  219. Description: Resets the sensor by a softReset
  220.  
  221. Input: none
  222.  
  223. Output: none
  224.  
  225. Misc:
  226.  
  227. ******************************************************************************/
  228. void HumiditySoftReset(void)
  229. {
  230. int i;
  231. HumidityConnectionReset(); //Reset communication
  232. HumidityWriteByte(HUMIDITY_RESET); //send Reset-command to sensor
  233. for (i=0;i<100;i++) HumidityDelay(); // 11ms delay
  234. }
  235.  
  236. /******************************************************************************
  237.  
  238. Name: unsigned char HumidityReadStatus(void)
  239.  
  240. Description: reads the status register with checksum (8-bit)
  241.  
  242. Input: none
  243.  
  244. Output: unsigned char status byte
  245.  
  246. Misc:
  247.  
  248. ******************************************************************************/
  249. unsigned char HumidityReadStatus(void)
  250. {
  251. unsigned char value,tmp;
  252.  
  253. HumidityTransStart(); //transmission start
  254. HumidityWriteByte(HUMIDITY_STATUS_REG_R); //send command to sensor
  255. value = HumidityReadByte(ACK); //read status register (8-bit)
  256. tmp=HumidityReadByte(noACK); //dummy read checksum (8-bit)
  257. return value;
  258. }
  259.  
  260. /******************************************************************************
  261.  
  262. Name: void HumidityWriteStatus(unsigned char value)
  263.  
  264. Description: writes the status register with checksum (8-bit)
  265.  
  266. Input: unsigned char value to write in the status register
  267.  
  268. Output: none
  269.  
  270. Misc:
  271.  
  272. ******************************************************************************/
  273. void HumidityWriteStatus(unsigned char value)
  274. {
  275. HumidityTransStart(); //transmission start
  276. HumidityWriteByte(HUMIDITY_STATUS_REG_W); //send command to sensor
  277. HumidityWriteByte(value); //send value of status register
  278. }
  279.  
  280. /******************************************************************************
  281.  
  282. Name: unsigned int HumidityMeasure(unsigned char mode)
  283.  
  284. Description: makes a measurement (humidity/temperature)
  285.  
  286. Input: mode -> HUMI or TEMP
  287.  
  288. Output: unsinged int Value mesured
  289.  
  290. Misc:
  291.  
  292. ******************************************************************************/
  293. unsigned int HumidityMeasure(unsigned char mode)
  294. {
  295. unsigned char msb,lsb,tmp;
  296. //int i,j;
  297. uint16_t i,j;
  298.  
  299. HumidityTransStart(); //transmission start
  300. switch (mode) //send command to sensor
  301. {
  302. case HUMIDITY_MEASURE_TEMP : HumidityWriteByte(HUMIDITY_MEASURE_TEMP);
  303. break;
  304. case HUMIDITY_MEASURE_HUMI : HumidityWriteByte(HUMIDITY_MEASURE_HUMI);
  305. break;
  306. default : break;
  307. }
  308.  
  309. HUMIDITY_PORT |= HUMIDITY_DATA; //release DATA-line
  310. HUMIDITY_DDR &= ~HUMIDITY_DATA; //DATA-line in input
  311.  
  312. for (i=0;i<=65530;i++)
  313. {
  314. for (j=0;j<10;j++) wdt_reset(); //WDR();
  315. if((HUMIDITY_PIN & HUMIDITY_DATA) == 0) break; //wait until sensor
  316. } //has finished the measure
  317. if(i > 65530)
  318. {
  319. HumiError=1; // or timeout (~2 sec.) is reached
  320. return 0xffff;
  321. }
  322.  
  323. msb =HumidityReadByte(ACK); //read the first byte (MSB)
  324. lsb=HumidityReadByte(ACK); //read the second byte (LSB)
  325. tmp =HumidityReadByte(noACK); //dummy read checksum
  326. return (msb<<8)+lsb;
  327. }
  328.  
  329. /******************************************************************************
  330.  
  331. Name: void HumidityCalc(float *p_humidity ,float *p_temperature)
  332.  
  333. Description: calculates temperature [°C] and humidity [%RH]
  334.  
  335. Input: humi [Ticks] (12 bit)
  336. temp [Ticks] (14 bit)
  337.  
  338. Output: humi [%RH]
  339. temp [°C]
  340.  
  341. Misc:
  342.  
  343. ******************************************************************************/
  344. void HumidityCalc(float *p_humidity ,float *p_temperature)
  345. {
  346. float C1=-4.0; // for 12 Bit
  347. float C2=+0.0405; // for 12 Bit
  348. float C3=-0.0000028; // for 12 Bit
  349. float T1=+0.01; // for 14 Bit @ 3V
  350. float T2=+0.00008; // for 14 Bit @ 3V
  351.  
  352. float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
  353. float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
  354. float rh_lin; // rh_lin: Humidity linear
  355. float rh_true; // rh_true: Temperature compensated humidity
  356. float t_C; // t_C : Temperature [°C]
  357.  
  358. t_C=t*0.01 - 39.6; //calc. temperature from ticks to [°C]
  359. rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
  360. rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. temp compensated humidity [%RH]
  361. if(rh_true>100)rh_true=100; //cut if the value is outside of
  362. if(rh_true<0.1)rh_true=0.1; //the physical possible range
  363.  
  364. *p_temperature=t_C; //return temperature [°C]
  365. *p_humidity=rh_true; //return humidity[%RH]
  366. }
  367.  
  368. /******************************************************************************
  369.  
  370. Name: void HumidityGet(float *p_humidity ,float *p_temperature)
  371.  
  372. Description: measure humidity [ticks](12 bit) and temperature [ticks](14 bit)
  373.  
  374. Input: humi [%RH]
  375. temp [°C]
  376.  
  377. Output: humi [%RH]
  378. temp [°C]
  379.  
  380. Misc:
  381.  
  382. ******************************************************************************/
  383. void HumidityGet(float *p_humidity ,float *p_temperature)
  384. {
  385. unsigned int humi_val,temp_val;
  386.  
  387. humi_val = HumidityMeasure(HUMIDITY_MEASURE_HUMI); //measure humidity
  388. temp_val = HumidityMeasure(HUMIDITY_MEASURE_TEMP); //measure temperature
  389.  
  390. if(HumiError == TRUE) HumidityConnectionReset(); //in case of an error: Reset
  391. else
  392. {
  393. *p_humidity=(float)humi_val; //converts integer to float
  394. *p_temperature=(float)temp_val; //converts integer to float
  395. HumidityCalc(p_humidity,p_temperature); //calculate humidity, temperature
  396. }
  397. }
  398.  
  399. /******************************************************************************
  400.  
  401. Name: void HumidityUpdate(void)
  402.  
  403. Description:
  404.  
  405. Input:
  406.  
  407. Output:
  408. Misc:
  409.  
  410. ******************************************************************************/
  411. void HumidityUpdate(void)
  412. {
  413. if (HumiError == TRUE) HumidityInit();
  414. HumidityGet(&Humidity,&Temperature);
  415. Hum = Humidity * 10;
  416. Temp = Temperature * 10;
  417. }
  418.