Stephen McGarry
/
SHT_v1
Revision 0:df1c8f2961a1, committed 2010-01-24
- Comitter:
- roselea
- Date:
- Sun Jan 24 22:00:35 2010 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r df1c8f2961a1 SHT.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHT.cpp Sun Jan 24 22:00:35 2010 +0000 @@ -0,0 +1,224 @@ +/* mbed module to use a Sensirion SHT1x /SHT7x sensor + * Copyright (c) 2007-2009 Stephen McGarry + * Released under the MIT License: http://mbed.org/license/mit + */ + +#include "SHT.h" + +#include "mbed.h" + +SHT::SHT(PinName p_sclk, PinName p_data, SHT_acc p_accuracy) : sclk(p_sclk), data(p_data), accuracy(p_accuracy) { + sclk=0; + data=0; // data pin will be used as open collector pin + data.mode(PullUp); // with the pull up internally active + data.input(); // with line released to go high + temperature = humidity = dewpoint=0.0f; + printf("constructor\n"); +} + +char SHT::write_byte(byte value) +//---------------------------------------------------------------------------------- +// writes a byte on the Sensibus and checks the acknowledge +{ + int i; + char error=0; + + for (i=0x80;i>0;i/=2) { //shift bit for masking + if (i & value) data.input(); //masking value with i , write to SENSI-BUS + else data.output(); + wait_us(1); //ensure sclk is low for min time + sclk=1; //clk for SENSI-BUS + wait_us(1); //pulsewith approx. 2 us + sclk=0; + } + data.input(); //release DATA-line + wait_us(1); //ensure sclk is low for min time + sclk=1; //clk #9 for ack + error=data; //check ack (DATA will be pulled down by SHT11) + wait_us(1); + sclk=0; + return error; //error=1 in case of no acknowledge +} + +byte SHT::read_byte(bool send_ack) +//---------------------------------------------------------------------------------- +// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" +{ + byte i,val=0; + data.input(); //release DATA-line + for (i=0x80;i>0;i/=2) { //shift bit for masking + wait_us(1); + sclk=1; //clk for SENSI-BUS + if (data) val=(val | i); //read bit + wait_us(1); + sclk=0; + } + wait_us(1); + if (send_ack) data.output(); // if ack needed then drive data low + sclk=1; //clk #9 for ack + wait_us(1); + sclk=0; + data.input(); //release DATA-line + return val; +} + +void SHT::trans_start(void) +//---------------------------------------------------------------------------------- +// generates a transmission start +// _____ ________ +// DATA: |_______| +// ___ ___ +// SCK : ___| |___| |______ +{ + data.input(); + sclk=0; //Initial state + wait_us(1); + sclk=1; + wait_us(1); + data.output(); // data low + wait_us(1); + sclk=0; + wait_us(1); + sclk=1; + wait_us(1); + data.input(); // allow data to high + wait_us(1); + sclk=0; + wait_us(1); +} + +void SHT::connection_reset(void) +//---------------------------------------------------------------------------------- +// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart +// _____________________________________________________ ________ +// DATA: |_______| +// _ _ _ _ _ _ _ _ _ ___ ___ +// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______ +{ + int i; + data.input(); // allow data high + sclk=0; // and clk low + for (i=0;i<9;i++) { // 9 SCK cycles + wait_us(1); + sclk=1; + wait_us(1); + sclk=0; + } +} +char SHT::soft_reset(void) +//---------------------------------------------------------------------------------- +// resets the sensor by a softreset +{ + char error=0; + SHT::connection_reset(); //reset communication + trans_start(); + error+=write_byte(com_reset); //send RESET-command to sensor + return error; //error=1 in case of no response form the sensor +} + +char SHT::read_status(byte &value) +//---------------------------------------------------------------------------------- +// reads the status register with checksum (8-bit) +{ + //byte checksum; + + char error=0; + trans_start(); //transmission start + error=write_byte(com_read_status_reg); //send command to sensor + value=read_byte(send_ack); //read status register (8-bit) + /* checksum= */ + (void)read_byte(no_ack); //read checksum (8-bit) + // check the checksum ?? + return error; //error=1 in case of no response form the sensor +} + +char SHT::write_status(byte value) +//---------------------------------------------------------------------------------- +// writes the status register (8-bit) +{ + char error=0; + trans_start(); //transmission start + error+=write_byte(com_write_status_reg); //send command to sensor + error+=write_byte(value); //send value of status register + return error; //error>=1 in case of no response form the sensor +} + +char SHT::measure(int &value, byte command) +//---------------------------------------------------------------------------------- +// makes a measurement (humidity/temperature) with checksum +{ + unsigned int i; + byte msb; + // byte checksum; + + trans_start(); //transmission start + if (write_byte(command)) return 1; // if command fails return + + for (i=10000;i;i--) { //wait until sensor has finished the measurement + wait_us(100); + if (data==0) break; + } + if (data) return 1; // or timeout (~1 sec.) is reached !! + msb = read_byte(send_ack); //read the first byte (MSB) + value = msb*256 + read_byte(send_ack); //read the second byte (LSB) + /* checksum= */ + (void)read_byte(no_ack); //read checksum + return 0; +} + +void SHT::calculate() +//---------------------------------------------------------------------------------------- +// calculates temperature [°C] and humidity [%RH] +// input : hum [Ticks] (12 bit) +// temp [Ticks] (14 bit) +// output: humidity [%RH] +// temperature [°C] +{ + 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; // rh: Humidity [Ticks] 12 Bit + float t; // t: Temperature [Ticks] 14 Bit + //float rh_lin; // rh_lin: Humidity linear + if (accuracy==SHT_low) { + rh=hum*16; // rescale to high accuracy values - 8 to 12 bits + t=temp*4; // and 12 to 14 bits + } else { + rh=hum; + t=temp; + } + + temperature=t*0.01 - 40; //calc. temperature from ticks to [°C] + humidity=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH] + // =(temperature-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH] (ignore as never >0.25%) + if (humidity>100)humidity=100; //cut if the value is outside of + if (humidity<0.1)humidity=0.1; //the physical possible range +} + +float SHT::get_temperature() { // get the most recent temp reading + return temperature; +} + +float SHT::get_humidity() { // get the most recent humidity reading + return humidity; +} + +float SHT::get_dewpoint() { // get the most recent dewpoint value + return dewpoint; +} + +void SHT::update(SHT_acc acc) { // update stored values from sensor + int error=0; + connection_reset(); + if (acc!=accuracy) { + accuracy=acc; + error+=write_status((acc==SHT_low)?0x01:0x00); //set the status reg to high or low accuarcy + } + error+=measure(temp,com_measure_temp); + error+=measure(hum,com_measure_humid); + if (!error) calculate(); + +}
diff -r 000000000000 -r df1c8f2961a1 SHT.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHT.h Sun Jan 24 22:00:35 2010 +0000 @@ -0,0 +1,66 @@ +/* mbed module to use a Sensirion SHT1x /SHT7x sensor + * Copyright (c) 2007-2009 Stephen McGarry + * Released under the MIT License: http://mbed.org/license/mit + */ +#ifndef SHT_H +#define SHT_H + +#include "mbed.h" + +enum SHT_acc { + SHT_low=0, + SHT_high=1 +}; + +typedef unsigned char byte; + +class SHT : public Base { +public: + /* Constructor: SHT + * Creates an SHT interface connected to specific pins. + * + */ + SHT(PinName p_sclk, PinName p_data, SHT_acc p_accuracy); + + /* Functions + */ + float get_temperature(); // get the most recent temp reading + float get_humidity(); // get the most recent humidity reading + float get_dewpoint(); // get the most recent dewpoint value + void update(SHT_acc accuracy); // update stored values from sensor + +protected: + byte read_byte(bool send_ack); + char write_byte(byte value); + void trans_start(void); + void connection_reset(void); + char soft_reset(); + char read_status(byte &value); + char write_status(byte value); + char measure(int &value, byte mode); + void calculate(); + + DigitalOut sclk; + DigitalInOut data; + SHT_acc accuracy; // will we use high or low accuracy mode on the sensor + + float temperature; // calculated from sensor reading + float humidity; + float dewpoint; + int temp,hum; // integer values from sensor before conversion + + enum commands { + com_read_status_reg=0x06, + com_write_status_reg=0x07, + com_measure_temp=0x03, + com_measure_humid=0x05, + com_reset=0x1E + }; + + enum acks { + no_ack=0, + send_ack=1 + }; +}; + +#endif \ No newline at end of file
diff -r 000000000000 -r df1c8f2961a1 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Jan 24 22:00:35 2010 +0000 @@ -0,0 +1,20 @@ +// simple test for SHT temp modules + +#include "mbed.h" + +#include "SHT.h" + +SHT th1(p5,p6,SHT_high); // sclock, data + +DigitalOut led1(LED1); + +int main() { + while(1) { + th1.update(SHT_high); + printf("t:%6.2fC h:%6.2f%%\n",th1.get_temperature(),th1.get_humidity()); + led1=!led1; + wait(1); + } + +} +
diff -r 000000000000 -r df1c8f2961a1 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sun Jan 24 22:00:35 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0