Humidity and Temperature Sensor - Sensirion SHT1x driver
Fork of SHTx by
Revision 0:d55659b0c4a0, committed 2010-11-18
- Comitter:
- NegativeBlack
- Date:
- Thu Nov 18 10:23:43 2010 +0000
- Child:
- 1:8465801be23f
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i2c.cpp Thu Nov 18 10:23:43 2010 +0000 @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2010 Roy van Dam <roy@negative-black.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "i2c.hpp" + +namespace SHTx { + I2C::I2C(PinName sda, PinName scl) : + scl_pin(scl), sda_pin(sda), frequency(10) { + this->sda_pin.output(); + this->scl_pin.output(); + } + + void + I2C::setFrequency(uint32_t hz) { + this->frequency = (1000000 / hz); + } + + void + I2C::start(void) { + this->output(); + this->sda(1); + this->scl(1); + this->sda(0); + this->scl(0); + this->scl(1); + this->sda(1); + this->scl(0); + } + + void + I2C::stop(void) { + this->output(); + this->sda(0); + this->scl(1); + this->sda(1); + } + + bool + I2C::wait(void) { + bool ack = false; + + this->input(); + for (uint8_t i = 0; i < 500 && !ack; i++) { + ack = !this->sda_pin; + wait_ms(1); + } + + return ack; + } + + bool + I2C::write(uint8_t data) { + bool ack; + + this->output(); + for (uint8_t i = 8; i; i--) { + this->shift_out(data & 0x80); + data <<= 1; + } + + this->input(); + ack = !this->shift_in(); + + return ack; + } + + uint8_t + I2C::read(bool ack) { + uint8_t data = 0; + + this->input(); + for (uint8_t i = 8; i; i--) { + data <<= 1; + data |= this->shift_in(); + } + + this->output(); + this->shift_out(!ack); + + return data; + } + + void + I2C::output(void) { + this->sda_pin.output(); + } + + void + I2C::input(void) { + this->sda_pin.input(); + } + + void + I2C::sda(bool value) { + this->sda_pin = value; + wait_us(this->frequency); + } + + void + I2C::scl(bool value) { + this->scl_pin = value; + wait_us(this->frequency); + } + + void + I2C::shift_out(bool bit) { + this->sda(bit); + this->scl(1); + this->scl(0); + } + + bool + I2C::shift_in(void) { + wait_us(this->frequency); + this->scl(1); + bool bit = this->sda_pin; + this->scl(0); + return bit; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i2c.hpp Thu Nov 18 10:23:43 2010 +0000 @@ -0,0 +1,161 @@ +/** + * Copyright (c) 2010 Roy van Dam <roy@negative-black.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _I2C_HPP_ +#define _I2C_HPP_ + +#include "mbed.h" + +namespace SHTx { + /** + * Class: I2C + * Humidity and Temperature Sensor - SHT15 + * I2C Bit-bang master driver. + */ + class I2C { + private: + DigitalInOut scl_pin; + DigitalInOut sda_pin; + + uint32_t frequency; + + public: + /** + * Constructor: SHTx::I2C + * Create an I2C Master interface, connected to the specified pins. + * Bit-bang I2C driver to get around the lousy I2C implementation in the + * SHTx interface... + * + * Variables: + * sda - I2C data line pin + * scl - I2C clock line pin + */ + I2C(PinName sda, PinName scl); + + /** + * Function: setFrequency + * Set the frequency of the SHTx::I2C interface + * + * Variables: + * hz - The bus frequency in hertz + */ + void setFrequency(uint32_t hz); + + /** + * Function: start + * Issue start condition on the SHTx::I2C bus + */ + void start(void); + + /** + * Function: stop + * Issue stop condition on the SHTx::I2C bus + */ + void stop(void); + + /** + * Function: wait + * Wait for SHT15 to complete measurement. + * Max timeout 500ms. + * + * Variables: + * returns - true if an ACK was received, false otherwise + */ + bool wait(void); + + /** + * Function: write + * Write single byte out on the SHTx::I2C bus + * + * Variables: + * data - data to write out on bus + * returns - true if an ACK was received, false otherwise + */ + bool write(uint8_t data); + + /** + * Function: write + * Read single byte form the I2C bus + * + * Variables: + * ack - indicates if the byte is to be acknowledged + * returns - the read byte + */ + uint8_t read(bool ack); + + private: + /** + * Function: output + * Configures sda pin as output + */ + void output(void); + + /** + * Function: input + * Configures sda pin as input + */ + void input(void); + + /** + * Function: sda + * Drive sda pin. + * + * Variables: + * value - drive pin high or low + */ + void sda(bool value); + + /** + * Function: scl + * Drive scl pin. + * + * Variables: + * value - drive pin high or low + */ + void scl(bool value); + + /** + * Function: shift_out + * Write single bit out on the SHTx::I2C bus + * + * Variables: + * bit - value of the bit to be written. + */ + void shift_out(bool bit); + + /** + * Function: shift_in + * Read single bit from the SHTx::I2C bus + * + * Variables: + * return - value of the bit read. + */ + bool shift_in(void); + }; +} + +/* !_I2C_HPP_ */ +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sht15.cpp Thu Nov 18 10:23:43 2010 +0000 @@ -0,0 +1,220 @@ +/** + * Copyright (c) 2010 Roy van Dam <roy@negative-black.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sht15.hpp" + +namespace SHTx { + SHT15::SHT15(PinName sda, PinName scl): i2c(sda, scl) { + this->ready = true; + wait_ms(11); + } + + float + SHT15::getTemperature(void) { + return this->convertTemperature( + this->temperature, + this->getFlag(flag_resolution), + this->scale + ); + } + + float + SHT15::getHumidity(void) { + return this->convertHumidity( + this->humidity, + this->temperature, + this->getFlag(flag_resolution) + ); + } + + bool + SHT15::checkBattery(void) { + this->readRegister(cmd_read_register); + return this->getFlag(flag_battery); + } + + bool + SHT15::setHeater(bool value) { + this->setFlag(flag_heater, value); + return this->writeRegister(); + } + + bool + SHT15::setResolution(bool value) { + this->setFlag(flag_resolution, value); + return this->writeRegister(); + } + + void + SHT15::setScale(bool value) { + this->scale = value; + } + + bool + SHT15::update(void) { + if ((this->ready == false) || + !this->readRegister(cmd_read_temperature) || + !this->readRegister(cmd_read_humidity)) { + return false; + } + + return true; + } + + bool + SHT15::reset(void) { + while (this->ready == false) { + continue; + } + + this->ready = false; + this->i2c.start(); + bool ack = this->i2c.write(cmd_reset_device); + this->i2c.stop(); + this->ready = true; + + if (ack) { + this->status_register = 0; + this->humidity = 0; + this->temperature = 0; + wait_ms(11); + return true; + } + + return false; + } + + float + SHT15::convertTemperature(uint16_t sot, bool res, bool scale) { + // Temperature conversion coefficients + float d1 = this->coefficient.dv[scale]; + float d2 = ((scale) ? this->coefficient.df[res] + : this->coefficient.dc[res]); + + // Temperature data conversion + return d1 + (d2 * (float)(sot)); + } + + float + SHT15::convertHumidity(uint16_t sohr, uint16_t sot, bool res) { + // Humidity conversion coefficients + float c1 = this->coefficient.c1[res]; + float c2 = this->coefficient.c2[res]; + float c3 = this->coefficient.c3[res]; + + // Temperature compensation coefficients + float t1 = this->coefficient.t1[res]; + float t2 = this->coefficient.t2[res]; + + // Temperature data conversion to celcius + float temp = this->convertTemperature(sot, res, false); + + // Humidity data conversion to relative humidity + float humid = c1 + (c2 * (float)(sohr)) + (c3 * (float)(sohr * sohr)); + + // Calculate temperature compensation + return (temp - 25) + (t1 + (t2 * (float)(sohr)) + humid); + } + + bool + SHT15::writeRegister(void) { + while (this->ready == false) { + continue; + } + + this->ready = false; + this->i2c.start(); + + if (this->i2c.write(cmd_write_register)) { + this->i2c.write(this->status_register); + } + + this->i2c.stop(); + this->ready = true; + + return true; + } + + bool + SHT15::readRegister(cmd_list command) { + while (this->ready == false) { + continue; + } + + this->ready = false; + this->i2c.start(); + + if (!this->i2c.write(command)) { + this->i2c.stop(); + return false; + } + + switch (command) { + case cmd_read_temperature: { + if (!this->i2c.wait()) { + this->i2c.stop(); + return false; + } + + this->temperature = this->i2c.read(1) << 8; + this->temperature |= this->i2c.read(0); + } break; + + case cmd_read_humidity: { + if (!this->i2c.wait()) { + this->i2c.stop(); + return false; + } + + this->humidity = this->i2c.read(1) << 8; + this->humidity |= this->i2c.read(0); + } break; + + case cmd_read_register: { + this->status_register = this->i2c.read(0); + } break; + } + + this->i2c.stop(); + this->ready = true; + + return true; + } + + bool + SHT15::getFlag(SHT15::flag_list flag) { + return (this->status_register & flag) ? true : false; + } + + void + SHT15::setFlag(SHT15::flag_list flag, bool value) { + if (value) { + this->status_register |= flag; + } else { + this->status_register &= ~flag; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sht15.hpp Thu Nov 18 10:23:43 2010 +0000 @@ -0,0 +1,249 @@ +/** + * Copyright (c) 2010 Roy van Dam <roy@negative-black.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SHT15_HPP_ +#define _SHT15_HPP_ + +#include "mbed.h" +#include "i2c.hpp" + +namespace SHTx { + /** + * Class: SHT15 + * Humidity and Temperature Sensor - SHT15 + * High level software interface. + */ + class SHT15 { + private: + I2C i2c; + + bool ready; + bool scale; + + uint8_t status_register; + uint16_t humidity; + uint16_t temperature; + + struct coefficients { + // Humidity conversion coefficients + float c1[2], c2[2], c3[2]; + + // Temperature conversion coefficients + float dc[2], df[2], dv[2]; + + // Temperature compensation coefficients + float t1[2], t2[2]; + + // Initialize table + coefficients(void) { + c1[0] = -2.046f; c2[1] = -2.046f; + c2[0] = 0.036f; c2[1] = 0.587f; + c3[0] = -0.0000015955f; c2[1] = -0.00040845f; + + dc[0] = 0.01f; dc[1] = 0.04f; + df[0] = 0.018f; df[1] = 0.072f; + dv[0] = -39.7f; dv[1] = -39.5f; + + t1[0] = 0.01f; t1[1] = 0.01f; + t2[0] = 0.00008f; t2[1] = 0.00128f; + }; + } coefficient; + + enum cmd_list { + cmd_read_temperature = 0x03, + cmd_read_humidity = 0x05, + cmd_read_register = 0x07, + cmd_write_register = 0x06, + cmd_reset_device = 0x1E + }; + + enum flag_list { + flag_resolution = 0x01, + flag_reset = 0x02, + flag_heater = 0x04, + flag_battery = 0x40 + }; + + public: + /* + * Initializes I2C interface and waits + * the 11ms device initialization time. + */ + SHT15(PinName sda, PinName scl); + + /** + * Function: getTemperature + * Returns the current temperature. + * + * Values: + * returns - current temperature. + */ + float getTemperature(void); + + /** + * Function: getHumidity + * Returns the current relative humidity. + * + * Values: + * returns - relative humidity. + */ + float getHumidity(void); + + /** + * Function: checkBattery + * Returns true if battery voltage drops + * below 2.4 volt. + * + * Values: + * returns - true on low battery, false otherwise + */ + bool checkBattery(void); + + /** + * Function: setHeater + * Enable on chip heating element. The heater may + * increase the temperature of the sensor by 5C to + * 10C beyond ambient temperature. + * + * Values: + * value - true->on, false->off + * return - operation result + */ + bool setHeater(bool value); + + /** + * Function: setResolution + * Set lower measurement resolution to allow + * faster update frequencies. + * + * Resolutions + * low: 8bit humid. - 12bit temp. + * high: 12bit humid. - 14bit temp. + * + * Values: + * value - true->low, false->high + * return - operation result + */ + bool setResolution(bool value); + + /** + * Function: setScale + * Sets output scale to fahrenheit or celcius. + * + * Values: + * value - true->fahrenheit, false->celcius + */ + void setScale(bool value); + + /** + * Function: update + * Performs humidity and temperature + * sensor readout of the chip. + * + * Values: + * return - operation result + */ + bool update(void); + + /** + * Function: reset + * Performs full chip reset. + * + * Values: + * return - operation result + */ + bool reset(void); + + private: + + /** + * Function: convertTemperature + * Convert sensor data to human readable value + * on the farenheit or celcius scale. + * + * Values: + * sot - raw temperatue sensor output + * res - true->low, false->high + * scale - true->fahrenheit, false->celcius + * return - temperature + */ + float convertTemperature(uint16_t sot, bool res = false, bool scale = false); + + /** + * Function: convertHumidity + * Convert sensor data to relative humidity + * in percentage. + * + * Values: + * sohr - raw humidity sensor output + * sot - raw temperatue sensor output + * res - true->low, false->high + * return - relative humidity + */ + float convertHumidity(uint16_t sohr, uint16_t sot, bool res = false); + + /** + * Function: writeRegister + * Write internal chip register. + * + * Values: + * return - operation result + */ + bool writeRegister(void); + + /** + * Function: readRegister + * Reads internal chip register + * + * Values: + * command - register to be accessed + * return - operation result + */ + bool readRegister(cmd_list command); + + /** + * Function: setFlag + * Modify local register flag. + * + * Values: + * flag - flag to be modified + * value - value to be assigned + */ + void setFlag(flag_list flag, bool value); + + /** + * Function: getFlag + * Get local register flag. + * + * Values: + * returns - flag value + */ + bool getFlag(flag_list flag); + }; +} + +/* !_SHT15_HPP_ */ +#endif \ No newline at end of file