mbed Weather Platform firmware http://mbed.org/users/okini3939/notebook/mbed-weather-platform-firmware/
Dependencies: ChaNFSSD EthernetNetIf I2CLEDDisp Agentbed ChaNFSUSB ILinterpreter mbed BMP085 WeatherMeters ConfigFile ChaNFS I2CLCD
SHT_v1/SHT.cpp
- Committer:
- okini3939
- Date:
- 2012-03-16
- Revision:
- 8:bed0b81794ba
- Parent:
- 0:bdb53686c194
File content as of revision 8:bed0b81794ba:
/* 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(); }