Sample code for temperature from Gyroscope Module 3-Axis L3G4200D (#27911)
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?
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
Anyone???
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
Just curious...
Jim...
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? Im 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 twos 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.
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.
Edit: I had originally put spin code sorry!
Edit: added corrected code to read temp and gyros 2/22
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.
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
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
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
http://www.parallax.com/Store/Sensors/TemperatureHumidity/tabid/174/CategoryID/49/List/0/SortField/0/Level/a/ProductID/84/Default.aspx
' {$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
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.
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
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.
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 }