SHT V4 5V UART

Dependencies:   mbed

Fork of SHT_v1 by Stephen McGarry

Committer:
fblanc
Date:
Tue Feb 23 08:10:54 2016 +0000
Revision:
1:0dbbb4802508
Parent:
0:df1c8f2961a1
SHT V4 5V;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
roselea 0:df1c8f2961a1 1 /* mbed module to use a Sensirion SHT1x /SHT7x sensor
roselea 0:df1c8f2961a1 2 * Copyright (c) 2007-2009 Stephen McGarry
roselea 0:df1c8f2961a1 3 * Released under the MIT License: http://mbed.org/license/mit
roselea 0:df1c8f2961a1 4 */
roselea 0:df1c8f2961a1 5
roselea 0:df1c8f2961a1 6 #include "SHT.h"
roselea 0:df1c8f2961a1 7
roselea 0:df1c8f2961a1 8 #include "mbed.h"
fblanc 1:0dbbb4802508 9 #define MICROSECONDE 10//1
roselea 0:df1c8f2961a1 10
roselea 0:df1c8f2961a1 11 SHT::SHT(PinName p_sclk, PinName p_data, SHT_acc p_accuracy) : sclk(p_sclk), data(p_data), accuracy(p_accuracy) {
roselea 0:df1c8f2961a1 12 sclk=0;
roselea 0:df1c8f2961a1 13 data=0; // data pin will be used as open collector pin
roselea 0:df1c8f2961a1 14 data.mode(PullUp); // with the pull up internally active
roselea 0:df1c8f2961a1 15 data.input(); // with line released to go high
roselea 0:df1c8f2961a1 16 temperature = humidity = dewpoint=0.0f;
fblanc 1:0dbbb4802508 17
roselea 0:df1c8f2961a1 18 }
roselea 0:df1c8f2961a1 19
roselea 0:df1c8f2961a1 20 char SHT::write_byte(byte value)
roselea 0:df1c8f2961a1 21 //----------------------------------------------------------------------------------
roselea 0:df1c8f2961a1 22 // writes a byte on the Sensibus and checks the acknowledge
roselea 0:df1c8f2961a1 23 {
roselea 0:df1c8f2961a1 24 int i;
roselea 0:df1c8f2961a1 25 char error=0;
roselea 0:df1c8f2961a1 26
roselea 0:df1c8f2961a1 27 for (i=0x80;i>0;i/=2) { //shift bit for masking
roselea 0:df1c8f2961a1 28 if (i & value) data.input(); //masking value with i , write to SENSI-BUS
roselea 0:df1c8f2961a1 29 else data.output();
fblanc 1:0dbbb4802508 30 wait_us(MICROSECONDE); //ensure sclk is low for min time
fblanc 1:0dbbb4802508 31
roselea 0:df1c8f2961a1 32 sclk=1; //clk for SENSI-BUS
fblanc 1:0dbbb4802508 33 wait_us(MICROSECONDE); //pulsewith approx. 2 us
roselea 0:df1c8f2961a1 34 sclk=0;
roselea 0:df1c8f2961a1 35 }
roselea 0:df1c8f2961a1 36 data.input(); //release DATA-line
fblanc 1:0dbbb4802508 37 wait_us(MICROSECONDE); //ensure sclk is low for min time
roselea 0:df1c8f2961a1 38 sclk=1; //clk #9 for ack
roselea 0:df1c8f2961a1 39 error=data; //check ack (DATA will be pulled down by SHT11)
fblanc 1:0dbbb4802508 40 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 41 sclk=0;
roselea 0:df1c8f2961a1 42 return error; //error=1 in case of no acknowledge
roselea 0:df1c8f2961a1 43 }
roselea 0:df1c8f2961a1 44
roselea 0:df1c8f2961a1 45 byte SHT::read_byte(bool send_ack)
roselea 0:df1c8f2961a1 46 //----------------------------------------------------------------------------------
roselea 0:df1c8f2961a1 47 // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
roselea 0:df1c8f2961a1 48 {
roselea 0:df1c8f2961a1 49 byte i,val=0;
roselea 0:df1c8f2961a1 50 data.input(); //release DATA-line
roselea 0:df1c8f2961a1 51 for (i=0x80;i>0;i/=2) { //shift bit for masking
fblanc 1:0dbbb4802508 52 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 53 sclk=1; //clk for SENSI-BUS
roselea 0:df1c8f2961a1 54 if (data) val=(val | i); //read bit
fblanc 1:0dbbb4802508 55 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 56 sclk=0;
roselea 0:df1c8f2961a1 57 }
fblanc 1:0dbbb4802508 58 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 59 if (send_ack) data.output(); // if ack needed then drive data low
roselea 0:df1c8f2961a1 60 sclk=1; //clk #9 for ack
fblanc 1:0dbbb4802508 61 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 62 sclk=0;
roselea 0:df1c8f2961a1 63 data.input(); //release DATA-line
roselea 0:df1c8f2961a1 64 return val;
roselea 0:df1c8f2961a1 65 }
roselea 0:df1c8f2961a1 66
roselea 0:df1c8f2961a1 67 void SHT::trans_start(void)
roselea 0:df1c8f2961a1 68 //----------------------------------------------------------------------------------
roselea 0:df1c8f2961a1 69 // generates a transmission start
roselea 0:df1c8f2961a1 70 // _____ ________
roselea 0:df1c8f2961a1 71 // DATA: |_______|
roselea 0:df1c8f2961a1 72 // ___ ___
roselea 0:df1c8f2961a1 73 // SCK : ___| |___| |______
roselea 0:df1c8f2961a1 74 {
roselea 0:df1c8f2961a1 75 data.input();
roselea 0:df1c8f2961a1 76 sclk=0; //Initial state
fblanc 1:0dbbb4802508 77 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 78 sclk=1;
fblanc 1:0dbbb4802508 79 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 80 data.output(); // data low
fblanc 1:0dbbb4802508 81 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 82 sclk=0;
fblanc 1:0dbbb4802508 83 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 84 sclk=1;
fblanc 1:0dbbb4802508 85 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 86 data.input(); // allow data to high
fblanc 1:0dbbb4802508 87 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 88 sclk=0;
fblanc 1:0dbbb4802508 89 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 90 }
roselea 0:df1c8f2961a1 91
roselea 0:df1c8f2961a1 92 void SHT::connection_reset(void)
roselea 0:df1c8f2961a1 93 //----------------------------------------------------------------------------------
roselea 0:df1c8f2961a1 94 // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
roselea 0:df1c8f2961a1 95 // _____________________________________________________ ________
roselea 0:df1c8f2961a1 96 // DATA: |_______|
roselea 0:df1c8f2961a1 97 // _ _ _ _ _ _ _ _ _ ___ ___
roselea 0:df1c8f2961a1 98 // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
roselea 0:df1c8f2961a1 99 {
roselea 0:df1c8f2961a1 100 int i;
roselea 0:df1c8f2961a1 101 data.input(); // allow data high
roselea 0:df1c8f2961a1 102 sclk=0; // and clk low
roselea 0:df1c8f2961a1 103 for (i=0;i<9;i++) { // 9 SCK cycles
fblanc 1:0dbbb4802508 104 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 105 sclk=1;
fblanc 1:0dbbb4802508 106 wait_us(MICROSECONDE);
roselea 0:df1c8f2961a1 107 sclk=0;
roselea 0:df1c8f2961a1 108 }
roselea 0:df1c8f2961a1 109 }
fblanc 1:0dbbb4802508 110
roselea 0:df1c8f2961a1 111 char SHT::soft_reset(void)
roselea 0:df1c8f2961a1 112 //----------------------------------------------------------------------------------
roselea 0:df1c8f2961a1 113 // resets the sensor by a softreset
roselea 0:df1c8f2961a1 114 {
roselea 0:df1c8f2961a1 115 char error=0;
roselea 0:df1c8f2961a1 116 SHT::connection_reset(); //reset communication
roselea 0:df1c8f2961a1 117 trans_start();
roselea 0:df1c8f2961a1 118 error+=write_byte(com_reset); //send RESET-command to sensor
roselea 0:df1c8f2961a1 119 return error; //error=1 in case of no response form the sensor
roselea 0:df1c8f2961a1 120 }
roselea 0:df1c8f2961a1 121
roselea 0:df1c8f2961a1 122 char SHT::read_status(byte &value)
roselea 0:df1c8f2961a1 123 //----------------------------------------------------------------------------------
roselea 0:df1c8f2961a1 124 // reads the status register with checksum (8-bit)
roselea 0:df1c8f2961a1 125 {
roselea 0:df1c8f2961a1 126 //byte checksum;
roselea 0:df1c8f2961a1 127
roselea 0:df1c8f2961a1 128 char error=0;
roselea 0:df1c8f2961a1 129 trans_start(); //transmission start
roselea 0:df1c8f2961a1 130 error=write_byte(com_read_status_reg); //send command to sensor
roselea 0:df1c8f2961a1 131 value=read_byte(send_ack); //read status register (8-bit)
roselea 0:df1c8f2961a1 132 /* checksum= */
roselea 0:df1c8f2961a1 133 (void)read_byte(no_ack); //read checksum (8-bit)
roselea 0:df1c8f2961a1 134 // check the checksum ??
roselea 0:df1c8f2961a1 135 return error; //error=1 in case of no response form the sensor
roselea 0:df1c8f2961a1 136 }
roselea 0:df1c8f2961a1 137
roselea 0:df1c8f2961a1 138 char SHT::write_status(byte value)
roselea 0:df1c8f2961a1 139 //----------------------------------------------------------------------------------
roselea 0:df1c8f2961a1 140 // writes the status register (8-bit)
roselea 0:df1c8f2961a1 141 {
roselea 0:df1c8f2961a1 142 char error=0;
roselea 0:df1c8f2961a1 143 trans_start(); //transmission start
roselea 0:df1c8f2961a1 144 error+=write_byte(com_write_status_reg); //send command to sensor
roselea 0:df1c8f2961a1 145 error+=write_byte(value); //send value of status register
roselea 0:df1c8f2961a1 146 return error; //error>=1 in case of no response form the sensor
roselea 0:df1c8f2961a1 147 }
roselea 0:df1c8f2961a1 148
roselea 0:df1c8f2961a1 149 char SHT::measure(int &value, byte command)
roselea 0:df1c8f2961a1 150 //----------------------------------------------------------------------------------
roselea 0:df1c8f2961a1 151 // makes a measurement (humidity/temperature) with checksum
roselea 0:df1c8f2961a1 152 {
roselea 0:df1c8f2961a1 153 unsigned int i;
roselea 0:df1c8f2961a1 154 byte msb;
roselea 0:df1c8f2961a1 155 // byte checksum;
roselea 0:df1c8f2961a1 156
roselea 0:df1c8f2961a1 157 trans_start(); //transmission start
roselea 0:df1c8f2961a1 158 if (write_byte(command)) return 1; // if command fails return
roselea 0:df1c8f2961a1 159
roselea 0:df1c8f2961a1 160 for (i=10000;i;i--) { //wait until sensor has finished the measurement
roselea 0:df1c8f2961a1 161 wait_us(100);
roselea 0:df1c8f2961a1 162 if (data==0) break;
roselea 0:df1c8f2961a1 163 }
roselea 0:df1c8f2961a1 164 if (data) return 1; // or timeout (~1 sec.) is reached !!
roselea 0:df1c8f2961a1 165 msb = read_byte(send_ack); //read the first byte (MSB)
roselea 0:df1c8f2961a1 166 value = msb*256 + read_byte(send_ack); //read the second byte (LSB)
roselea 0:df1c8f2961a1 167 /* checksum= */
roselea 0:df1c8f2961a1 168 (void)read_byte(no_ack); //read checksum
roselea 0:df1c8f2961a1 169 return 0;
roselea 0:df1c8f2961a1 170 }
roselea 0:df1c8f2961a1 171
roselea 0:df1c8f2961a1 172 void SHT::calculate()
roselea 0:df1c8f2961a1 173 //----------------------------------------------------------------------------------------
fblanc 1:0dbbb4802508 174 // calculates temperature [�C] and humidity [%RH]
roselea 0:df1c8f2961a1 175 // input : hum [Ticks] (12 bit)
roselea 0:df1c8f2961a1 176 // temp [Ticks] (14 bit)
roselea 0:df1c8f2961a1 177 // output: humidity [%RH]
fblanc 1:0dbbb4802508 178 // temperature [�C]
roselea 0:df1c8f2961a1 179 {
fblanc 1:0dbbb4802508 180 //Optimized V4 humidity conversion coefficients
fblanc 1:0dbbb4802508 181 const float C1=-2.0468; // for 12 Bit
fblanc 1:0dbbb4802508 182 const float C2=0.0367; // for 12 Bit
fblanc 1:0dbbb4802508 183 const float C3=-1.5955E-6; // for 12 Bit
fblanc 1:0dbbb4802508 184 const float T1=0.01; // for 12
fblanc 1:0dbbb4802508 185 const float T2=0.00008; // for 12 Bit
fblanc 1:0dbbb4802508 186 const float D1= -40.1; //for °C 5V
fblanc 1:0dbbb4802508 187 const float D2= 0.01 ; //for °C for 14
roselea 0:df1c8f2961a1 188 float rh; // rh: Humidity [Ticks] 12 Bit
roselea 0:df1c8f2961a1 189 float t; // t: Temperature [Ticks] 14 Bit
fblanc 1:0dbbb4802508 190 float rh_lin; // rh_lin: Humidity linear
roselea 0:df1c8f2961a1 191 if (accuracy==SHT_low) {
roselea 0:df1c8f2961a1 192 rh=hum*16; // rescale to high accuracy values - 8 to 12 bits
roselea 0:df1c8f2961a1 193 t=temp*4; // and 12 to 14 bits
roselea 0:df1c8f2961a1 194 } else {
roselea 0:df1c8f2961a1 195 rh=hum;
roselea 0:df1c8f2961a1 196 t=temp;
roselea 0:df1c8f2961a1 197 }
roselea 0:df1c8f2961a1 198
fblanc 1:0dbbb4802508 199 temperature=D1 + D2*t ; //calc. temperature from ticks to [�C]
fblanc 1:0dbbb4802508 200 rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
fblanc 1:0dbbb4802508 201 humidity =(temperature-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH] (ignore as never >0.25%)
roselea 0:df1c8f2961a1 202 if (humidity>100)humidity=100; //cut if the value is outside of
roselea 0:df1c8f2961a1 203 if (humidity<0.1)humidity=0.1; //the physical possible range
roselea 0:df1c8f2961a1 204 }
roselea 0:df1c8f2961a1 205
roselea 0:df1c8f2961a1 206 float SHT::get_temperature() { // get the most recent temp reading
roselea 0:df1c8f2961a1 207 return temperature;
roselea 0:df1c8f2961a1 208 }
roselea 0:df1c8f2961a1 209
roselea 0:df1c8f2961a1 210 float SHT::get_humidity() { // get the most recent humidity reading
roselea 0:df1c8f2961a1 211 return humidity;
roselea 0:df1c8f2961a1 212 }
roselea 0:df1c8f2961a1 213
roselea 0:df1c8f2961a1 214 float SHT::get_dewpoint() { // get the most recent dewpoint value
roselea 0:df1c8f2961a1 215 return dewpoint;
roselea 0:df1c8f2961a1 216 }
roselea 0:df1c8f2961a1 217
fblanc 1:0dbbb4802508 218 int SHT::update(SHT_acc acc) { // update stored values from sensor
roselea 0:df1c8f2961a1 219 int error=0;
fblanc 1:0dbbb4802508 220 soft_reset();
fblanc 1:0dbbb4802508 221 //connection_reset();
roselea 0:df1c8f2961a1 222 if (acc!=accuracy) {
roselea 0:df1c8f2961a1 223 accuracy=acc;
roselea 0:df1c8f2961a1 224 error+=write_status((acc==SHT_low)?0x01:0x00); //set the status reg to high or low accuarcy
roselea 0:df1c8f2961a1 225 }
roselea 0:df1c8f2961a1 226 error+=measure(temp,com_measure_temp);
roselea 0:df1c8f2961a1 227 error+=measure(hum,com_measure_humid);
roselea 0:df1c8f2961a1 228 if (!error) calculate();
fblanc 1:0dbbb4802508 229 return error;
roselea 0:df1c8f2961a1 230 }