Shop OBEX P1 Docs P2 Docs Learn Events
Sensirion SHT11 SimpleTools Code — Parallax Forums

Sensirion SHT11 SimpleTools Code

tdlivingstdlivings Posts: 437
edited 2013-05-20 14:31 in Propeller 1
As an exercise I decided to try the functions in simpletools.h to wiggle the pins of a prop and interface
to Sensirion SHT11 Humidity Sensor.

This is a work in progress and as I said a learning exercise for me and some feedback for Andy on
simpletools.

Rather than use spin2cpp on some Spin code I had doing the same thing I went through my Spin code
and converted it to "C" as if I was writing it from scratch. I left data sizes as long just like function return
values and parameters are in Spin.

The first demo is for testing and I used my scope to observe the signals
It is producing reasonable numbers but as I said first run through jus to see what is going on.
I know I need to revisit some of the calc's as far as rounding and I am not returning a status of
a not ACQ.
It does not launch into a new cog as this version is to test wiggling the pins and calculating values.
The size of the total code for the following demo is 4624 bytes. Using SimpleIDE as is all defaults out of the box.

/*
  Test SHT11 Humidity Temp Sensor Code
*  
*/
#include "simpletools.h"                      // Include simple tools
#include "sht11.h"                            // SHT11 Sensor
  //Define pins used for testing
int  DatPin = 9;
int  ClkPin = 8;
// Create an instance of the structure to return measured value
sht11values_t MyVals;
sht11values_t *pMyVals;
 
int main()                                    // Main function
{
long Hum;
long TmpC;
long TmpF;
long Status;
  // Add startup code here.
  // Assign the address of our structure to the pointer
  pMyVals = &MyVals;
  pause(1000);
  Start(DatPin,ClkPin,pMyVals);
  printf("Starting Measurements\n");
  Status = ReadStatusReg();
  printf("Status Reg = %d\n",Status);
  while(1)                                    // Repeat indefinitely
  {
    // Add main loop code here.
    Measure();
    Hum = pMyVals->rhlin;
    TmpC = pMyVals->tempC;
    TmpF = pMyVals->tempF;
    printf("H:%d.%d%% T:%d.%dC, %d.%dF\n",Hum/10,Hum%10,TmpC/10,TmpC%10,TmpF/10,TmpF%10);
    printf("rawhum: %d\n",pMyVals->rawhum);
    printf("rawtemp: %d\n",pMyVals->rawtemp);
    printf("rhlin: %d\n",pMyVals->rhlin);
    printf("rhtrue: %d\n",pMyVals->rhtrue);
    printf("tempC: %d\n",pMyVals->tempC);
    printf("tempF: %d\n",pMyVals->tempF);
    printf("\n");
    pause(10000);                             //Pace the measurement
    
  }  
}


In Rsadeika's thread he used Spin2cpp to convert the obex driver to "C" and I wonder how the code size compares

@Rsadeika I would be curious if the code produces reasonable values for Humidity and Temp with your sensor

I attached a zip of the sht11 header and C code as well as the demo above. and a screen shot of it's output
I did not zip up the whole project
It is not in Simple Library form as that is a furture exercise for me to learn how to do.
Just copy sht11.c and sht11.h to a project folder and add the sht11.c file to a new project using the file link command
then replace the C code of the new SimpleIDE project with the Demo_1 code.

Also three scope pics 02 is showing sending a command to measure Humidity, 03 Shows the scope trigger and is as fast
as we can do a high the low using simpletools functions. 05 shows is reading back a vaue


Tom
538 x 558 - 36K
800 x 503 - 29K
800 x 503 - 22K
800 x 503 - 30K

Comments

  • RsadeikaRsadeika Posts: 3,837
    edited 2013-05-20 03:38
    In Rsadeika's thread he used Spin2cpp to convert the obex driver to "C" and I wonder how the code size compares
    I am not sure as to how I would make that fair comparison. I am a beginner at this C stuff, so ...
    @Rsadeika I would be curious if the code produces reasonable values for Humidity and Temp with your sensor
    Since you use the word "reasonable", I am assuming that your readout is not what you expected. A brief history, I have two Parallax Sensirion modules, the first one was used in my Spin prototype contraption. When I got the thing to work I noticed the values were at least 4 F degrees off, as it compared to my digital read out thermometer. Since I do not have a digital read out humidity device for comparison, I can not say anything about the humidity values.

    The Activity Board Sensirion module set up, when I got it to work, was only 1 F degree off. In this small sampling, I would say that there is quite a difference between the two devices. I wonder what Andy is getting, since he is using my code that has the software compensation. I ended up doing a software compensation change to get the readings closer to what my digital thermometer was reading.

    At this point I am not to concerned about the humidity readings, since they look like they are in the ballpark.

    I have not looked at your code, yet, but I am curious as to how you handled the Sensirion data output. In the Spin example, that is available in the OBEX, the data conversion looked very complex, especially when it uses float values. I tried to do a C version, but had no success. Hopefully somebody will create a nice Sensirion lib, so everybody benefits.

    Ray
  • tdlivingstdlivings Posts: 437
    edited 2013-05-20 12:45
    @Rsadeika When I said reasonable numbers I was not unhappy the numbers were in the same range
    as other devices and sensors I had in the lab. A couple of degrees hotter and a percent H higher but who
    is to say which is right. Same goes for your digital thermometer who is to say if it is right , actually it and the
    sensor could be one up a couple of degrees and the other down a couple.

    Since we now have floating point in the new Propeller C I decided to check the fixed point way I was doing the
    sensor calculations by doing a floating point version right inline with the calculations. Doing it inline means I
    am using the same raw counts for both calculations of the same value.
    I like the numbers only rhtrue is a degree low and I need to go look at that.

    @Feedback on Propeller C
    The size of the project increased from the 4624 bytes to 16000 bytes by adding math.h for the floating point calcs.
    I wondered if I needed to add math.h just to use floats because I am not using any math functions and so I took it
    out and it built fine but it did not calculate any of the floating point values. It does not tell you you forgot to include
    math.h just keeps it a secret.
    I do not know if that is what was intended.

    Changes made to add floating point constants from V5 Data Sheet
    /*V5 Constants*/
       /*Fractional parts of constants cannot be greator than 1*/
    #define   Kd1C_16_16    25991578  //  10 * 39.66 @ 3.3 Volts, is minus but do a subtract instead of sign here
    #define   Kd1C_fp       -39.66
    #define   Kd1F_16_16    25834291  //  10 * 39.42 @ 3.3 Volts, is minus but do a subtract instead of sign here
    #define   Kd1F_fp       -39.42
    #define   Kd2C_0_16   6554       // 10 * 0.01
    #define   Kd2C_fp     0.01
    #define   Kd2F_0_16   11796      // 10 * 0.018
    #define   Kd2F_fp     0.018
       /*RHlin constants to compute 10 times RHlin*/
    #define   Kc3_0_16   1               // 1.5955e-5 times 65536 actually 1.04 rounded up
    #define   Kc3_0_24   268         // 1.5955e-5 as a 24 bit fraction ie times 2^24
    #define   Kc3_0_32   85899       // 10 * 2e**-6  times 2**32
    #define   Kc3_fp     -1.5955e-6
    #define   Kc2_0_16   24052        // 10 * 0.0367 times 65536
    #define   Kc2_fp     0.0367
    #define   Kc1_16_16   1341391     // 10 * 2.0468 times 65536
    #define   Kc1_fp     -2.0468
     
       /*Constants to compute RH true ie RHlin adjusted for temp different than 25 Deg C
        RHtrue = (TC - 25)* (t1 + t2* SOH) + RHlin
        We have 10 times RHlin so multiply constants by 10*/
    #define  Kt1_0_16    6554    // 0.1 * 65536
    #define  Kt1_fp      1.0e-2  // 0.01
    #define  Kt2_0_16    52      // 0.0008 * 65536
    #define  Kt2_fp      8.0e-5  // 0.00008
    
    

    New measure function with floating point calcs added
    int Measure() {
    long rhtru;
    long stat;
    long humraw;
    long humlin;
    long tmpC;
    long traw;
    double humlinfp;
    double tmpCfp;
    double tmpFfp;
    double rhtrufp;
    /*Take a measurement of Temp and RH Humidity Values*/
    /* Do the complete measurement of Temp ==> RHlin ==> Rhtrue */
    /* Computing 10 times Values*/
    
        /*Get the raw humidity counts and convert th RHlin*/
        stat = SendCommand(KREADHUM);
        humraw = ReadValue();
        humlin = RawToRHlin(humraw);
        //waitcnt(clkfreq/1000 + cnt)
        pause(1);
        // DO IT IN FLOATING POINT
        humlinfp = Kc1_fp + Kc2_fp * humraw + Kc3_fp * (humraw * humraw);
        /*Get the raw temp counts and convert to Deg C*/
        pause(1);
        stat = SendCommand(KREADTEMP);
        traw = ReadValue();
        tmpC = RawToTempC(traw);
        //waitcnt(clkfreq/1000 + cnt)
        pause(1);
        //DO IT IN FLOATING POINT
        tmpCfp = Kd1C_fp + (Kd2C_fp * traw);
        tmpFfp = Kd1F_fp + (Kd2F_fp * traw);
        pause(1);
        /*Correct humlin for a temp different than 25 Deg C*/
        rhtru = Kt2_0_16 * humraw;    // 0:16 * 16:0 ==> 16:16  t2 * raw counts
        rhtru = rhtru  + Kt1_0_16;     // 16:16 + 0:16  ==> 16:16  t1 + t2 * raw
        /*Had to divide temp dif by 10 because without it the result of the multiply became
         a false negitive number. Without the div by 10 we are actually calculating 100 times
         because we have 10 times the temp dif and 10 times the constants.
         Another way to do it would be to only do the constants as is without multipling them by 10.
         That is what Tracy did*/
        rhtru = rhtru  * ( tmpC - 250L)/10L; // 16:16 * 16:0  ==> 32:16
        rhtru = rhtru  / 65536L;         // 16:0
        rhtru = rhtru + humlin;       // ==> 10 times RH true
        
        //DO IT IN FLOATING POINT
        rhtrufp = (tmpCfp - 25.0) * (Kt1_fp + Kt2_fp * traw) + humlinfp;
        
        /*Update the values*/
        avalues->rawhum =  humraw;
        avalues->rawtemp = traw;
        avalues->rhlin   = humlin;
        avalues->rhtrue  = rhtru;
        avalues->tempC  = tmpC;
        avalues->tempF   = RawToTempF(traw);
        avalues->rhlinfp   = humlinfp;
        avalues->rhtruefp  = rhtrufp;
        avalues->tempCfp  = tmpCfp;
        avalues->tempFfp   = tmpFfp;
       
        return(0);
    }
     
    

    Attached screen capture of it executing

    Tom
    538 x 558 - 39K
  • jazzedjazzed Posts: 11,803
    edited 2013-05-20 13:06
    tdlivings wrote: »
    @Feedback on Propeller C
    The size of the project increased from the 4624 bytes to 16000 bytes by adding math.h for the floating point calcs.

    Andy and I worked on this code size explosion over the weekend. C has a lot of standard requirements, and providing a library that offers a subset of the requirements (instead of the whole enchilada) drastically reduces the memory footprint. The Tiny library attempts this already, but it has problems. Stay tuned.

    BTW, which math.h functions did you need? I don't see anything math.h specific.
  • tdlivingstdlivings Posts: 437
    edited 2013-05-20 14:08
    @jazzed
    Maybe I am thinking wrong when I said no math.h I am assuming that is what unchecking Math Lib in
    the linker tab puts in or takes out.
    As you said I am not using any functions from math.h.
    If I uncheck Math Lib in the linker tab none of the floating point calcs are executed as shown in the attached pic

    Tom
    538 x 558 - 34K
  • jazzedjazzed Posts: 11,803
    edited 2013-05-20 14:31
    tdlivings wrote: »
    @jazzed
    Maybe I am thinking wrong when I said no math.h I am assuming that is what unchecking Math Lib in
    the linker tab puts in or takes out.

    Yes, I see. Checking Math Lib only "links" the library. It does not "#include <math.h>" for you.
    tdlivings wrote: »
    As you said I am not using any functions from math.h.
    If I uncheck Math Lib in the linker tab none of the floating point calcs are executed as shown in the attached pic

    Right. With the current printf, if you don't link the math lib, you generally will not see floating point output (often I have seen messages saying to link the library). We are working on a "simple library" version of printf, scanf, and friends that do not require linking the math library and results in a much smaller program binary (all floating point will be 32bit).
Sign In or Register to comment.