Paparazzi UAS  v5.8.2_stable-0-g6260b7c
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
humid_sht.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2014 The Paparazzi team
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
31 #include "std.h"
32 #include "mcu_periph/gpio.h"
33 #include "mcu_periph/uart.h"
34 #include "messages.h"
36 #include "humid_sht.h"
37 
38 //#include "led.h"
39 
40 #define noACK 0
41 #define ACK 1
42 #define TEMP 0
43 #define HUMI 1
44 
45 //adr command r/w
46 //000 0011 0
47 #define STATUS_REG_W 0x06
48 //000 0011 1
49 #define STATUS_REG_R 0x07
50 //000 0001 1
51 #define MEASURE_TEMP 0x03
52 //000 0010 1
53 #define MEASURE_HUMI 0x05
54 //000 1111 0
55 #define RESET 0x1e
56 
57 
58 #define SHT_IDLE 0
59 #define SHT_MEASURING_HUMID 1
60 #define SHT_MEASURING_TEMP 2
61 
62 #if !defined SHT_DAT_GPIO || !defined SHT_SCK_GPIO
63 #error You need to define SHT_DAT_GPIO and SHT_SCK_GPIO
64 #endif
65 
67 #define DATA_SET gpio_setup_input(SHT_DAT_GPIO)
68 #define DATA_CLR gpio_setup_output(SHT_DAT_GPIO)
70 #define DATA_IN gpio_get(SHT_DAT_GPIO)
72 
74 #define SCK_SET gpio_set(SHT_SCK_GPIO)
75 #define SCK_CLR gpio_clear(SHT_SCK_GPIO)
77 
78 
83 
86 void s_transstart(void);
87 void s_connectionreset(void);
88 uint8_t s_read_statusreg(uint8_t *p_value, uint8_t *p_checksum);
90 uint8_t s_measure(uint16_t *p_value, uint8_t *p_checksum, uint8_t mode);
92 uint8_t s_read_measure(uint16_t *p_value, uint8_t *p_checksum);
93 void calc_sht(uint16_t hum, uint16_t tem, float *fhum , float *ftem);
95 
96 
98 {
99  uint8_t i, error = 0;
100 
101  for (i = 0x80; i > 0; i /= 2) { //shift bit for masking
102  if (i & value) { DATA_SET; } //masking value with i , write to SENSI-BUS
103  else { DATA_CLR; }
104  SCK_SET; //clk for SENSI-BUS
105  SCK_SET; SCK_SET; SCK_SET; //pulswith approx. 5 us
106  // _nop_();_nop_();_nop_(); //pulswith approx. 5 us
107  SCK_CLR;
108  }
109  DATA_SET; //release DATA-line
110  SCK_SET; //clk #9 for ack
111  error = DATA_IN; //check ack (DATA will be pulled down by SHT11)
112  SCK_CLR;
113 
114  return error; //error=1 in case of no acknowledge
115 }
116 
118 {
119  uint8_t i, val = 0;
120 
121  DATA_SET; //release DATA-line
122  for (i = 0x80; i > 0; i /= 2) { //shift bit for masking
123  SCK_SET; //clk for SENSI-BUS
124  if (DATA_IN) { val = (val | i); } //read bit
125  SCK_CLR;
126  }
127 
128  if (ack) { DATA_CLR; } //in case of "ack==1" pull down DATA-Line
129  SCK_SET; //clk #9 for ack
130  SCK_SET; SCK_SET; SCK_SET; //pulswith approx. 5 us
131  // _nop_();_nop_();_nop_(); //pulswith approx. 5 us
132  SCK_CLR;
133  DATA_SET; //release DATA-line
134  return val;
135 }
136 
137 void s_transstart(void)
138 {
139  // generates a transmission start
140  // _____ ________
141  // DATA: |_______|
142  // ___ ___
143  // SCK : ___| |___| |______
144 
145  DATA_SET; SCK_CLR; //Initial state
146  SCK_CLR;// _nop_();
147  SCK_SET;
148  SCK_SET;// _nop_();
149  DATA_CLR;
150  DATA_CLR;// _nop_();
151  SCK_CLR;
152  SCK_CLR; SCK_CLR; SCK_CLR; // _nop_();_nop_();_nop_();
153  SCK_SET;
154  SCK_SET;// _nop_();
155  DATA_SET;
156  DATA_SET;// _nop_();
157  SCK_CLR;
158 }
159 
161 {
162  // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
163  // _____________________________________________________ ________
164  // DATA: |_______|
165  // _ _ _ _ _ _ _ _ _ ___ ___
166  // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
167 
168  uint8_t i;
169 
170  DATA_SET; SCK_CLR; //Initial state
171  for (i = 0; i < 9; i++) { //9 SCK cycles
172  SCK_SET;
173  SCK_CLR;
174  }
175  s_transstart(); //transmission start
176 }
177 
178 uint8_t s_read_statusreg(uint8_t *p_value, uint8_t *p_checksum)
179 {
180  // reads the status register with checksum (8-bit)
181  uint8_t error = 0;
182 
183  s_transstart(); //transmission start
184  error = s_write_byte(STATUS_REG_R); //send command to sensor
185  *p_value = s_read_byte(ACK); //read status register (8-bit)
186  *p_checksum = s_read_byte(noACK); //read checksum (8-bit)
187  return error; //error=1 in case of no response form the sensor
188 }
189 
191 {
192  // writes the status register with checksum (8-bit)
193  uint8_t error = 0;
194 
195  s_transstart(); //transmission start
196  error += s_write_byte(STATUS_REG_W); //send command to sensor
197  error += s_write_byte(*p_value); //send value of status register
198  return error; //error>=1 in case of no response form the sensor
199 }
200 
201 uint8_t s_measure(uint16_t *p_value, uint8_t *p_checksum, uint8_t mode)
202 {
203  // makes a measurement (humidity/temperature) with checksum
204  uint8_t error = 0;
205  uint32_t i;
206 
207  s_transstart(); //transmission start
208  switch (mode) { //send command to sensor
209  case TEMP : error += s_write_byte(MEASURE_TEMP); break;
210  case HUMI : error += s_write_byte(MEASURE_HUMI); break;
211  default : break;
212  }
213  for (i = 0; i < 6665535; i++) if (DATA_IN == 0) { break; } //wait until sensor has finished the measurement
214  if (DATA_IN) { error += 1; } // or timeout (~2 sec.) is reached
215  *(p_value) = s_read_byte(ACK) << 8; //read the first byte (MSB)
216  *(p_value) |= s_read_byte(ACK); //read the second byte (LSB)
217  *p_checksum = s_read_byte(noACK); //read checksum
218 
219  return error;
220 }
221 
223 {
224  // makes a measurement (humidity/temperature) with checksum
225  uint8_t error = 0;
226 
227  s_transstart(); //transmission start
228  switch (mode) { //send command to sensor
229  case TEMP : error += s_write_byte(MEASURE_TEMP); break;
230  case HUMI : error += s_write_byte(MEASURE_HUMI); break;
231  default : break;
232  }
233 
234  return error;
235 }
236 
237 uint8_t s_read_measure(uint16_t *p_value, uint8_t *p_checksum)
238 {
239  // reads a measurement (humidity/temperature) with checksum
240  uint8_t error = 0;
241 
242  if (DATA_IN) { error += 1; } //still busy?
243  *(p_value) = s_read_byte(ACK) << 8; //read the first byte (MSB)
244  *(p_value) |= s_read_byte(ACK); //read the second byte (LSB)
245  *p_checksum = s_read_byte(noACK); //read checksum
246 
247  return error;
248 }
249 
250 void calc_sht(uint16_t hum, uint16_t tem, float *fhum , float *ftem)
251 {
252  // calculates temperature [ C] and humidity [%RH]
253  // input : humi [Ticks] (12 bit)
254  // temp [Ticks] (14 bit)
255  // output: humi [%RH]
256  // temp [ C]
257 
258  const float C1 = -4.0; // for 12 Bit
259  const float C2 = 0.0405; // for 12 Bit
260  const float C3 = -0.0000028; // for 12 Bit
261  const float T1 = 0.01; // for 14 Bit @ 5V
262  const float T2 = 0.00008; // for 14 Bit @ 5V
263  float rh; // rh: Humidity [Ticks] 12 Bit
264  float t; // t: Temperature [Ticks] 14 Bit
265  float rh_lin; // rh_lin: Humidity linear
266  float rh_true; // rh_true: Temperature compensated humidity
267  float t_C; // t_C : Temperature [ C]
268 
269  rh = (float)hum; //converts integer to float
270  t = (float)tem; //converts integer to float
271 
272  t_C = t * 0.01 - 39.66; //calc. Temperature from ticks to [°C] @ 3.5V
273  rh_lin = C3 * rh * rh + C2 * rh + C1; //calc. Humidity from ticks to [%RH]
274  rh_true = (t_C - 25) * (T1 + T2 * rh) + rh_lin; //calc. Temperature compensated humidity [%RH]
275  if (rh_true > 100) { rh_true = 100; } //cut if the value is outside of
276  if (rh_true < 0.1) { rh_true = 0.1; } //the physical possible range
277  *ftem = t_C; //return temperature [ C]
278  *fhum = rh_true; //return humidity[%RH]
279 }
280 
282 {
283  // resets the sensor by a softreset
284  uint8_t error = 0;
285 
286  s_connectionreset(); //reset communication
287  error += s_write_byte(RESET); //send RESET-command to sensor
288 
289  return error; //error=1 in case of no response form the sensor
290 }
291 
292 void humid_sht_init(void)
293 {
294  /* Configure DAT/SCL pin as GPIO */
295  gpio_setup_input(SHT_DAT_GPIO);
296  gpio_setup_output(SHT_SCK_GPIO);
297  gpio_clear(SHT_SCK_GPIO);
298 
299 
302 }
303 
305 {
306  uint8_t error = 0, checksum;
307 
308  if (humid_sht_status == SHT_IDLE) {
309  /* init humidity read */
313  } else if (humid_sht_status == SHT_MEASURING_HUMID) {
314  /* get data */
315  error += s_read_measure(&humidsht, &checksum);
316 
317  if (error != 0) {
319  s_start_measure(HUMI); //restart
320  //LED_TOGGLE(2);
321  } else {
322  error += s_start_measure(TEMP);
324  }
325  } else if (humid_sht_status == SHT_MEASURING_TEMP) {
326  /* get data */
327  error += s_read_measure(&tempsht, &checksum);
328 
329  if (error != 0) {
331  s_start_measure(TEMP); //restart
332  //LED_TOGGLE(2);
333  } else {
339  DOWNLINK_SEND_SHT_STATUS(DefaultChannel, DefaultDevice, &humidsht, &tempsht, &fhumidsht, &ftempsht);
341  }
342  }
343 }
unsigned short uint16_t
Definition: types.h:16
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
void humid_sht_init(void)
Definition: humid_sht.c:292
#define SHT_MEASURING_HUMID
Definition: humid_sht.c:59
void humid_sht_periodic(void)
Definition: humid_sht.c:304
#define DATA_SET
set data pin to input
Definition: humid_sht.c:67
#define SHT_IDLE
Definition: humid_sht.c:58
uint16_t value
Definition: adc_arch.c:586
Some architecture independent helper functions for GPIOs.
#define HUMI
Definition: humid_sht.c:43
#define DATA_CLR
set data pin to output
Definition: humid_sht.c:69
uint8_t s_write_byte(uint8_t value)
Definition: humid_sht.c:97
uint16_t humidsht
Definition: humid_sht.c:79
#define FALSE
Definition: std.h:5
#define TEMP
Definition: humid_sht.c:42
uint8_t s_write_statusreg(uint8_t *p_value)
Definition: humid_sht.c:190
#define TRUE
Definition: std.h:4
uint8_t s_read_measure(uint16_t *p_value, uint8_t *p_checksum)
Definition: humid_sht.c:237
#define STATUS_REG_W
Definition: humid_sht.c:47
#define MEASURE_HUMI
Definition: humid_sht.c:53
uint8_t humid_sht_status
Definition: humid_sht.c:82
uint16_t val[TCOUPLE_NB]
void gpio_clear(uint32_t port, uint16_t pin)
Clear a gpio output to low level.
Definition: gpio_ardrone.c:70
unsigned long uint32_t
Definition: types.h:18
#define SCK_SET
set clock pin to high
Definition: humid_sht.c:74
#define STATUS_REG_R
Definition: humid_sht.c:49
#define MEASURE_TEMP
Definition: humid_sht.c:51
uint8_t s_read_byte(uint8_t ack)
Definition: humid_sht.c:117
uint8_t s_start_measure(uint8_t mode)
Definition: humid_sht.c:222
#define SHT_MEASURING_TEMP
Definition: humid_sht.c:60
uint8_t humid_sht_reset(void)
Definition: humid_sht.c:281
void s_transstart(void)
Definition: humid_sht.c:137
SHTxx sensor interface.
void calc_sht(uint16_t hum, uint16_t tem, float *fhum, float *ftem)
Definition: humid_sht.c:250
unsigned char uint8_t
Definition: types.h:14
bool_t humid_sht_available
Definition: humid_sht.c:81
uint8_t s_read_statusreg(uint8_t *p_value, uint8_t *p_checksum)
Definition: humid_sht.c:178
float ftempsht
Definition: humid_sht.c:80
void gpio_setup_input(uint32_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as inputs.
Definition: gpio_ardrone.c:86
#define SCK_CLR
set clock pin to low
Definition: humid_sht.c:76
#define noACK
Definition: humid_sht.c:40
#define ACK
Definition: humid_sht.c:41
void s_connectionreset(void)
Definition: humid_sht.c:160
uint8_t s_measure(uint16_t *p_value, uint8_t *p_checksum, uint8_t mode)
Definition: humid_sht.c:201
float fhumidsht
Definition: humid_sht.c:80
#define DATA_IN
get data pin
Definition: humid_sht.c:71
uint16_t tempsht
Definition: humid_sht.c:79
void gpio_setup_output(uint32_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as outputs.
Definition: gpio_ardrone.c:102
#define RESET
Definition: humid_sht.c:55