|
|
View previous topic :: View next topic |
Author |
Message |
rrb011270
Joined: 07 Sep 2003 Posts: 51
|
Sensirion SHT11 Humidity & Temp Sensor |
Posted: Mon Sep 15, 2003 6:11 pm |
|
|
Mabuhay!
Anybody have tried to make a driver for the sensirion SHT11 humidity and temperature sensor?
Anyone can share light on this device for PIC18452? a sample code will help.
Thnx |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Guest
|
|
Posted: Tue Sep 16, 2003 12:08 am |
|
|
I tried it but it has error in expression:
float rh=*p_humidity; --> expression must evaluate to a constant.
|
|
|
Steve H. Guest
|
Sensirion SHT 11 Humidity Sensor |
Posted: Tue Sep 16, 2003 12:55 am |
|
|
I have a project documented at,
http://www.analoghome.com/projects/dewpointer.html
Contact me at the mailto box on that page if you would like to chat more.
It works pretty neat! :-)
Steve H. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 16, 2003 1:24 am |
|
|
I can see that they've changed the code since I last worked on it.
To fix that problem, you need to declare rh and t without
setting them equal to a value.
Then, down below the declarations, you should put in
two lines of code that set rh and t to their initial values.
See the code below:
Code: |
void calc_sth11(float *p_humidity ,float *p_temperature)
{
const float C1 = -4.0;
const float C2 = 0.0405;
const float C3 = -0.0000028;
const float T1 = 0.01;
const float T2 = 0.00008;
float rh; // Declare rh
float t; // Declare t
float rh_lin;
float rh_true;
float t_C;
rh = *p_humidity; // Set rh to its initial value
t = *p_temperature; // Set t to its initial value
|
|
|
|
Guest
|
it compile but not working... |
Posted: Tue Sep 16, 2003 4:14 am |
|
|
Mabuhay!
I try the edited code... CCS compile it but the code will not generate any data at the serial monitor for temp display and humidity.
I'll review the code... any help in debugging will help..
thnx
PCM programmer wrote: | I can see that they've changed the code since I last worked on it.
To fix that problem, you need to declare rh and t without
setting them equal to a value.
Then, down below the declarations, you should put in
two lines of code that set rh and t to their initial values.
See the code below:
Code: |
void calc_sth11(float *p_humidity ,float *p_temperature)
{
const float C1 = -4.0;
const float C2 = 0.0405;
const float C3 = -0.0000028;
const float T1 = 0.01;
const float T2 = 0.00008;
float rh; // Declare rh
float t; // Declare t
float rh_lin;
float rh_true;
float t_C;
rh = *p_humidity; // Set rh to its initial value
t = *p_temperature; // Set t to its initial value
|
|
|
|
|
rrb011270
Joined: 07 Sep 2003 Posts: 51
|
|
Posted: Wed Sep 24, 2003 9:33 pm |
|
|
Mabuhay!
I modify the code of sensirion temperature/humiduty sensors that is located at sensirion website but unfortunately, the result i get from the serial port monitor does not change its value and/or erroneous results.
One more thing, the formula I guess has a typo error...
Can anybody check the code? verify the formula?
I need help on this....
Thnx
Quote: |
#include <18F452.h> //Microcontroller specific library, e.g. port definitions
//#device ICD=TRUE // with an ICD debugger
#fuses HS,NOLVP,NOWDT,PUT // high speed, no watch dog timer
#use delay (clock=20000000) // 20MHz clock
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <math.h>
#include <LCD.C>
typedef union
{ long i;
float f;
} value;
//----------------------------------------------------------------------------------
// modul-var
//----------------------------------------------------------------------------------
enum {TEMP,HUMI};
//#define DATA P1_1
//#define SCK P1_0
#define DATA PIN_A0
#define SCK PIN_A1
#define noACK 0
#define ACK 1
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
//----------------------------------------------------------------------------------
char s_write_byte(char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
char i,error=0;
for (i=0x80;i>0;i/=2) //shift bit for masking
{ if (i & value) output_high(DATA); // DATA=1; //masking value with i , write to SENSI-BUS
else output_low(DATA); //DATA=0;
output_high(SCK); //SCK=1; //clk for SENSI-BUS
delay_us(2); //_nop_();_nop_();_nop_(); //pulswith approx. 5 us
delay_us(2);
delay_us(2);
output_low(SCK); //SCK=0;
}
output_high(DATA); //DATA=1; //release DATA-line
output_high(SCK); //SCK=1; //clk #9 for ack
error=input(DATA); //DATA; //check ack (DATA will be pulled down by SHT11)
output_low(SCK); //SCK=0;
return(error); //error=1 in case of no acknowledge
}
//----------------------------------------------------------------------------------
char s_read_byte(char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
char i,val=0;
output_high(DATA); //DATA=1; //release DATA-line
for (i=0x80;i>0;i/=2) //shift bit for masking
{
output_high(SCK); //SCK=1; //clk for SENSI-BUS
if (input(DATA)) val=(val | i); //read bit
output_low(SCK); //SCK=0;
}
if (input(DATA)==!ack) //in case of "ack==1" pull down DATA-Line
output_low(DATA);
output_high(SCK); //SCK=1; //clk #9 for ack
delay_us(2); //_nop_();
delay_us(2); //_nop_();
delay_us(2); //_nop_(); //pulswith approx. 5 us
output_low(SCK); //SCK=0;
output_high(DATA); //DATA=1; //release DATA-line
return(val);
}
//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
{
output_high(DATA); // DATA=1;
output_low(SCK); // SCK=0; //Initial state
delay_us(2); // _nop_();
output_high(SCK); // SCK=1;
delay_us(2); // _nop_();
output_low(DATA); // DATA=0;
delay_us(2); // _nop_();
output_low(SCK); // SCK=0;
delay_us(2); // _nop_();
delay_us(2); // _nop_();
delay_us(2); // _nop_();
output_high(SCK); // SCK=1;
delay_us(2); // _nop_();
output_high(DATA); // DATA=1;
delay_us(2); // _nop_();
output_low(SCK); // SCK=0;
}
//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
{
char i;
output_high(DATA); // DATA=1;
for(i=0;i<9;i++) // 9 SCK cycles
{
output_high(SCK); // SCK=1;
output_low(SCK); // SCK=0;
}
s_transstart(); //transmission start
}
//----------------------------------------------------------------------------------
char s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset
{
char error=0;
s_connectionreset(); //reset communication
error+=s_write_byte(RESET); //send RESET-command to sensor
return(error); //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_read_statusreg(char *p_value,char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
char error=0;
s_transstart(); //transmission start
error=s_write_byte(STATUS_REG_R); //send command to sensor
*p_value=s_read_byte(ACK); //read status register (8-bit)
*p_checksum=s_read_byte(noACK); //read checksum (8-bit)
return(error); //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_write_statusreg(char *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
char error=0;
s_transstart(); //transmission start
error+=s_write_byte(STATUS_REG_W);//send command to sensor
error+=s_write_byte(*p_value); //send value of status register
return(error); //error>=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_measure(char *p_value,char *p_checksum,char mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
char error=0;
long i;
s_transstart(); //transmission start
switch(mode){ //send command to sensor
case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i<65535;i++) if(input(DATA)==0) break; //wait until sensor has finished the measurement
if(input(DATA)) error+=1; // or timeout (~2 sec.) is reached
*(p_value) =s_read_byte(ACK); //read the first byte (MSB)
*(p_value+1)=s_read_byte(ACK); //read the second byte (LSB)
*p_checksum =s_read_byte(noACK); //read checksum
return(error);
}
/*
//----------------------------------------------------------------------------------
void init_uart()
//----------------------------------------------------------------------------------
//9600 bps @ 11.059 MHz
{SCON = 0x52;
TMOD = 0x20;
TCON = 0x69;
TH1 = 0xfd;
}
*/
//----------------------------------------------------------------------------------------
void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------------
// calculates temperature [�C] and humidity [%RH]
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH]
// temp [�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; // Declare rh
float t; // Declare t
float rh_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature [�C]
rh = *p_humidity; // rh: Humidity [Ticks] 12 Bit
t = *p_temperature; // t: Temperature [Ticks] 14 Bit
t_C=t*0.01 - 40; //calc. temperature from ticks to [�C]
rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH]
if(rh_true>100) rh_true=100; //cut if the value is outside of
if(rh_true<0.1) rh_true=0.1; //the physical possible range
*p_temperature=t_C; //return temperature [�C]
*p_humidity=rh_true; //return humidity[%RH]
}
//--------------------------------------------------------------------
float calc_dewpoint(float h,float t)
//--------------------------------------------------------------------
// calculates dew point
// input: humidity [%RH], temperature [�C]
// output: dew point [�C]
{ float logEx,dew_point;
//logEx=0.66077+7.5*t/(237.3+t)+(log10(h)-2);
logEx=-1.33923+((7.5+t)/(237.3+t))+log10(h);
//dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
dew_point = ((0.66077-logEx)*237.3)/(logEx-8.16077);
return(dew_point);
}
//----------------------------------------------------------------------------------
void main()
//----------------------------------------------------------------------------------
// sample program that shows how to use SHT11 functions
// 1. connection reset
// 2. measure humidity [ticks](12 bit) and temperature [ticks](14 bit)
// 3. calculate humidity [%RH] and temperature [�C]
// 4. calculate dew point [�C]
// 5. print temperature, humidity, dew point
{
value humi_val,temp_val;
float dew_point;
char error,checksum;
long i;
int cmd;
/* connection reset */
s_connectionreset();
while(TRUE)
{
error=0;
error+=s_measure((char*) &humi_val.i,&checksum,HUMI); //measure humidity
error+=s_measure((char*) &temp_val.i,&checksum,TEMP); //measure temperature
if(error!=0) s_connectionreset(); //in case of an error: connection reset
else
{ humi_val.f=(float)humi_val.i; //converts integer to float
temp_val.f=(float)temp_val.i; //converts integer to float
calc_sth11(&humi_val.f,&temp_val.f); //calculate humidity, temperature
dew_point=calc_dewpoint(humi_val.f,temp_val.f); //calculate dew point
printf("\ntemp:%5.1fC humi:%5.1f%% \fdew point:%5.1fC",temp_val.f,humi_val.f,dew_point);
}
//----------wait approx. 0.8s to avoid heating up SHTxx------------------------------
for (i=0;i<40000;i++); //(be sure that the compiler doesn't eliminate this line!)
//-----------------------------------------------------------------------------------
}
}
| [/quote] |
|
|
adrian
Joined: 08 Sep 2003 Posts: 92 Location: Glasgow, UK
|
|
Posted: Thu Jun 10, 2004 8:12 am |
|
|
I see from this thread that there are people out there who have used this device. I have an application which I could use this device, but need to know if the SHT11 can co-exist on a network with other I2C devices. Can any one advise?
Secondly it looks as if the SHT11 has a different addressing structure to the standard I2C devices I am used to using, does the address for this thing really start at 0x03h?
I am assuming that the reserved address of 0x00h is reserved as it is the I2C general broadcast address?
Finally, as the SHT11 does not have any external addressing pins, I have to assume that I can only have one device on an I2C network? |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu Jun 10, 2004 8:28 am |
|
|
The SHT1X sensors are not completely I2C compatible. First, the Start signal implements a Start and Stop signal. I bit-bang the Start signal for the sensor and then use the standard I2C commands to address and read the sensor. I've found that the pull-up resistors need to be a much lower value than normally would be used on standard I2C devices. I am, however, using these devices on the same I2C bus as some memory devices. I have a CBT3253 Fet Mux/Demux IC that I'm using to address four different sensors on the same bus. This IC has the effect of acting as a 'buffer' between it's serial bus and the I2C bus. I have pull-up's next to the sensor as well as the standard pull-up's for the I2C bus. This works quite well for me. It took me a bit to figure out the quirks with this sensor and getting it to work on the I2C bus with other components.
Ronald |
|
|
Spinners
Joined: 23 Jun 2004 Posts: 1
|
Newbie |
Posted: Wed Jun 23, 2004 4:24 pm |
|
|
Hi I'm a newbie here
and have been playing with the code provided above
and was wondering how the xmit and rcv pins work when you call
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, errors)
the help files arent helping me -
and as of right now im getting garbage into tera term pro
that kind of looks like the following (i copied and pasted, but some of the symbols changed, but it's essentially the same)-------->
x<�x��x<x<��x<��x�x<��x�x<�x����x�x����x���x<���x��x
<�x�x<x�x<��x��x<�x��x<x<��x<��x�x
any help would be great!!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 23, 2004 4:41 pm |
|
|
This thread is about the SHT11 chip, and writing drivers for it.
You shouldn't attach a newbie question about RS232 to it.
You should start a new thread for your problem. |
|
|
Guest
|
SHT11 DRV |
Posted: Fri Jun 25, 2004 2:24 pm |
|
|
Code: |
///////////////////////////////////////////////////////////////////////////////
#define ACK 0
// Command byte values adr cmd r/w
#define Reset 0x1e // 000 1111 0
#define MeasureTemp 0x03 // 000 0001 1
#define MeasureHumi 0x05 // 000 0010 1
#define WrStatusReg 0x06 // 000 0011 0
#define RdStatusReg 0x07 // 000 0011 1
// Define Data & Clock Pins
#define Data PIN_B7
#define Sck PIN_B6
short error, chkCRC, Acknowledge;
int TimeOut,err;
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
long CalcTempValues(long Lx){
long value;
float Fx;
Fx=0.01*(float)Lx;
Fx=Fx-40;
Value=Fx*10;
return(value);
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
long CalcHumiValues(long Lx){
long Value;
float Fx, Fy;
Fx=(float)Lx*(float)Lx;
Fx=Fx*(-0.0000028);
Fy=(float)Lx*0.0405;
Fx=Fx+Fy;
Fx=Fx-4;
Value=Fx*10;
return(value);
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
void TransmitStart(){
output_high(Data);
output_low(Sck); delay_us(2);
output_high(SCK); delay_us(2);
output_low(Data); delay_us(2);
output_low(SCK); delay_us(6);
output_high(SCK); delay_us(2);
output_high(Data);delay_us(2);
output_low(SCK); delay_us(2);
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
void RST_Connection(){
int i;
output_high(Data);
for(i=1;i<=10;++i) {
output_high(SCK); delay_us(2);
output_low(SCK); delay_us(2);
}
TransmitStart();
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
void RST_Software(){
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
int WriteStatReg(int command){
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
int ReadStatReg(int command){
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
long ReadValue(){
byte i, ByteHigh=0, ByteLow=0;
long Lx;
for(i=1;i<=8;++i){ // read high byte VALUE from SHT11
output_high(SCK);
delay_us(2);
shift_left(&ByteHigh,1,input(Data));
output_low(SCK);
delay_us(2);
}
output_low(Data);
delay_us(2);
output_high(SCK);
delay_us(2);
output_low(SCK);
output_float(Data);
delay_us(2);
for(i=1;i<=8;++i){ // read low byte VALUE from SHT11
output_high(SCK);
delay_us(2);
shift_left(&ByteLow,1,input(Data));
output_low(SCK);
delay_us(2);
}
output_high(Data);
delay_us(2);
output_high(SCK);
delay_us(2);
output_low(SCK);
output_float(Data);
delay_us(2);
Lx=make16(ByteHigh,ByteLow);
return(Lx);
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
void SendCommand(int Command){
byte i;
for(i=128;i>0;i/=2){
if(i & Command) output_high(Data);
else output_low(Data);
delay_us(2);
output_high(SCK);
delay_us(2);
output_low(SCK);
}
output_float(Data);
delay_us(2);
output_high(SCK);
delay_us(2);
output_low(SCK);
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
long ReadTemperature(){
short Acknowledge;
long Lx,Value;
TransmitStart();
SendCommand(MeasureTemp);
while(input(Data));
delay_us(2);
Lx=ReadValue(); // Read temperature value
Value=CalcTempValues(Lx);
return(Value);
}
/////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
long ReadHumidity(){
long Lx,Value;
TransmitStart();
SendCommand(MeasureHumi);
while(input(Data));
delay_us(2);
Lx=ReadValue(); // Read humidity value
Value=CalcHumiValues(Lx);
return(Value);
}
|
|
|
|
james Guest
|
|
Posted: Mon May 29, 2006 2:24 am |
|
|
hi mr guest
I test your routine for sht11 , he work with the older version of sht11 but he doesn't with the new versions, the causes are probably the recent structure modifications, please check it and modify your routine thanks ^^ |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|