SHT11 basic stamp code compatible with SHT21 ?

CuriousOneCuriousOne Posts: 922
edited March 2014 in BASIC Stamp Vote Up0Vote Down
Hello.

I've got this module:

http://www.ebay.com/itm/SHT21-Digital-Humidity-And-Temperature-Sensor-Module-Replace-SHT11-SHT15-/200941266522?pt=LH_DefaultDomain_0&hash=item2ec908665a

I've used sample code parallax provides for SHT21 and it appears to be working - humidity readings do increase when I breath on it, or decrease when I put it to dry situation. The problem is that, I have accurite indoor humidity meter, and it's reading, which I found pretty close to real ones (according to personal feelings), are completely different. When SHT21 shows 45%, accurite shows 31% and so on.

As far as I know, that SHT21 has "true" I2C, wheile SHT11 - does not. I've tried to use both BS2 and BS2P boards - no difference.

BS2 sample code from here:

http://www.parallax.com/downloads/sensirion-temphumidity-sensor-bs2-example-code

Comments

  • 12 Comments sorted by Date Added Votes
  • Tracy AllenTracy Allen Posts: 6,088
    edited March 2014 Vote Up0Vote Down
    While it is fully i2c compatible, Sensirion also made it backward compatible with the SHT11 protocol. The formula for conversion of the raw reading into RH and temperature is different though. That probably explains the discrepancy. Refer to pages 10-12 in the version 2 data sheet for the SHT21.

    If you have a 'p series Stamp, you might try the I2CIN and I2COUT commands instead of the old SHT11 protocol. I've used the SHT25 with i2c on the Propeller but haven't tried it on the Stamp.
  • I realize this is an old thread, but was wondering if someone could point me in the right direction. I picked up a SHT21 and found the code for SHT11 does not work.

    I've used sample code parallax provides for SHT21 and it appears to be working

    Is there example code that works with the SHT21 ? ,
  • Tracy AllenTracy Allen Posts: 6,088
    edited August 5 Vote Up0Vote Down
    There is also this thread,
    http://forums.parallax.com/discussion/157185/sht-22-and-basic-stamp/p1
    (it was an sht-21, not sht-22)

    The sht11 code should read the raw sensor data okay, but the math to convert to proper temperature and RH units needs to be modified. The math is easier for the sht21.


  • Mike2545Mike2545 Posts: 433
    edited August 6 Vote Up0Vote Down
    Thank you Tracy Allen, I am running the code you wrote "SHT11 Advanced BS2" :), I did see that you wrote:
    Just to compare in red and blue, the formulae for the SHT2x:
    °C = -46.85 + 175.72 * rawT / (2^resT) resT is 14 bits default
    %RH = -6 + 125 * rawH / (2^resH) resH is 12 bits default
    res = resolution, tradeoff with speed, set in the user register.

    with formulae for SHT1x:
    °C = -40.1 + 0.01 * rawT on 14 bit setting and 5V supply
    %RH1 = -2.0468 + 0.0367 * rawH - 1.5955E-6 * rawH^2 on 12 bit setting
    then temperature compensation
    %RH = (°C - 25) * (.01 + 0.00008 * rawH) + RH1
    The SHT1x too has both high and low resolution modes.

    but cannot make heads or tails of it

    The one thing I was never good at was the 8 bit math operations needed to significantly modify code of this magnitude. That is why I was looking for some code to work with with SHT21
    Any help would be greatly appreciated on this.

    This code is where I think the modifications are needed
    tC = soT / 10 - 400                           ' convert to tenths C
      tF = soT ** 11796 - 400                       ' convert to tenths F
    
    ...
      rhLin = (soRH ** 26542)
      rhLin = rhLin - ((soRH ** 3468) * (soRH ** 3468) + 50 / 100)
      rhLin = rhLin - 40
    ...
     rhTrue = ((tC / 10 - 25) * (soRH ** 524 + 1) + (rhLin * 10)) + 5 / 10  
    
    

    Mike2545
  • Tracy AllenTracy Allen Posts: 6,088
    edited August 6 Vote Up0Vote Down
    I'm not where I can test it now, but this would be my starting point. The nice thing about the SHT21 is that the raw readings come out as the numerators of binary fractions, rawT/(2^14) or rawRH/(2^12), and they are left justified in a 16-bit word. That is exactly the representation needed in order to use the ** operator.
    convertRaw2Real:
      degC = (rawT & $fffc) ** 17572 - 4685   'xxx.xx
      RH = (rawRH & $fff0) ** 1250 - 60   ' xx.x
      return
    
    The &fffc and $fff0 mask off the least significant 2 and 4 bits respectively, which the SHT21 uses to carry status information.

    In Spin for the Prop I use,
      degC := (rawC * 17572) >> 16 - 4685
      RH := (rawH * 1250) >> 16 -  60
    
    which could be done with ** also, but it is easier with 32 bit longs simply to multiply and then divide by 2^16 using >> 16.
  • Mike2545Mike2545 Posts: 433
    edited August 6 Vote Up0Vote Down
    Tracy, thank you for the code snippet. I must be getting the raw data incorrectly for the SHT21, this is the code I am using from the SHT11:
    SHT_Measure_Temp:
      GOSUB SHT_Start                               ' alert device
      ioByte = ShtTemp                              ' temperature command
      GOSUB SHT_Write_Byte                          ' send command
      GOSUB SHT_Wait                                ' wait until measurement done
      ackBit = Ack                                  ' another read follows
      GOSUB SHT_Read_Byte                           ' get MSB
      soT.HIGHBYTE = ioByte
      ackBit = NoAck                                ' last read
      GOSUB SHT_Read_Byte                           ' get LSB
      soT.LOWBYTE = ioByte
    

    similar for the humidity:
    SHT_Measure_Humidity:
      GOSUB SHT_Start                               ' alert device
      ioByte = ShtHumi                              ' humidity command
      GOSUB SHT_Write_Byte                          ' send command
      GOSUB SHT_Wait                                ' wait until measurement done
      ackBit = Ack                                  ' another read follows
      GOSUB SHT_Read_Byte                           ' get MSB
      soRH.HIGHBYTE = ioByte
      ackBit = NoAck                                ' last read
      GOSUB SHT_Read_Byte                           ' get LSB
      soRH.LOWBYTE = ioByte
    

    I'm betting the way to get data from the SHT21 differs....


    Mike
  • One thing that comes to mind is that the SHT1x returns its data right justified in a 16 bit field. So, to make it compatible with the code I posted, you'll need to make it left justified. That would be 2 bits left for temperature and 4 bits left for humidity...
    rawT = sot << 2
    rawH = soRH << 4
    provided you are set for the default 14 and 12 bit resolutions respectively.

    Look at pages 11–12 of the 2014 SHT2x data sheet to read the discussion of compatibility with SHT1x code.
  • Mike2545Mike2545 Posts: 433
    edited August 8 Vote Up0Vote Down
    Tracy, I am getting close here, I can get the sensor to give a varying output when I place my finger on it.
    The SHT21 temp says my room is 42°C (107.6°F) Actual temperature is ~ 23.8°C (75°F)
    rawT @ 42°C = 111

    Here is the code:
    ' {$STAMP BS2p}
    ' {$PBASIC 2.0}
    
      tf    VAR Byte
      tc    VAR Byte
      rawT  VAR Word
      rawRH VAR Byte
    
      PAUSE 250                                     ' let DEBUG window open
      DEBUG CLS
      DEBUG "SHT21 Demo", CR
      DEBUG "----------", CR
    
    Main:
    
    I2COUT 0 ,%10000000, [%11100011]
      PAUSE 50
    I2CIN  1 , %10000001, [rawT]
      DEBUG 2, 0, 3
      DEBUG "rawT...... "
      DEBUG  DEC rawT, 11, CR
      rawT= rawT <<2
      tC = (rawT & $fffc) ** 17572 - 4685
      DEBUG "Deg C......", DEC tC
      PAUSE 500
    
    
      GOTO main
    

    What do you think the calibration/ conversion issue could be?
  • Tracy AllenTracy Allen Posts: 6,088
    edited August 8 Vote Up0Vote Down
    I see that you are in fact using the i2c commands on the BS2p, not the SHT11 protocol. That is a different story. Better in the long run of course.

    The command %11100011 is for temperature using the clock hold mechanism. I'm not really sure if the Stamp supports clock hold, vaguely recall the affirmative, but can't put my finger on an example. If it does, the correct command would be, best guessing,
    I2CIN 0,%10000000,%11100011,[rawT.byte1,rawT.byte0]
    tC = (rawT & $fffc) ** 17572 - 4685
    There would be no I2COUT command. The I2CIN command takes care of everything. It writes the command %11100011 in the slot that is often called the address, and then it issues a repeated start and sends the %10000001 ID for reading, and then it it waits for the SHT21 to release the hold, and then it retrieves the high and low bytes of the data.

    The SHT21 also allows for systems that don't support clock hold. (Many don't) . That code would look something like this:
    I2COUT 0, %10000000,[%11110011] ' temperature, no hold master
    Pause 100 . ' conversion at 14 bits can take up to 85ms
    I2CIN 0, %10000000, [rawT,byte1, rawT.byte0]
    tC = (rawT & $fffc) ** 17572 - 4685

    In either case, use the rawT value in the math without shifting two bits left. (It is already left justified)


  • Tracy, both ways "seem" to give varying results, the temperature is bouncing all over the place. I will order up a unit from a reputable source and see how it behaves. Thanks for your help on this. I'll report back on the results.

    :)

    Mike
  • If I get a chance I'll try it here. Need to add level shifting to my SHT21 breakouts.

    Note that the newer SHT31 works on a wider supply range, 2.4 to 5.5 volts. The word is, the SHT1x series is going to go EOL in the not too distant future, also deprecating the SHT21. Sensirion is pushing the SHT3x for new projects.
  • Tracy AllenTracy Allen Posts: 6,088
    edited August 8 Vote Up0Vote Down
    Okay, got it hooked up with a TXS0102 for level shifting. It works okay with the no-hold program as follows. Also attached screen shot.
    '{$STAMP BS2pe}
    '{$PBASIC 2.5}
    
    rawT VAR WORD
    tC VAR WORD
    rawH VAR WORD
    rH VAR WORD
    
    main:
    DEBUG CR,"Hello",CR
    
    DO 
    PAUSE 1000
    I2COUT 8, %10000000,[%11110011] ' temperature, no hold master
    PAUSE 100  ' conversion at 14 bits can take up to 85ms
    I2CIN 8, %10000000, [rawT.BYTE1, rawT.BYTE0]
    I2COUT 8, %10000000,[%11110101] ' humidity, no hold master
    PAUSE 100  ' conversion at 12 bits
    I2CIN 8, %10000000, [rawH.BYTE1, rawH.BYTE0]
    
    tC = (rawT & $fffc) ** 17572 - 4685
    rH = (rawH & $fff0) ** 1250 - 60   ' xx.x
    
    DEBUG CR,"rawT= ",DEC rawT,"   degC= ",DEC tC/100,".",DEC2 tC
    DEBUG CR,"rawH= ",DEC rawH,"    %RH= ",DEC rH/10,".",DEC1 rH
    LOOP
    
    Noisy readings at first were cured by a good bypass capacitor on the TXS0102 power.
    The SHT21 command for clock hold did not work. The SHT21 did hold the clock (as seen on a 'scope), but then nothing happened on the Stamp when the SHT21 released the hold.
Sign In or Register to comment.