CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

sht75 crc

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
overmindx



Joined: 06 Oct 2008
Posts: 43

View user's profile Send private message

sht75 crc
PostPosted: Tue May 19, 2009 8:35 pm     Reply with quote

Hello everybody, has anybody used the crc feature of sht75? How can I implement it? Please help. Thanks.
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue May 19, 2009 11:40 pm     Reply with quote

I sell the source code for the SHT75 sensor that includes CRC validation. Details are here: http://www.brushelectronics.com/index.php?page=software#SENSIRION
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Guest








PostPosted: Wed May 20, 2009 6:54 pm     Reply with quote

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.
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Thu May 21, 2009 10:08 am     Reply with quote

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.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 21, 2009 10:23 am     Reply with quote

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.
wangine



Joined: 07 Jul 2009
Posts: 98
Location: Curtea de Arges, Romania

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Sun Sep 06, 2015 6:47 pm     Reply with quote

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.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 07, 2015 5:29 am     Reply with quote

Quote:
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.

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.
wangine



Joined: 07 Jul 2009
Posts: 98
Location: Curtea de Arges, Romania

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Mon Sep 07, 2015 5:53 am     Reply with quote

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.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Sep 07, 2015 8:05 am     Reply with quote

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
wangine



Joined: 07 Jul 2009
Posts: 98
Location: Curtea de Arges, Romania

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Mon Sep 07, 2015 10:45 am     Reply with quote

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.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 07, 2015 1:28 pm     Reply with quote

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 ?
wangine



Joined: 07 Jul 2009
Posts: 98
Location: Curtea de Arges, Romania

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Mon Sep 07, 2015 2:11 pm     Reply with quote

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
wangine



Joined: 07 Jul 2009
Posts: 98
Location: Curtea de Arges, Romania

View user's profile Send private message Send e-mail Yahoo Messenger

PostPosted: Sat Sep 12, 2015 8:55 pm     Reply with quote

PCM programmer wrote:
Quote:
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.

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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