Interfacing DS1620 Digital Thermometer and Hitachi H48C Tri-Axis Accelerometer Module
dconvict
Posts: 2
hi
we are working on a project in which we need to interface the hitachi h48c accelerometer and the ds1620 digital thermometer. we would like to the accelerometer take its reading, and if the value recorded for g-force exceeds our designated value (decimal value of 30), then the thermometer should take the temperature. the accelerometer reads in ASCII and we are having difficulty assigning this value.
we are fairly new to basic stamp and any insight you guys could give would be great. thanks
http://www.parallax.com/tabid/768/ProductID/97/Default.aspx accelerometer
http://www.parallax.com/dl/docs/prod/appkit/ds1620thermometer.pdf digital thermometer
here is the code:
[HTML]'Device reads temp when movement is detected with accelerometer.
'
' {$STAMP BS2}
' {$PBASIC 2.5}
' ===================== Define Pins and Variables ================
DQ CON 2 ' Pin 2 <=> DQ. Thermometer (T)
CLK_T CON 1 ' Pin 1 => CLK_T. (T)
RST CON 0 ' Pin 0 => RST (high = active). T)
Dio PIN 15 ' data to/from Accelermometr module
CLK_A PIN 14 ' clock output (A)
CS PIN 13 ' active-low chip select for Accelermometr (A)
' >>> Thermometer
DSdata VAR Word ' Word variable to hold 9-bit data. (T)
Sign VAR DSdata.BIT8 ' Sign bit of raw temperature data. (T)
T_sign VAR Bit ' Saved sign bit for converted temperature. (T)
' >>> Accelerometer
axis VAR Nib ' axis selection
rvCount VAR Word ' ref voltage adc counts
axCount VAR Word ' axis voltage adc counts
mVolts VAR Word ' millivolts
gForce VAR Word ' axis g-force
dValue VAR Word ' display value
dPad VAR Nib ' display pad
XOld VAR Word ' g-force for old x
YOld VAR Word ' g-force for old y
ZOld VAR Word ' g-force for old z
' ===================== Constants ===================
' >>> Constants for configuring the DS1620
Rconfig CON $AC ' Protocol for 'Read Configuration.' (T)
Wconfig CON $0C ' Protocol for 'Write Configuration.' (T)
CPU CON %10 ' Config bit: serial thermometer mode. (T)
NoCPU CON %00 ' Config bit: standalone thermostat mode. (T)
OneShot CON %01 ' Config bit: one conversion per start request. (T)
Cont CON %00 ' Config bit: continuous conversions after start. (T)
' >>> Constants for serial thermometer applications.
StartC CON $EE ' Protocol for 'Start Conversion.' (T)
StopC CON $22 ' Protocol for 'Stop Conversion.' (T)
Rtemp CON $AA ' Protocol for 'Read Temperature.' (T)
' >>> Constants for programming thermostat functions.
RhiT CON $A1 ' Protocol for 'Read High-Temperature Setting.' (T)
WhiT CON $01 ' Protocol for 'Write High-Temperature Setting.' (T)
RloT CON $A2 ' Protocol for 'Read Low-Temperature Setting.' (T)
WloT CON $02 ' Protocol for 'Write Low-Temperature Setting.'(T)
' >>> Accelermometer
XAxis CON 0 ' adc channels (A)
YAxis CON 1 ' (A)
ZAxis CON 2 ' (A)
VRef CON 3
Cnt2Mv CON $CE4C ' counts to millivolts
' 0.80586 with **
GfCnv CON $3852 ' g-force conversion
' 0.22 with **
dif CON 30 ' *****change needed to detect movement for accelerometer. This is part of our problem**********
' ===================== Begin Program ============================
' >>> Accelerometer
FOR axis = XAxis TO ZAxis ' loop through each axis
GOSUB Get_H48C ' read vRef & axis counts
dValue = rvCount ' display vRef count
dValue = axCount ' display axis count
mVolts = rvCount ** Cnt2Mv ' convert vref to mv
mVolts = axCount ** Cnt2Mv ' convert axis to mv
' calculate g-force
IF (axCount >= rvCount) THEN
gForce = (axCount - rvCount) ** GfCnv ' positive g-force
ELSE
gForce = -((rvCount - axCount) ** GfCnv) ' negative g-force
ENDIF
IF (axis = XAxis) THEN
XOld = gForce
ELSEIF (axis = YAxis)THEN
YOld = gForce
ELSE
ZOld = gForce
ENDIF
NEXT
PAUSE 200
Main:
FOR axis = XAxis TO ZAxis ' loop through each axis
GOSUB Get_H48C ' read vRef & axis counts
dValue = rvCount ' display vRef count
dValue = axCount ' display axis count
mVolts = rvCount ** Cnt2Mv ' convert vref to mv
mVolts = axCount ** Cnt2Mv ' convert axis to mv
' calculate g-force
IF (axCount >= rvCount) THEN
gForce = (axCount - rvCount) ** GfCnv ' positive g-force
ELSE
gForce = -((rvCount - axCount) ** GfCnv) ' negative g-force
ENDIF
'******this part of the code is supposed to start the temperature reading when there
'is a change in the gForce that is greater than what we pick for the different constants above.
'We are not sure what value to use for the different constant though because the accelerometer
'reads in ACSII. The decimal value we want it to be around is 30
IF (axis = XAxis) THEN
IF gForce > XOld + dif THEN
GOTO Temp
ELSEIF gForce < XOld - dif THEN
GOTO Temp
ELSE
XOld = gForce
ENDIF
ELSEIF (axis = YAxis)THEN
IF gForce > YOld + dif THEN
GOTO Temp
ELSEIF gForce < YOld - dif THEN
GOTO Temp
ELSE
YOld = gForce
ENDIF
ELSE
IF gForce > ZOld + dif THEN
GOTO Temp
ELSEIF gForce < ZOld - dif THEN
GOTO Temp
ELSE
ZOld = gForce
ENDIF
ENDIF
IF (axis = XAxis) THEN
XOld = gForce
ELSEIF (axis = YAxis)THEN
YOld = gForce
ELSE
ZOld = gForce
ENDIF
NEXT
PAUSE 200
GOTO Main
Temp:
LOW RST ' Deactivate '1620 for now. (T)
HIGH CLK_T ' Put clock in starting state. (T)
PAUSE 100 ' Let things settle down a moment. (T)
HIGH RST ' Activate the '1620 and set it for continuous..
SHIFTOUT DQ,CLK_T,LSBFIRST,[Wconfig,CPU+Cont] ' ..temp conversions. (T)
LOW RST ' Done--deactivate. (T)
PAUSE 50 ' Wait for the EEPROM to self-program. (T)
HIGH RST ' Now activate it again and send the..
SHIFTOUT DQ,CLK_T,LSBFIRST,[StartC] ' Send start-conversion protocol. (T)
LOW RST ' Done--deactivate. (T)
' >>> The loop below continuously reads the latest temperature from the DS1620.
again:
PAUSE 1000 ' Wait a second between readings. (T)
HIGH RST ' Activate the '1620.
SHIFTOUT DQ,CLK_T,LSBFIRST,[Rtemp] ' Request to read temperature. (T)
SHIFTIN DQ,CLK_T,LSBPRE,[DSdata\9] ' Get the temperature reading. (T)
LOW RST
T_sign = Sign ' Save the sign bit of the reading. (T)
DSdata = DSdata/2 ' Scale reading to whole degrees C. (T)
IF T_sign = 0 THEN no_neg1
DSdata = DSdata | $FF00 ' Extend sign bits for negative temps. (T)
no_neg1:
DEBUG SDEC DSdata," degrees C",CR ' Show signed temperature in C. (T)
DSDATa = (DSdata */ $01CC) ' Multiply by 1.8. (T)
IF T_sign = 0 THEN no_neg2 ' If negative, extend sign bits. (T)
DSdata = DSdata | $FF00
no_neg2:
DSdata = DSdata + 32 ' Complete the conversion. (T)
DEBUG SDEC DSdata," degrees F",CR ' Show signed temperature in F. (T)
GOTO again ' Repeat forever. (T)
' ===================== Subroutines ===================
' Reads VRef and selected H48C axis through an MCP3204 ADC
' -- pass axis (0 - 2) in "axis"
' -- returns reference voltage counts in "rvCount"
' -- returns axis voltage counts in "axCounts"
Get_H48C:
LOW CS
SHIFTOUT Dio, CLK_A, MSBFIRST, [%11\2, VRef\3] ' select vref register
SHIFTIN Dio, CLK_A, MSBPOST, [rvCount\13] ' read ref voltage counts
HIGH CS
PAUSE 1
'DEBUG CR,CR,CR,"HIIIIIIIIIII ", DEC rvCount, CR, CR,CR,CR
LOW CS
SHIFTOUT Dio, CLK_A, MSBFIRST, [%11\2, axis\3] ' select axis
SHIFTIN Dio, CLK_A, MSBPOST, [axCount\13] ' read axis voltage counts
HIGH CS
RETURN
[/HTML]
we are working on a project in which we need to interface the hitachi h48c accelerometer and the ds1620 digital thermometer. we would like to the accelerometer take its reading, and if the value recorded for g-force exceeds our designated value (decimal value of 30), then the thermometer should take the temperature. the accelerometer reads in ASCII and we are having difficulty assigning this value.
we are fairly new to basic stamp and any insight you guys could give would be great. thanks
http://www.parallax.com/tabid/768/ProductID/97/Default.aspx accelerometer
http://www.parallax.com/dl/docs/prod/appkit/ds1620thermometer.pdf digital thermometer
here is the code:
[HTML]'Device reads temp when movement is detected with accelerometer.
'
' {$STAMP BS2}
' {$PBASIC 2.5}
' ===================== Define Pins and Variables ================
DQ CON 2 ' Pin 2 <=> DQ. Thermometer (T)
CLK_T CON 1 ' Pin 1 => CLK_T. (T)
RST CON 0 ' Pin 0 => RST (high = active). T)
Dio PIN 15 ' data to/from Accelermometr module
CLK_A PIN 14 ' clock output (A)
CS PIN 13 ' active-low chip select for Accelermometr (A)
' >>> Thermometer
DSdata VAR Word ' Word variable to hold 9-bit data. (T)
Sign VAR DSdata.BIT8 ' Sign bit of raw temperature data. (T)
T_sign VAR Bit ' Saved sign bit for converted temperature. (T)
' >>> Accelerometer
axis VAR Nib ' axis selection
rvCount VAR Word ' ref voltage adc counts
axCount VAR Word ' axis voltage adc counts
mVolts VAR Word ' millivolts
gForce VAR Word ' axis g-force
dValue VAR Word ' display value
dPad VAR Nib ' display pad
XOld VAR Word ' g-force for old x
YOld VAR Word ' g-force for old y
ZOld VAR Word ' g-force for old z
' ===================== Constants ===================
' >>> Constants for configuring the DS1620
Rconfig CON $AC ' Protocol for 'Read Configuration.' (T)
Wconfig CON $0C ' Protocol for 'Write Configuration.' (T)
CPU CON %10 ' Config bit: serial thermometer mode. (T)
NoCPU CON %00 ' Config bit: standalone thermostat mode. (T)
OneShot CON %01 ' Config bit: one conversion per start request. (T)
Cont CON %00 ' Config bit: continuous conversions after start. (T)
' >>> Constants for serial thermometer applications.
StartC CON $EE ' Protocol for 'Start Conversion.' (T)
StopC CON $22 ' Protocol for 'Stop Conversion.' (T)
Rtemp CON $AA ' Protocol for 'Read Temperature.' (T)
' >>> Constants for programming thermostat functions.
RhiT CON $A1 ' Protocol for 'Read High-Temperature Setting.' (T)
WhiT CON $01 ' Protocol for 'Write High-Temperature Setting.' (T)
RloT CON $A2 ' Protocol for 'Read Low-Temperature Setting.' (T)
WloT CON $02 ' Protocol for 'Write Low-Temperature Setting.'(T)
' >>> Accelermometer
XAxis CON 0 ' adc channels (A)
YAxis CON 1 ' (A)
ZAxis CON 2 ' (A)
VRef CON 3
Cnt2Mv CON $CE4C ' counts to millivolts
' 0.80586 with **
GfCnv CON $3852 ' g-force conversion
' 0.22 with **
dif CON 30 ' *****change needed to detect movement for accelerometer. This is part of our problem**********
' ===================== Begin Program ============================
' >>> Accelerometer
FOR axis = XAxis TO ZAxis ' loop through each axis
GOSUB Get_H48C ' read vRef & axis counts
dValue = rvCount ' display vRef count
dValue = axCount ' display axis count
mVolts = rvCount ** Cnt2Mv ' convert vref to mv
mVolts = axCount ** Cnt2Mv ' convert axis to mv
' calculate g-force
IF (axCount >= rvCount) THEN
gForce = (axCount - rvCount) ** GfCnv ' positive g-force
ELSE
gForce = -((rvCount - axCount) ** GfCnv) ' negative g-force
ENDIF
IF (axis = XAxis) THEN
XOld = gForce
ELSEIF (axis = YAxis)THEN
YOld = gForce
ELSE
ZOld = gForce
ENDIF
NEXT
PAUSE 200
Main:
FOR axis = XAxis TO ZAxis ' loop through each axis
GOSUB Get_H48C ' read vRef & axis counts
dValue = rvCount ' display vRef count
dValue = axCount ' display axis count
mVolts = rvCount ** Cnt2Mv ' convert vref to mv
mVolts = axCount ** Cnt2Mv ' convert axis to mv
' calculate g-force
IF (axCount >= rvCount) THEN
gForce = (axCount - rvCount) ** GfCnv ' positive g-force
ELSE
gForce = -((rvCount - axCount) ** GfCnv) ' negative g-force
ENDIF
'******this part of the code is supposed to start the temperature reading when there
'is a change in the gForce that is greater than what we pick for the different constants above.
'We are not sure what value to use for the different constant though because the accelerometer
'reads in ACSII. The decimal value we want it to be around is 30
IF (axis = XAxis) THEN
IF gForce > XOld + dif THEN
GOTO Temp
ELSEIF gForce < XOld - dif THEN
GOTO Temp
ELSE
XOld = gForce
ENDIF
ELSEIF (axis = YAxis)THEN
IF gForce > YOld + dif THEN
GOTO Temp
ELSEIF gForce < YOld - dif THEN
GOTO Temp
ELSE
YOld = gForce
ENDIF
ELSE
IF gForce > ZOld + dif THEN
GOTO Temp
ELSEIF gForce < ZOld - dif THEN
GOTO Temp
ELSE
ZOld = gForce
ENDIF
ENDIF
IF (axis = XAxis) THEN
XOld = gForce
ELSEIF (axis = YAxis)THEN
YOld = gForce
ELSE
ZOld = gForce
ENDIF
NEXT
PAUSE 200
GOTO Main
Temp:
LOW RST ' Deactivate '1620 for now. (T)
HIGH CLK_T ' Put clock in starting state. (T)
PAUSE 100 ' Let things settle down a moment. (T)
HIGH RST ' Activate the '1620 and set it for continuous..
SHIFTOUT DQ,CLK_T,LSBFIRST,[Wconfig,CPU+Cont] ' ..temp conversions. (T)
LOW RST ' Done--deactivate. (T)
PAUSE 50 ' Wait for the EEPROM to self-program. (T)
HIGH RST ' Now activate it again and send the..
SHIFTOUT DQ,CLK_T,LSBFIRST,[StartC] ' Send start-conversion protocol. (T)
LOW RST ' Done--deactivate. (T)
' >>> The loop below continuously reads the latest temperature from the DS1620.
again:
PAUSE 1000 ' Wait a second between readings. (T)
HIGH RST ' Activate the '1620.
SHIFTOUT DQ,CLK_T,LSBFIRST,[Rtemp] ' Request to read temperature. (T)
SHIFTIN DQ,CLK_T,LSBPRE,[DSdata\9] ' Get the temperature reading. (T)
LOW RST
T_sign = Sign ' Save the sign bit of the reading. (T)
DSdata = DSdata/2 ' Scale reading to whole degrees C. (T)
IF T_sign = 0 THEN no_neg1
DSdata = DSdata | $FF00 ' Extend sign bits for negative temps. (T)
no_neg1:
DEBUG SDEC DSdata," degrees C",CR ' Show signed temperature in C. (T)
DSDATa = (DSdata */ $01CC) ' Multiply by 1.8. (T)
IF T_sign = 0 THEN no_neg2 ' If negative, extend sign bits. (T)
DSdata = DSdata | $FF00
no_neg2:
DSdata = DSdata + 32 ' Complete the conversion. (T)
DEBUG SDEC DSdata," degrees F",CR ' Show signed temperature in F. (T)
GOTO again ' Repeat forever. (T)
' ===================== Subroutines ===================
' Reads VRef and selected H48C axis through an MCP3204 ADC
' -- pass axis (0 - 2) in "axis"
' -- returns reference voltage counts in "rvCount"
' -- returns axis voltage counts in "axCounts"
Get_H48C:
LOW CS
SHIFTOUT Dio, CLK_A, MSBFIRST, [%11\2, VRef\3] ' select vref register
SHIFTIN Dio, CLK_A, MSBPOST, [rvCount\13] ' read ref voltage counts
HIGH CS
PAUSE 1
'DEBUG CR,CR,CR,"HIIIIIIIIIII ", DEC rvCount, CR, CR,CR,CR
LOW CS
SHIFTOUT Dio, CLK_A, MSBFIRST, [%11\2, axis\3] ' select axis
SHIFTIN Dio, CLK_A, MSBPOST, [axCount\13] ' read axis voltage counts
HIGH CS
RETURN
[/HTML]
Comments
A direct compare with a threshold should be easy. Be aware that the Stamp does not do comparisons (IF x>y) with negative numbers. Do you care about direction? You might need to select the direction and/or take the absolute value. The number 30 means 0.3g. It appears you are looking for changes in acceleration over a sampling interval of 200ms. Again, watch out for the minus signs.