![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
overmindx
Joined: 06 Oct 2008 Posts: 43
|
sht75 crc |
Posted: Tue May 19, 2009 8:35 pm |
|
|
Hello everybody, has anybody used the crc feature of sht75? How can I implement it? Please help. Thanks. |
|
![](templates/subSilver/images/spacer.gif) |
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
![](templates/subSilver/images/spacer.gif) |
Guest
|
|
Posted: Wed May 20, 2009 6:54 pm |
|
|
Andrew: And you have it at a very fair price too, IMHO....
If I need one - you have my business....
I am looking at the boot loaders however as I probably need this technology.
:-)
Steve H. |
|
![](templates/subSilver/images/spacer.gif) |
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Thu May 21, 2009 10:08 am |
|
|
overmindx wrote: | Hello everybody, has anybody used the crc feature of sht75? How can I implement it? Please help. Thanks. |
According to application note that would not be so hard, there is written how to implement it. On the 7th page is pascal source code for CRC lookup. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 21, 2009 10:23 am |
|
|
Use Google to search for:
Quote: | sht75 crc int char |
You find sample code here:
http://www.microchip.com/forums/tm.aspx?m=368365
See the attachment to Brem's post.
This is C18 code, so an 'int' is a 16-bit signed integer, but in CCS, an 'int'
is an 8-bit unsigned integer. |
|
![](templates/subSilver/images/spacer.gif) |
wangine
Joined: 07 Jul 2009 Posts: 98 Location: Curtea de Arges, Romania
|
|
Posted: Sun Sep 06, 2015 6:47 pm |
|
|
PCM programmer wrote: | Use Google to search for:
Quote: | sht75 crc int char |
You find sample code here:
http://www.microchip.com/forums/tm.aspx?m=368365
See the attachment to Brem's post.
This is C18 code, so an 'int' is a 16-bit signed integer, but in CCS, an 'int'
is an 8-bit unsigned integer. |
I try to convert for CCS but without success. I need to read humidity from 6 SHT75 sensors in one room. I use Hansolo driver right now, https://www.ccsinfo.com/forum/viewtopic.php?t=28564
The driver is working below 2 meters cable, thats good but the humidity look strange, a little bit high. That compare with other industrial humidity device, also i try to simulate in Proteus and look the same, humidity more high than real.
SHT75.h
Code: | //
// SHT75 Temp & Humid sensor
//
#ifndef _SHT75_H_
#define _SHT75_H_
void SHT75_Init( void);
void SHT75_TimerTick( void);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// int16 SOt; // Raw value temp
// int16 SOrh; // Raw value rh
#define sht_data_pin PIN_B0
#define sht_clk_pin PIN_B1
//
//typedef.h
//
typedef union
{
unsigned int16 _word;
struct
{
unsigned int8 byte0;
unsigned int8 byte1;
};
} WORD_16;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct _SHT75
{
unsigned newdata:1;
unsigned continuous:1;
unsigned int8 error;
unsigned int8 state;
unsigned int8 timeout;
WORD_16 SOt; // Raw value temp
WORD_16 SOrh; // Raw value rh
int16 T; // temp in 0.01 degree C
int16 RH; // rel humidity in 0.01%
int16 DP; // dew point (not yet)
unsigned int8 crc;
};
struct _SHT75 SHT75;
//extern struct _SHT75 SHT75;
#define SHT75_STATE_IDLE 0
#define SHT75_STATE_MEASURE_TEMP 1
#define SHT75_STATE_WAITING_TEMP 2
#define SHT75_STATE_COOLDOWN_TEMP 3
#define SHT75_STATE_MEASURE_RH 4
#define SHT75_STATE_WAITING_RH 5
#define SHT75_STATE_COOLDOWN_RH 6
#define SHT75_STATE_ERROR 9
#define SHT75_ERROR_NOACK 1
#define SHT75_ERROR_BADCRC 2
#define SHT75_ERROR_TIMEOUT 3
#endif
|
and SHT75.c
Code: | //
// SHT75 Commands
//
#define SHT75_CMD_MEASURE_TEMP 0b00000011
#define SHT75_CMD_MEASURE_HUMID 0b00000101
#define SHT75_CMD_READ_STATUS 0b00000111
#define SHT75_CMD_WRITE_STATUS 0b00000110
#define SHT75_CMD_SOFT_RESET 0b00011110
//
// Howmany times per second will SHT75_TimerTick() be called? Used to compute 1sec delay in between readings
//
#define SHT75_DELAY_1SEC (delay_ms(1000))
// SDA & SCK, with very crude delays
//
#define SDA_LO {output_low(sht_data_pin); delay_us(1);}
#define SDA_HI {output_float(sht_data_pin); delay_us(2);}
#define SDA input_state(sht_data_pin)
#define SCK_HI {output_high(sht_clk_pin); delay_us(2);}
#define SCK_LO {output_low(sht_clk_pin); delay_us(1);}
// Private function protos
//
void SHT75_StartTransmission( void);
void SHT75_EndTransmission( void);
void SHT75_WriteByte( unsigned char c);
void SHT75_WriteAck( void);
unsigned char SHT75_ReadByte( void);
unsigned char SHT75_ReadAck( void); //
unsigned char SHT75_CheckCRC( unsigned char b1, unsigned char b2, unsigned char b3);
//
// Init...
//
void SHT75_Init( void)
{
//sht_init();
output_float(sht_data_pin);
delay_us(1);
output_low(sht_clk_pin);
delay_us(1);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SHT75.newdata = 0; // No new data available yet..
SHT75.continuous = 1; // Start continuous reading
SHT75.state = SHT75_STATE_IDLE;
SHT75.timeout = SHT75_DELAY_1SEC;
SHT75.T = 0;
SHT75.RH = 0;
delay_ms(1); // Just wait a while...
SHT75_StartTransmission(); // And a soft reset plz..
SHT75_WriteByte( SHT75_CMD_SOFT_RESET);
SHT75_ReadAck();
SHT75_EndTransmission();
}
//
// Should be call every somany msecs
//
void SHT75_TimerTick( void)
{
switch( SHT75.state)
{
case SHT75_STATE_IDLE:
if( SHT75.continuous)
SHT75.state = SHT75_STATE_MEASURE_TEMP;
SHT75.error=0;
break;
case SHT75_STATE_MEASURE_TEMP:
SHT75_StartTransmission();
SHT75_WriteByte( SHT75_CMD_MEASURE_TEMP);
if( !SHT75_ReadAck())
{
SHT75_EndTransmission();
SHT75.error = SHT75_ERROR_NOACK;
SHT75.state = SHT75_STATE_ERROR;
break;
}
SHT75.timeout = SHT75_DELAY_1SEC;
SHT75.state = SHT75_STATE_WAITING_TEMP;
break;
case SHT75_STATE_WAITING_TEMP:
if( SDA == 0) // SHT75 will pull SDA low when done measuring
{
SHT75.SOt.byte1 = SHT75_ReadByte();
SHT75_WriteAck();
SHT75.SOt.byte0 = SHT75_ReadByte();
SHT75_WriteAck();
SHT75.crc = SHT75_ReadByte();
SHT75_EndTransmission();
if( !SHT75_CheckCRC( SHT75_CMD_MEASURE_TEMP, SHT75.SOt.byte1, SHT75.SOt.byte0))
{
SHT75.state = SHT75_STATE_ERROR;
SHT75.error = SHT75_ERROR_BADCRC;
break;
}
//
// Compute T, 0.01 deg's
// For 5V supply, 14 bit accuracy: T = -40.00 + 0.01*SOt
//
SHT75.T = -4000 + SHT75.SOt._word;
SHT75.state = SHT75_STATE_COOLDOWN_TEMP;
}
else
{
if( --SHT75.timeout >0)
break;
SHT75.state = SHT75_STATE_ERROR;
SHT75.error = SHT75_ERROR_TIMEOUT;
}
break;
case SHT75_STATE_COOLDOWN_TEMP:
if( --SHT75.timeout >0)
break;
SHT75.state = SHT75_STATE_MEASURE_RH;
break;
case SHT75_STATE_MEASURE_RH:
SHT75_StartTransmission();
SHT75_WriteByte( SHT75_CMD_MEASURE_HUMID);
if( !SHT75_ReadAck())
{
SHT75_EndTransmission();
SHT75.error = SHT75_ERROR_NOACK;
SHT75.state = SHT75_STATE_ERROR;
break;
}
SHT75.timeout = SHT75_DELAY_1SEC;
SHT75.state = SHT75_STATE_WAITING_RH;
break;
case SHT75_STATE_WAITING_RH:
if( SDA == 0) // SHT75 will pull SDA low when done measuring
{
SHT75.SOrh.byte1 = SHT75_ReadByte();
SHT75_WriteAck();
SHT75.SOrh.byte0 = SHT75_ReadByte();
SHT75_WriteAck();
SHT75.crc = SHT75_ReadByte();
SHT75_EndTransmission();
if( !SHT75_CheckCRC( SHT75_CMD_MEASURE_HUMID, SHT75.SOrh.byte1, SHT75.SOrh.byte0))
{
SHT75.state = SHT75_STATE_ERROR;
SHT75.error = SHT75_ERROR_BADCRC;
break;
}
else
{
//
// Compute RH, 0.01%'s
//
// For 12 bit acc: RH = -4 + 0.0405 * SOrh - 0.0000028*(SOrh*SOrh)
//
long SO = SHT75.SOrh._word;
long SO2 = SO*SO; // squared
SO2 *= -28; // need extra divide by 10
SO2 /= 100000; // should divide with 6 zero's, 1 more for the use of 28 iso 2.8, 2 less to make result in 0.01% units
// makes 5 zero's
SO *= 405; // multiply by 4.05
SO /= 100; //
SO = -400 + SO + SO2; // Final addition.
SHT75.RH = SO;
}
SHT75.state = SHT75_STATE_COOLDOWN_RH;
}
else //
{
if( --SHT75.timeout >0)
break;
SHT75.state = SHT75_STATE_ERROR;
SHT75.error = SHT75_ERROR_TIMEOUT;
}
break;
case SHT75_STATE_COOLDOWN_RH:
if( --SHT75.timeout >0)
break;
SHT75.newdata = 1; // Make new data available
SHT75.state = SHT75_STATE_IDLE; // Back to idle
break;
case SHT75_STATE_ERROR:
// if( SHT75.error == SHT75_ERROR_BADCRC)
//u,. Led_Set(1);
break;
default:
break;
}
}
void SHT75_StartTransmission( void)
{
// Transmission start sequence
SCK_HI;
SDA_LO;
SCK_LO;
SCK_HI;
SDA_HI;
SCK_LO;
}
void SHT75_EndTransmission( void)
{
// Idle state
SDA_HI;
SCK_LO;
}
void SHT75_WriteByte( unsigned char c)
{
char bits=8;
while( bits--)
{
if( c & 0b10000000)
SDA_HI
else
SDA_LO;
SCK_HI;
SCK_LO;
c <<=1;
}
SDA_HI;
}
void SHT75_WriteAck( void)
{
SDA_LO;
SCK_HI;
SCK_LO;
SDA_HI;
}
unsigned char SHT75_ReadByte( void)
{
unsigned char bits=8;
unsigned char rsl=0;
while( bits--)
{
rsl <<=1;
SCK_HI;
if( SDA)
rsl |= 1;
SCK_LO;
}
return rsl;
}
unsigned char SHT75_ReadAck( void)
{
unsigned char rsl=0;
SCK_HI;
rsl = SDA; // SDA low means ack received
SCK_LO;
return (rsl==0);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rom unsigned char CRC_Table[256] =
{
0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46,
67, 114, 33, 16, 135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109,
134, 183, 228, 213, 66, 115, 32, 17, 63, 14, 93, 108, 251, 202, 153, 168,
197, 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47, 184, 137, 218, 235,
61, 12, 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19,
126, 79, 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80,
187, 138, 217, 232, 127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149,
248, 201, 154, 171, 60, 13, 94, 111, 65, 112, 35, 18, 133, 180, 231, 214,
122, 75, 24, 41, 190, 143, 220, 237, 195, 242, 161, 144, 7, 54, 101, 84,
57, 8, 91, 106, 253, 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23,
252, 205, 158, 175, 56, 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210,
191, 142, 221, 236, 123, 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145,
71, 118, 37, 20, 131, 178, 225, 208, 254, 207, 156, 173, 58, 11, 88, 105,
4, 53, 102, 87, 192, 241, 162, 147, 189, 140, 223, 238, 121, 72, 27, 42,
193, 240, 163, 146, 5, 52, 103, 86, 120, 73, 26, 43, 188, 141, 222, 239,
130, 179, 224, 209, 70, 119, 36, 21, 59, 10, 89, 104, 255, 206, 157, 172
};
//
// Compute CRC of command byte and 2 rcvd bytes, and checks it against CRC stored in global struct
//
unsigned char SHT75_CheckCRC( unsigned char b1, unsigned char b2, unsigned char b3)
{
unsigned char crc = 0;
unsigned char tmp = 0;
unsigned char bits= 8;
crc = CRC_Table[ crc ^ b1];
crc = CRC_Table[ crc ^ b2];
crc = CRC_Table[ crc ^ b3];
while( bits--)
{
tmp >>=1;
if( crc & 0b10000000)
tmp |= 0b10000000;
crc <<=1;
}
return (tmp==SHT75.crc);
}
|
The driver is stuck somehow, just initialise sensor, send some data and sto , no communication after 1 second.
I think the problem is here, but i don't know how to solve.
Code: |
#define SHT75_DELAY_1SEC (delay_ms(1000))
// SDA & SCK, with very crude delays
//
#define SDA_LO {output_low(sht_data_pin); delay_us(1);}
#define SDA_HI {output_float(sht_data_pin); delay_us(2);}
#define SDA input_state(sht_data_pin)
#define SCK_HI {output_high(sht_clk_pin); delay_us(2);}
#define SCK_LO {output_low(sht_clk_pin); delay_us(1);}
| here original for C18
Code: | #define SHT75_DELAY_1SEC (1000/TIMER_TICK)
//
// SDA & SCK, with very crude delays
//
#define SDA_LO {SHT75_SDA_Tris(0); Delay10TCYx( 1);}
#define SDA_HI {SHT75_SDA_Tris(1); Delay10TCYx( 1);}
#define SDA SHT75_SDA_Get()
#define SCK_HI {SHT75_SCK_Set(1); Delay10TCYx( 1);}
#define SCK_LO {SHT75_SCK_Set(0); Delay10TCYx( 1);}
|
The original driver in PCM Programmer link.
Thanks and sorry for my english. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 07, 2015 5:29 am |
|
|
What humidity value(s) did you read ? How do you know it's too high ?
You must be comparing it to some other unit, that you're using as a
standard. |
|
![](templates/subSilver/images/spacer.gif) |
wangine
Joined: 07 Jul 2009 Posts: 98 Location: Curtea de Arges, Romania
|
|
Posted: Mon Sep 07, 2015 5:53 am |
|
|
PCM programmer wrote: | What do you want us to do ? You posted some C18 code, but your
complaint is about the Han Solo code in the Code Library.
If you have a complaint about the Han Solo code, then post the results
that you expected to get, and also post what you are actually getting.
Explain how you know the humidity from the Han Solo code is incorrect. |
On HanSolo code humidity is correct only at 27 *C, i compare with Fluke 971 meter and for temperature compare i use Fluke 289 multimeter with temperature probe. Also i have in the same isolated tobacco room other 4 analog humidity sensors, with some pic18xx controllers. Temperature looks good on 34*C, between 20 and 90*C the error is around 4.8*C, my compare temperature probe have error 0,012%
I didn't post a C18 code, i modify entire code trying to get CRC check. On end of post i put the part that i believe is wrong. To understand the entire Hansolo code, need time, the same time can be used to write a new one. I say just i used a Hansolo code and after some tests i notice humidity is more high than meter and others sensors show in same room, same position.
Now my question is if some one can help me to understand where is the problem on the code i posted below because i really want to include a CRC check. The code is compiled without errors in CCS, but somewhere the code stuck in some loop, the temperature and humidity variables return 0 all time. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Mon Sep 07, 2015 8:05 am |
|
|
You try breaking up your program into two sections
1) reading the sensor
2) computing the temp/humid from the readings.
If you put known 'dummy' values instead of reading the sensors you'll get to know if the 'math' for computing the temperature and humidity are correct. I'm sure the SHT75 datasheet will have known values say for 0*C, 100*C or similar. By doing this you can confirm the 'math' is right or wrong.
Once this is working 100%, then get real data from the sensors at a known temperature and humidity,compared to your Fluke test equipment. If there is an error, it's with the sensors or communications NOT the 'math' sections.
Right now you could have a small problem in BOTH sections, reading and computing making it impossible to 'see' where the problems are.
Jay |
|
![](templates/subSilver/images/spacer.gif) |
wangine
Joined: 07 Jul 2009 Posts: 98 Location: Curtea de Arges, Romania
|
|
Posted: Mon Sep 07, 2015 10:45 am |
|
|
Yup, are perfectly right , when i begin to made some driver, i made separate function for test each part. After all has success, i put all parts together, but in this case the code is already done, and need to understand piece by piece to start to divide sections. I put answer here not because i want to get code to work free, just i think some are more smart or already studied or know that. I am 99% sure the mistake is in math part, but is weird because the math look exactly like in datasheet.
On second code (C18), is difficult, i understand just some section of code, far away CRC section for me. Right now i work on SHT25 driver, i buy 5 sensors on 4 diferent countries, include chinese. I finish some different hardware with diferent pic's and ... i still work. Driver look like SHT75 but is not the same, i need more study. Thanks for all answers. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 07, 2015 1:28 pm |
|
|
Quote: | I think the problem is here, but i don't know how to solve. |
What's the oscillator frequency for your PIC ?
The translated code below would be accurate if PIC is running at 40 MHz.
Code: |
#define SHT75_DELAY_1SEC (delay_ms(1000))
// SDA & SCK, with very crude delays
//
#define SDA_LO {output_low(sht_data_pin); delay_us(1);}
#define SDA_HI {output_float(sht_data_pin); delay_us(2);}
#define SDA input_state(sht_data_pin)
#define SCK_HI {output_high(sht_clk_pin); delay_us(2);}
#define SCK_LO {output_low(sht_clk_pin); delay_us(1);}
here original for C18
Code:
#define SHT75_DELAY_1SEC (1000/TIMER_TICK)
//
// SDA & SCK, with very crude delays
//
#define SDA_LO {SHT75_SDA_Tris(0); Delay10TCYx( 1);}
#define SDA_HI {SHT75_SDA_Tris(1); Delay10TCYx( 1);}
#define SDA SHT75_SDA_Get()
#define SCK_HI {SHT75_SCK_Set(1); Delay10TCYx( 1);}
#define SCK_LO {SHT75_SCK_Set(0); Delay10TCYx( 1);}
|
But where did the sht75.c and sht75.h files originally come from ?
What was the PIC oscillator frequency on the original project ? |
|
![](templates/subSilver/images/spacer.gif) |
wangine
Joined: 07 Jul 2009 Posts: 98 Location: Curtea de Arges, Romania
|
|
Posted: Mon Sep 07, 2015 2:11 pm |
|
|
SHT75.h
Code: | //
// SHT75 Temp & Humid sensor
//
#ifndef _SHT75_H_
#define _SHT75_H_
void SHT75_Init( void);
void SHT75_TimerTick( void);
struct _SHT75
{
unsigned newdata:1;
unsigned continuous:1;
unsigned char error;
unsigned char state;
unsigned char timeout;
WORD SOt; // Raw value temp
WORD SOrh; // Raw value rh
int T; // temp in 0.01 degree C
int RH; // rel humidity in 0.01%
int DP; // dew point (not yet)
unsigned char crc;
};
extern struct _SHT75 SHT75;
#define SHT75_STATE_IDLE 0
#define SHT75_STATE_MEASURE_TEMP 1
#define SHT75_STATE_WAITING_TEMP 2
#define SHT75_STATE_COOLDOWN_TEMP 3
#define SHT75_STATE_MEASURE_RH 4
#define SHT75_STATE_WAITING_RH 5
#define SHT75_STATE_COOLDOWN_RH 6
#define SHT75_STATE_ERROR 9
#define SHT75_ERROR_NOACK 1
#define SHT75_ERROR_BADCRC 2
#define SHT75_ERROR_TIMEOUT 3
#endif
|
and sht75.c
Code: | //
// SHT75.c
//
#include <p18cxxx.h>
#include <typedefs.h>
#include "io_cfg.h"
#include "SHT75.h"
#include <timedelays.h>
//
// SHT75 Commands
//
#define SHT75_CMD_MEASURE_TEMP 0b00000011
#define SHT75_CMD_MEASURE_HUMID 0b00000101
#define SHT75_CMD_READ_STATUS 0b00000111
#define SHT75_CMD_WRITE_STATUS 0b00000110
#define SHT75_CMD_SOFT_RESET 0b00011110
//
// Howmany times per second will SHT75_TimerTick() be called? Used to compute 1sec delay in between readings
//
#define SHT75_DELAY_1SEC (1000/TIMER_TICK)
//
// SDA & SCK, with very crude delays
//
#define SDA_LO {SHT75_SDA_Tris(0); Delay10TCYx( 1);}
#define SDA_HI {SHT75_SDA_Tris(1); Delay10TCYx( 1);}
#define SDA SHT75_SDA_Get()
#define SCK_HI {SHT75_SCK_Set(1); Delay10TCYx( 1);}
#define SCK_LO {SHT75_SCK_Set(0); Delay10TCYx( 1);}
//
// Private function protos
//
void SHT75_StartTransmission( void);
void SHT75_EndTransmission( void);
void SHT75_WriteByte( unsigned char c);
void SHT75_WriteAck( void);
unsigned char SHT75_ReadByte( void);
unsigned char SHT75_ReadAck( void); //
unsigned char SHT75_CheckCRC( unsigned char b1, unsigned char b2, unsigned char b3);
struct _SHT75 SHT75;
//
// Init...
//
void SHT75_Init( void)
{
//#if (CAN_SOURCEADDRESS == CAN_SA_HUMIDSENSOR3)
LATCbits.LATC4 = 1; // function as Pull up, error in PCB
//#endif
SHT75_SDA_Set(0); //
SHT75_SDA_Tris(1); // SDA High imp
SHT75_SCK_Tris(0); //
SHT75_SCK_Set(0); // CLK Low
SHT75.newdata = 0; // No new data available yet..
SHT75.continuous = 1; // Start continuous reading
SHT75.state = SHT75_STATE_IDLE;
SHT75.timeout = SHT75_DELAY_1SEC;
SHT75.T = 0;
SHT75.RH = 0;
DelaymSec(1); // Just wait a while...
SHT75_StartTransmission(); // And a soft reset plz..
SHT75_WriteByte( SHT75_CMD_SOFT_RESET);
SHT75_ReadAck();
SHT75_EndTransmission();
}
//
// Should be call every somany msecs
//
void SHT75_TimerTick( void)
{
switch( SHT75.state)
{
case SHT75_STATE_IDLE:
if( SHT75.continuous)
SHT75.state = SHT75_STATE_MEASURE_TEMP;
SHT75.error=0;
break;
case SHT75_STATE_MEASURE_TEMP:
SHT75_StartTransmission();
SHT75_WriteByte( SHT75_CMD_MEASURE_TEMP);
if( !SHT75_ReadAck())
{
SHT75_EndTransmission();
SHT75.error = SHT75_ERROR_NOACK;
SHT75.state = SHT75_STATE_ERROR;
break;
}
SHT75.timeout = SHT75_DELAY_1SEC;
SHT75.state = SHT75_STATE_WAITING_TEMP;
break;
case SHT75_STATE_WAITING_TEMP:
if( SDA == 0) // SHT75 will pull SDA low when done measuring
{
SHT75.SOt.byte1 = SHT75_ReadByte();
SHT75_WriteAck();
SHT75.SOt.byte0 = SHT75_ReadByte();
SHT75_WriteAck();
SHT75.crc = SHT75_ReadByte();
SHT75_EndTransmission();
if( !SHT75_CheckCRC( SHT75_CMD_MEASURE_TEMP, SHT75.SOt.byte1, SHT75.SOt.byte0))
{
SHT75.state = SHT75_STATE_ERROR;
SHT75.error = SHT75_ERROR_BADCRC;
break;
}
//
// Compute T, 0.01 deg's
// For 5V supply, 14 bit accuracy: T = -40.00 + 0.01*SOt
//
SHT75.T = -4000 + SHT75.SOt._word;
SHT75.state = SHT75_STATE_COOLDOWN_TEMP;
}
else
{
if( --SHT75.timeout >0)
break;
SHT75.state = SHT75_STATE_ERROR;
SHT75.error = SHT75_ERROR_TIMEOUT;
}
break;
case SHT75_STATE_COOLDOWN_TEMP:
if( --SHT75.timeout >0)
break;
SHT75.state = SHT75_STATE_MEASURE_RH;
break;
case SHT75_STATE_MEASURE_RH:
SHT75_StartTransmission();
SHT75_WriteByte( SHT75_CMD_MEASURE_HUMID);
if( !SHT75_ReadAck())
{
SHT75_EndTransmission();
SHT75.error = SHT75_ERROR_NOACK;
SHT75.state = SHT75_STATE_ERROR;
break;
}
SHT75.timeout = SHT75_DELAY_1SEC;
SHT75.state = SHT75_STATE_WAITING_RH;
break;
case SHT75_STATE_WAITING_RH:
if( SDA == 0) // SHT75 will pull SDA low when done measuring
{
SHT75.SOrh.byte1 = SHT75_ReadByte();
SHT75_WriteAck();
SHT75.SOrh.byte0 = SHT75_ReadByte();
SHT75_WriteAck();
SHT75.crc = SHT75_ReadByte();
SHT75_EndTransmission();
if( !SHT75_CheckCRC( SHT75_CMD_MEASURE_HUMID, SHT75.SOrh.byte1, SHT75.SOrh.byte0))
{
SHT75.state = SHT75_STATE_ERROR;
SHT75.error = SHT75_ERROR_BADCRC;
break;
}
else
{
//
// Compute RH, 0.01%'s
//
// For 12 bit acc: RH = -4 + 0.0405 * SOrh - 0.0000028*(SOrh*SOrh)
//
long SO = SHT75.SOrh._word;
long SO2 = SO*SO; // squared
SO2 *= -28; // need extra divide by 10
SO2 /= 100000; // should divide with 6 zero's, 1 more for the use of 28 iso 2.8, 2 less to make result in 0.01% units
// makes 5 zero's
SO *= 405; // multiply by 4.05
SO /= 100; //
SO = -400 + SO + SO2; // Final addition.
SHT75.RH = SO;
}
SHT75.state = SHT75_STATE_COOLDOWN_RH;
}
else //
{
if( --SHT75.timeout >0)
break;
SHT75.state = SHT75_STATE_ERROR;
SHT75.error = SHT75_ERROR_TIMEOUT;
}
break;
case SHT75_STATE_COOLDOWN_RH:
if( --SHT75.timeout >0)
break;
SHT75.newdata = 1; // Make new data available
SHT75.state = SHT75_STATE_IDLE; // Back to idle
break;
case SHT75_STATE_ERROR:
// if( SHT75.error == SHT75_ERROR_BADCRC)
//u,. Led_Set(1);
break;
default:
break;
}
}
void SHT75_StartTransmission( void)
{
// Transmission start sequence
SCK_HI;
SDA_LO;
SCK_LO;
SCK_HI;
SDA_HI;
SCK_LO;
}
void SHT75_EndTransmission( void)
{
// Idle state
SDA_HI;
SCK_LO;
}
void SHT75_WriteByte( unsigned char c)
{
char bits=8;
while( bits--)
{
if( c & 0b10000000)
SDA_HI
else
SDA_LO;
SCK_HI;
SCK_LO;
c <<=1;
}
SDA_HI;
}
void SHT75_WriteAck( void)
{
SDA_LO;
SCK_HI;
SCK_LO;
SDA_HI;
}
unsigned char SHT75_ReadByte( void)
{
unsigned char bits=8;
unsigned char rsl=0;
while( bits--)
{
rsl <<=1;
SCK_HI;
if( SDA)
rsl |= 1;
SCK_LO;
}
return rsl;
}
unsigned char SHT75_ReadAck( void)
{
unsigned char rsl=0;
SCK_HI;
rsl = SDA; // SDA low means ack received
SCK_LO;
return (rsl==0);
}
rom unsigned char CRC_Table[256] =
{
0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46,
67, 114, 33, 16, 135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109,
134, 183, 228, 213, 66, 115, 32, 17, 63, 14, 93, 108, 251, 202, 153, 168,
197, 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47, 184, 137, 218, 235,
61, 12, 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19,
126, 79, 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80,
187, 138, 217, 232, 127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149,
248, 201, 154, 171, 60, 13, 94, 111, 65, 112, 35, 18, 133, 180, 231, 214,
122, 75, 24, 41, 190, 143, 220, 237, 195, 242, 161, 144, 7, 54, 101, 84,
57, 8, 91, 106, 253, 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23,
252, 205, 158, 175, 56, 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210,
191, 142, 221, 236, 123, 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145,
71, 118, 37, 20, 131, 178, 225, 208, 254, 207, 156, 173, 58, 11, 88, 105,
4, 53, 102, 87, 192, 241, 162, 147, 189, 140, 223, 238, 121, 72, 27, 42,
193, 240, 163, 146, 5, 52, 103, 86, 120, 73, 26, 43, 188, 141, 222, 239,
130, 179, 224, 209, 70, 119, 36, 21, 59, 10, 89, 104, 255, 206, 157, 172
};
//
// Compute CRC of command byte and 2 rcvd bytes, and checks it against CRC stored in global struct
//
unsigned char SHT75_CheckCRC( unsigned char b1, unsigned char b2, unsigned char b3)
{
unsigned char crc = 0;
unsigned char tmp = 0;
unsigned char bits= 8;
crc = CRC_Table[ crc ^ b1];
crc = CRC_Table[ crc ^ b2];
crc = CRC_Table[ crc ^ b3];
while( bits--)
{
tmp >>=1;
if( crc & 0b10000000)
tmp |= 0b10000000;
crc <<=1;
}
return (tmp==SHT75.crc);
}
|
Has take from your sugestion on brem's post on C18 forum , typedef.h missing but i made one include to don't modify the original code just int8/16/32 variables , is different on C18
this deff///
Code: | //
//typedef.h
//
typedef union
{
unsigned int16 _word;
struct
{
unsigned int8 byte0;
unsigned int8 byte1;
};
} WORD_16;
|
and i try to don't modify any function , right now i found where code stuck.
Code: | if( !SHT75_CheckCRC( SHT75_CMD_MEASURE_TEMP, SHT75.SOt.byte1, SHT75.SOt.byte0))
{
SHT75.state = SHT75_STATE_ERROR;
SHT75.error = SHT75_ERROR_BADCRC;
break;
} | . The loop never go out from here because case function don't have a valid state, if i pass CRC loop , the temperature return only 7520 , and stuck like that .Im so lost right now |
|
![](templates/subSilver/images/spacer.gif) |
wangine
Joined: 07 Jul 2009 Posts: 98 Location: Curtea de Arges, Romania
|
|
Posted: Sat Sep 12, 2015 8:55 pm |
|
|
PCM programmer wrote: |
What humidity value(s) did you read ? How do you know it's too high ?
You must be comparing it to some other unit, that you're using as a
standard. |
I give up with CRC check, i made my own driver for SHT25 , is more faster than SHT75. Anyway the last test i made with SHT75 and Hansolo code was :// I put in a high pressure vessel (6 bar) water to a boil in which 99.99999% humidity is normal and the temperature 117 ° C, and sensor looks 117.82 temperature and humidity 120.29 RH, and that is impossible, right ? I will try in the next few days to calibrate the code after some different tests with different sensors. I have 6 sensors and 3 different hardware, pic18f4550, pic18f4520 and dspic33FJ128MC804. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|