Shop OBEX P1 Docs P2 Docs Learn Events
Sample code for temperature from Gyroscope Module 3-Axis L3G4200D (#27911) — Parallax Forums

Sample code for temperature from Gyroscope Module 3-Axis L3G4200D (#27911)

kmc123kmc123 Posts: 33
edited 2013-04-01 06:36 in Accessories
Does anyone have any sample code for reading temperature with the Gyroscope Module 3-Axis L3G4200D (#27911)?
I have it set up and working, but I have no idea how to read the temp - The sample code on the product page shows X Y and Z readings - I'm looking for a simple temp reading from a BS2.

Does anyone have something to share?

Comments

  • stuartXstuartX Posts: 88
    edited 2012-02-14 07:05
    I just use the DS1620 chip for temperature, its much simpler for me.
  • kmc123kmc123 Posts: 33
    edited 2012-02-14 08:16
    Thanks Stuart - I know there are other ways but I already have this and as an added benefit it has the ability to give temp readings - I just need help on how to read it...
    Anyone???
  • kmc123kmc123 Posts: 33
    edited 2012-02-15 15:06
    Man - I'm pulling my hair out on this one (And I don't have much left ;) )

    This is the only sensor / product that I have ever purchased from Parallax that does not have sample code or examples on how to use one of it's features...

    I attempted the following code on a whim (It's really just taking the sample code and plugging in OUT_TEMP instead of OUT_X_INC in the code.

    I get numbers returned, but they are very low numbers (10-20) and I have no idea if I'm on the right track or if I am, how to convert those numbers to a temperature scale for degrees C or F...

    There has to be someone out there that has read temp from one of these, Right :)

    Parallax??? Can you help with a piece of example code?


    ' ============================================================================
    ' L3G4200D_Gyroscope_Demo.bs2 - This is a Gyroscope Module test program, it
    ' displays the X,Y,Z raw data from this device.
    '
    ' Author.... (C) 2009 Parallax, Inc -- All Rights Reserved
    '
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    ' ============================================================================
    ' -----[ Pins/Constants/Variables ]-------------------------------------------
    SDA            PIN      1                    ' P0 transceives to/from SDA
    SCL            PIN      0                    ' P1 sends clock pulses
    '----[Registers]--------------------------------------------------------------
      WRITE_Data   CON $D2     'Used to perform a Write operation
      READ_Data    CON $D3     'Used to perform a Read operation
      WHO_AM_I      CON $0F
      CTRL_REG1     CON $20    'SUB $A0
      CTRL_REG2     CON $21
      CTRL_REG3     CON $22
      CTRL_REG4     CON $23
      CTRL_REG5     CON $24
      REFERENCE     CON $25
      OUT_TEMP      CON $26
      STATUS_REG    CON $27
      OUT_X_L       CON $28
      OUT_X_INC     CON $A8
      OUT_X_H       CON $29
      OUT_Y_L       CON $2A
      OUT_Y_H       CON $2B
      OUT_Z_L       CON $2C
      OUT_Z_H       CON $2D
      FIFO_CTRL_REG CON $2E
      FIFO_SRC_REG  CON $2F
      INT1_CFG      CON $30
      INT1_SRC      CON $31
      INT1_TSH_XH   CON $32
      INT1_TSH_XL   CON $33
      INT1_TSH_YH   CON $34
      INT1_TSH_YL   CON $35
      INT1_TSH_ZH   CON $36
      INT1_TSH_ZL   CON $37
      INT1_DURATION CON $38
    I2C_DATA       VAR      Byte
    I2C_LSB        VAR      Bit
    I2C_REG        VAR      Byte
    I2C_VAL        VAR      Byte
    X              VAR      Word
    Y              VAR      Word
    Z              VAR      Word
    T              VAR      Word
    rawl           VAR      Word
    rawh           VAR      Word
    CX             VAR      Word
    CY             VAR      Word
    CZ             VAR      Word
    reps           VAR      Byte
    ' -----[ Main Routine ]-------------------------------------------------------
    PAUSE 100
      ' Set up data ready signal
      I2C_REG = CTRL_REG3
      I2C_VAL = $08
      GOSUB I2C_Write_Reg
      ' Set up "block data update" mode
      I2C_REG = CTRL_REG4
      I2C_VAL = $80
      GOSUB I2C_Write_Reg
      ' Send the get continuous output command
      I2C_REG = CTRL_REG1
      I2C_VAL = $1F
      GOSUB I2C_Write_Reg
    DO
      GOSUB Gyro_Get_Temp
      DEBUG HOME, "Temp = ", 11, SDEC T, CR
    LOOP
    
    ' -----[ Subroutines ]--------------------------------------------------------
    Gyro_Get_Temp:
    GOSUB Wait_For_Data_Ready
      GOSUB I2C_Start
            I2C_DATA = WRITE_DATA
      GOSUB I2C_Write                            ' Read the data starting at pointer register
            I2C_DATA = OUT_TEMP
      GOSUB I2C_Write
      GOSUB I2C_Stop
    
      GOSUB I2C_Start
            I2C_DATA = READ_DATA
      GOSUB I2C_Write
    
      GOSUB I2C_Read
            rawL = I2C_DATA                    ' Read in the high byte
      GOSUB I2C_ACK
      'GOSUB I2C_Read
            'rawH = I2C_DATA                    ' Read in the low byte
      'GOSUB I2C_ACK
            'T = (rawH << 8) | rawL             ' OR high and low into T
            T = rawL
    RETURN
     
    ' Read the status register until the ZYXDA bit is high
    Wait_For_Data_Ready:
    DO
      I2C_REG = STATUS_REG
      GOSUB I2C_Read_Reg
    LOOP UNTIL ((I2C_DATA & $08) <> 0)
    RETURN
    ' Set I2C_REG & I2C_VAL before calling this
    I2C_Write_Reg:
      GOSUB I2C_Start
      I2C_DATA = WRITE_DATA
      GOSUB I2C_Write
      I2C_DATA = I2C_REG
      GOSUB I2C_Write
      I2C_DATA = I2C_VAL
      GOSUB I2C_Write
      GOSUB I2C_Stop
    RETURN
    ' Set I2C_REG before calling this, I2C_DATA will have result
    I2C_Read_Reg:
      GOSUB I2C_Start
      I2C_DATA = WRITE_DATA
      GOSUB I2C_Write
      I2C_DATA = I2C_REG
      GOSUB I2C_Write
      GOSUB I2C_Stop
      GOSUB I2C_Start
      I2C_DATA = READ_DATA
      GOSUB I2C_Write
      GOSUB I2C_Read
      GOSUB I2C_NACK
      GOSUB I2C_Stop
    RETURN
    I2C_Start:
      LOW SDA                                    ' Pull SDA low
      LOW SCL                                    ' Pull SCL low
    RETURN
    I2C_Stop:
      LOW   SDA                                  ' Pull SDA low
      INPUT SCL                                  ' Let SCL float high
      INPUT SDA                                  ' Let SDA float high
    RETURN
    I2C_ACK:
      LOW   SDA                                  ' Pull SDA low
      INPUT SCL                                  ' Let SCL float high
      LOW   SCL                                  ' Pull SCL low
      INPUT SDA                                  ' Let SDA float high
    RETURN
    I2C_NACK:
      INPUT SDA                                  ' Let SDA float high
      INPUT SCL                                  ' Let SCL float high
      LOW   SCL                                  ' Pull SCL low
    RETURN
    I2C_Read:
      SHIFTIN SDA, SCL, MSBPRE, [I2C_DATA]       ' Read in 8 bits, MSB first
    RETURN
    I2C_Write:
      I2C_LSB = I2C_DATA.BIT0                    ' Store the status of the LSB
      I2C_DATA = I2C_DATA / 2
      SHIFTOUT SDA, SCL, MSBFIRST, [I2C_DATA\7]  ' Write out the first 7 bits, MSB first
      IF I2C_LSB THEN INPUT SDA ELSE LOW SDA     ' Write the 8th bit
      INPUT SCL                                  ' Using an open collector output
      LOW SCL
      INPUT SDA                                  ' Leave SDA as an input
      INPUT SCL                                  ' Ignore the ACK bit
      LOW SCL
    RETURN
    I3C_Write:
      SHIFTOUT SDA, SCL, MSBFIRST, [I2C_DATA]    ' Write out 8 bits, MSB first
      INPUT SDA                                  ' Leave SDA as an input
      INPUT SCL                                  ' Ignore ACK bit
      LOW SCL
    RETURN
    
    
    
  • stuartXstuartX Posts: 88
    edited 2012-02-15 19:24
    I have search and google everywhere. I can not find any example code pulling temperature information from that chip. I'll keep look to see if I can find something. I was thinking of purchasing the chip to learn it.
  • kmc123kmc123 Posts: 33
    edited 2012-02-15 19:50
    Thanks for trying Stuart - I am sure that someone out there has done this before, it's just a question of will they see this thread :)
  • JimInCAJimInCA Posts: 80
    edited 2012-02-16 08:06
    May I ask why you want to read the temperature from the gyro? I believe that the temperature reading on the gyro is the die temperature which is intended to be used to adjust the gyro reading to compensate for drift due the the change in the die temperature, that is, for calibration of the gyro. I don't believe that it's the ambient temperature.
    Just curious...
    Jim...
  • stuartXstuartX Posts: 88
    edited 2012-02-16 08:07
    @kmc123
    I was searching through the web for this issue, I found a chip (Triple-Axis Digital-Output Gyro ITG-3200)which is a different chip but does the same thing as yours. In the post it was stated on how to retrieve the temperature information.
    {One person asked the following:}
    Gyros work great. I like the built-in filtering options.
    Heads up — for me it came set to use the alternate I2C address (0x69) instead of the default (0x68).
    Has anyone gotten good data from the temperature sensor? I’m getting values around -16,000, at room temp=/.

    {The reply was:}
    The description above mentions that they pulled AD0 high, so 0x69 is the expected address.
    Then see Table 3.1 in the manual. -13200 represents 35 celsius, then every 280 from there is another degree celsius. (Admittedly a bit confusing to decipher from the table).
    So code would look like:
    tempC = 35.0 + ((rawVal + 13200)/280.0);
    Also note that you divide the gyro values by 14.375 to get degrees per second.

    I mention all that to say is that I went to the PDF (27911-GyroscopeAppNote2) listed for Parallax's chip and it
    states the following under section 7.

    7 Temperature sensor
    The L3G4200D is provided with an internal temperature sensor that is suitable for delta
    temperature measurement. Temperature data are generated with a frequency of 1 Hz and
    are stored inside the OUT_TEMP register in two’s complement format, with a sensitivity if -1
    LSB/°C.

    So I'm thinking that you have to retrieve that termperature information from the OUT_TEMP register. I"m not a programmer, but maybe this can give one a hint to get the proper code syntax to retrieve that data.
    I hope that helps in some way.
  • stuartXstuartX Posts: 88
    edited 2012-02-16 10:02
    @kmc123,
    I found a datasheet with more info on the chip/temperature.
    Look at the attachment go to page 34 (or search for table 30 and/or table 40)
    Look at table 39 & table 40. It lists the registers for temperature.
  • kmc123kmc123 Posts: 33
    edited 2012-02-16 10:43
    Thanks Stuart - The code I posted below uses OUT_TEMP which is a Hex 26 and I do get a numeric value in return, but I don't know if I'm doing right because of the return values and even if I am doing it right, there must be a conversion routine / formula to turn the numbers I am seeing into temperature numbers...
  • stuartXstuartX Posts: 88
    edited 2012-02-16 11:25
    Yes, thats why I submitted the post before on the other chip which had some type of conversion for the raw data. what type of numbers were they?
  • ratronicratronic Posts: 1,451
    edited 2012-02-16 20:11
    kmc123 sorry for putting spin code but the register to read is $26 I will look at their stamp example and see if I can adapt it.

    Edit: I had originally put spin code sorry!
  • ratronicratronic Posts: 1,451
    edited 2012-02-16 20:59
    Sorry about the post with spin code, I just tryed to load my bs2 with this code to test it but I am having problems talking to it so this is untested but does compile. Let me know if you see the temp.
    Edit: added corrected code to read temp and gyros 2/22
  • kmc123kmc123 Posts: 33
    edited 2012-02-17 07:37
    Hey Dave,

    Thanks so much for looking at this for me!

    I ran your code and I'm getting the same results as I got in the last code that I posted.

    Currently it is 79 degrees F in my office, and the numbers I am getting with both my code and your code fluctuate between 11 and 13.

    Debug.JPG


    This is obviously not Degrees F or Degrees C (With 11,12, and 13 it would directly convert to 51.8, 53.6, or 55.4 Degrees F) - , and I don't see a logical formula to convert it to either.

    If I take the lowest number I am getting (11) and multiply it by 2 (22) I come CLOSE to the current temp (22 C = 71.6 F) but the 24 and 26 convert to 75.2 and 78.8 which are WAY too high, so it can't be as easy as that :(

    I really appreciate your help and if you have any other ideas I'd love to hear them!!!

    -Kevin
    446 x 349 - 32K
  • ratronicratronic Posts: 1,451
    edited 2012-02-17 08:34
    Edit: Kevin I am far from an expert with using gyros. I also get the same output as you at room temperature. See the attachment Temperature sensor characteristics that should help you to calculate the output you want.

    Edit2: The temp# returned from the gyro is an 8 bit two's complement integer representing -128 to 127. Also note that as the temp goes up the temp register # returned will decrease for every degree celsius and it seems you have about a 14 degree celsius temp offset for real/read room temperature
    1024 x 512 - 88K
    1024 x 532 - 51K
  • kmc123kmc123 Posts: 33
    edited 2012-02-24 19:08
    I do notice that it's calibrated for 3.0 volts and I'm running it from 5 - I'll go get a 3 volt voltage regulator or power it from a prop board to see what the results are...

    ratronic wrote: »
    Edit: Kevin I am far from an expert with using gyros. I also get the same output as you at room temperature. See the attachment Temperature sensor characteristics that should help you to calculate the output you want.

    Edit2: The temp# returned from the gyro is an 8 bit two's complement integer representing -128 to 127. Also note that as the temp goes up the temp register # returned will decrease for every degree celsius and it seems you have about a 14 degree celsius temp offset for real/read room temperature
  • ratronicratronic Posts: 1,451
    edited 2012-02-24 20:12
    Kevin I have tried it with a Propeller @ 3.3volts and a BS2 @ 5volts and get the same output at either voltage at the same room temperature. Reading the temp register when it drops below zero is going to be difficult with a BS2. I am not sure what you are looking for but I ask the same question as JimInCA's post#7?
  • kmc123kmc123 Posts: 33
    edited 2012-02-25 04:05
    Hey Dave,

    Bummer on the lower voltage getting the same result :(

    As far as WHY I want to get temp from it, I wanted to add the temp of my kids treehouse to the 4x20 lcd display and since I'm planning on using this sensor in the treehouse control panel project anyway and it's advertised as "The Gyroscope Module is a low power 3-axis angular rate sensor featuring temperature data as an added bonus." I thought - PERFECT - This is going to be EXACTLY what I need!!! Little did I know it would be this difficult lol


    ratronic wrote: »
    Kevin I have tried it with a Propeller @ 3.3volts and a BS2 @ 5volts and get the same output at either voltage at the same room temperature. Reading the temp register when it drops below zero is going to be difficult with a BS2. I am not sure what you are looking for but I ask the same question as JimInCA's post#7?
  • ratronicratronic Posts: 1,451
    edited 2012-02-25 07:47
    Kevin just to let you know the temp register in the gyro in no way was meant to convey ambient room temperature. It shows the chip temperature in celsius and the temp register output # shows changes in temperature backwards and will have some offset to the real temperature. Sorry but I think you would be better off using something like as stuartX suggested in post#2 to display room temperature on your lcd plus it will save you some major headaches.
    http://www.parallax.com/Store/Sensors/TemperatureHumidity/tabid/174/CategoryID/49/List/0/SortField/0/Level/a/ProductID/84/Default.aspx
  • ratronicratronic Posts: 1,451
    edited 2012-02-25 16:44
    Kevin in case you decide to go with the DS1620 for the kids treehouse here is a program I adapted from Tracy Allen's website to read the DS1620 to the 4x20 LCD. You will have to make sure the pin #'s are set in the constants section for your setup.
    ' {$STAMP BS2}                                                                                             
    ' {$PBASIC 2.5}                                                                                            
                                                                                                               
    'pin/baud constants-----------------                                                                       
    RST  CON 15        'ds1620 rst pin                                                                         
    CLK  CON 14        'ds1620 clk pin                                                                         
    DQ   CON 13        'ds1620 dq pin                                                                          
    LCD  CON 12        '4x20 lcd signal pin                                                                    
                                                                                                               
    BAUD CON 84        'lcd baud rate 9600 true                                                                
                                                                                                               
    'variables--------------------------                                                                       
    x    VAR Word    ' define a general purpose variable                                                       
    sign VAR x.BIT15 ' sign bit of x                                                                           
    degC VAR Word    ' define a variable to hold degrees Celsius                                               
    degF VAR Word    ' to hold degrees Fahrenheit                                                              
                                                                                                               
    'program----------------------------                                                                       
    PAUSE 500                                                                                                  
    SEROUT LCD, BAUD, [12]        'lcd formfeed                                                                
    PAUSE 5                                                                                                    
    SEROUT LCD, BAUD, [22]        'turn off cursor                                                             
    SEROUT LCD, BAUD, [17]        'turn on lcd backlight                                                       
                                                                                                               
    HIGH RST                      'set mode 2 continuous temp reading                                          
    SHIFTOUT DQ,CLK,LSBFIRST,[12,2]                                                                            
    LOW RST                                                                                                    
                                                                                                               
    HIGH RST                      ' select the DS1620                                                          
    SHIFTOUT DQ,CLK,LSBFIRST,[238] ' "start conversions" command                                               
    LOW RST                                                                                                    
                                                                                                               
    DO                            ' going to loop once per second                                              
    HIGH RST                      ' select the DS1620                                                          
    SHIFTOUT DQ,CLK,LSBFIRST,[170]' send the "get data" command                                                
    SHIFTIN DQ,CLK,LSBPRE,[x\9]   ' get the data, including sign                                               
    LOW RST                       ' end the command                                                            
    x.BYTE1 = -x.BIT8             ' extend the sign to 16 bits                                                 
    degC=x*5                      ' convert to 'C*10 (resolution 0.5 'C)                                       
                                                                                                               
    ' & show the result on the LCD------                                                                       
    SEROUT LCD, BAUD, [128, "Celsius    ", REP "-"\degC.BIT15, DEC ABS degC/10, ".", DEC1 ABS degC, "  ", CR]  
    degF= degC+2732*9/5-4598      ' 'C*10 to 'F (first to Kelvin*10)                                           
    SEROUT LCD, BAUD, ["Fahrenheit ", REP "-"\degF.BIT15, DEC ABS degF/10, ".", DEC1 ABS degF, "  ", CR, CR]   
                                                                                                               
    PAUSE 1000                    ' 1 second pause                                                             
    LOOP                          ' read & display temperature again
    
  • Home UserHome User Posts: 1
    edited 2012-07-08 09:38
    I don't know if anyone still needs this, but using the L3G4200D gyro unit with an arduino, I was able to get a temperature reading (accurate enough for my needs) by using:

    L3G4200D gyro;

    // Get Gyro Temperature
    int gyroModuleTemperature()
    {
    return (map(gyro.readReg(0x26), 127, -127, -40, 85)+26) * (9.0/5.0); // Return degrees F.
    }

    You might need to change the +26 value to get your correct offset.
    Hopefully it can help someone.

    kmc123 wrote: »
    Hey Dave,

    Bummer on the lower voltage getting the same result :(

    As far as WHY I want to get temp from it, I wanted to add the temp of my kids treehouse to the 4x20 lcd display and since I'm planning on using this sensor in the treehouse control panel project anyway and it's advertised as "The Gyroscope Module is a low power 3-axis angular rate sensor featuring temperature data as an added bonus." I thought - PERFECT - This is going to be EXACTLY what I need!!! Little did I know it would be this difficult lol
  • verticalearthverticalearth Posts: 1
    edited 2012-08-20 15:41
    FYI

    I emailed Parallax about the temperature data being accurate for a room or an environment.

    "Yes, you can use the temperature reading from the Gyro to have the current temperature of the room or atmosphere that the Gyro is in." - Nick from Parallax

    More you know




  • edawsonedawson Posts: 3
    edited 2012-12-23 09:46
    Sensor Output is 25 at 25 Deg C and the output changes -1 for each Deg change in Temp
    The 25 is not the Temperature it is a Reference number
    To Get the Temperature you have to
    Subtract the Value in OUT_TEMP(26h) Register From 25
    then Add that to 25 Then use it as Deg C or Convert it to Deg F =(Deg C*9/5+32)
    Note The Temp is not ambient Temp it is the Sensor Temperature of the chip
    which changes negative for positive temp changes because that the direction the Measurements are affected
    They increase as temp Decreases so an negative correction is needed.
    To Measure Approx Ambient Temp one could add an offset Correction Number to get closer.
    Comment the temperature measurement is Sensor Temp not ambient. The following can be used to create something somewhat useful

    VAR

    Byte STemp, ESTemp

    PUB ReadTemp
    STemp := Read_1B(OUT_TEMP)
    ESTemp := 25 - STemp
    ESTemp := ESTemp + 25 - 4 'Deg C the -4 is my correction yours may be different
    ESTemp := ESTemp * 9 / 5 +32 'Deg F
  • captainstcaptainst Posts: 1
    edited 2013-02-20 02:26
    edawson wrote: »
    Sensor Output is 25 at 25 Deg C and the output changes -1 for each Deg change in Temp
    The 25 is not the Temperature it is a Reference number
    To Get the Temperature you have to
    Subtract the Value in OUT_TEMP(26h) Register From 25
    then Add that to 25 Then use it as Deg C or Convert it to Deg F =(Deg C*9/5+32)
    Note The Temp is not ambient Temp it is the Sensor Temperature of the chip
    which changes negative for positive temp changes because that the direction the Measurements are affected
    They increase as temp Decreases so an negative correction is needed.
    To Measure Approx Ambient Temp one could add an offset Correction Number to get closer.
    Comment the temperature measurement is Sensor Temp not ambient. The following can be used to create something somewhat useful

    VAR

    Byte STemp, ESTemp

    PUB ReadTemp
    STemp := Read_1B(OUT_TEMP)
    ESTemp := 25 - STemp
    ESTemp := ESTemp + 25 - 4 'Deg C the -4 is my correction yours may be different
    ESTemp := ESTemp * 9 / 5 +32 'Deg F

    I run into the same problem with L3GD20. This should be the most correct solution, although not confirmed by the ST authorities.
    The datasheet is not complete and really misleading on this.
  • GreeceHGreeceH Posts: 1
    edited 2013-04-01 06:36
    kmc123 wrote: »
    Does anyone have something to share?

    I'm using an Arduino with SDA->A4 and SCL->A5 with 5v.

    Try:

    1) If you're in an office, use a can of compressed air to change the temperature of the sensor. A soft stream of air should lower the temperature a degree or two to prove the sensor is working. Alternatively, put the sensor in the sun.

    2) remember to enable to control ready signal.
    #include <Wire.h>
    
    const unsigned int BAUD_RATE = 9600 ;
    
    const int GYRO_READY = 0x08;
    const int GYRO_ADDRESS = 0x69 ; 
    const byte GYRO_READY_REGISTER = 0x22 ;
    const byte GYRO_TEMPERATURE_REGISTER = 0x26 ; 
    
    
    void setup()
    {
      Serial.begin (BAUD_RATE);
      Wire.begin();
      Wire.beginTransmission(GYRO_ADDRESS);
      Wire.write(GYRO_READY_REGISTER);
      Wire.write(GYRO_READY);
      Wire.endTransmission();  
    }
    
    
    void loop()
    {
      byte temperature ;
      Wire.requestFrom(GYRO_ADDRESS, 1);
      if (Wire.available())
      {
        Wire.beginTransmission(GYRO_ADDRESS);
        Wire.write(GYRO_TEMPERATURE_REGISTER);
        Wire.endTransmission();  
      
        temperature = Wire.read();
        Serial.print("Degrees C: ");
        Serial.println (temperature);
      }
      delay(2500); // to slow output to be readable
    }
    
Sign In or Register to comment.