Problem with propeller code for DS1620 temp sensor
Hello,
I'm currently putting together a temp sensor (DS1620) using a propeller chip and LCD screen. I've managed to get it to all work using code posted in the propeller obex, but I've noticed a problem with the coding. When the temperature is stable, the temp displays normally...however, as soon as the temp changes it displays the temp as being 0C or 32F. I'm not very experienced with the propeller language so I was wondering if anyone could spot what was causing this error. Any help would be greatly appreciated. Thanks!!
This is the main code:
CON
RdTmp = $AA ' read temperature
WrHi = $01 ' write TH (high temp)
WrLo = $02 ' write TL (low temp)
RdHi = $A1 ' read TH
RdLo = $A2 ' read TL
RdCntr = $A0 ' read counter
RdSlope = $A9 ' read slope
StartC = $EE ' start conversion
StopC = $22 ' stop conversion
WrCfg = $0C ' write config register
RdCfg = $AC ' read config register
#0, TempC, TempF
VAR
word dpin, cpin, rst, started
OBJ
io : "shiftio"
delay : "timing"
PUB start(data_pin, clock_pin, rst_pin)
'' Initializes DS1620 for free-run with host CPU
dpin := data_pin
cpin := clock_pin
rst := rst_pin
high(rst) ' activate sensor
io.shiftout(dpin, cpin, io#LsbFirst, WrCfg, 8) ' write to config register
io.shiftout(dpin, cpin, io#LsbFirst, %10, 8) ' set for CPU, free-run
low(rst) ' deactivate
delay.pause1ms(10) ' allow EE write
high(rst) ' reactivate
io.shiftout(dpin, cpin, io#LsbFirst, StartC, 8) ' start conversions
low(rst)
started~~ ' flag sensor as started
PUB gettempc | tc
'' Returns temperature in 0.1° C units
'' -- resolution is 0.5° C
if started
high(rst) ' activate sensor
io.shiftout(dpin, cpin, io#LsbFirst, RdTmp, 8) ' send read temp command
tc := io.shiftin(dpin, cpin, io#LsbPre, 9) ' read temp in 0.5° C units
low(rst) ' deactivate sensor
tc := tc << 23 ~> 23 ' extend sign bit
tc *= 5 ' convert to 10ths
return tc
PUB gettempf | tf
'' Returns temperature in 0.1° F units
'' -- resolution is 0.9° F
if started
tf := gettempc * 9 / 5 + 320 ' convert to Fahrenheit
return tf
PRI high(pin)
outa[pin]~~ ' write "1" to pin
dira[pin]~~ ' make an output
PRI low(pin)
outa[pin]~ ' write "0" to pin
dira[pin]~~ ' make an output
These are the methods called:
'' *****************************
'' * ShiftIO *
'' * (C) 2006 Parallax, Inc. *
'' *****************************
''
'' Mimics SHIFTOUT and SHIFTIN functions of the BS2. For flexibility,
'' the clock pin is toggled so the user must preset the clock line to
'' the idle state:
''
''
'' data
'' clock0
'' clock1
CON
#0, LsbFirst, MsbFirst ' shiftout modes
#0, MsbPre, LsbPre, MsbPost, LsbPost ' shiftin modes
OBJ
delay : "timing"
PUB shiftout(dpin, cpin, mode, value, bits)
dira[dpin]~~ ' make pins outputs
dira[cpin]~~
case mode
LsbFirst:
value <-= 1 ' pre-align lsb
repeat bits
outa[dpin] := (value ->= 1) & 1 ' output data bit
delay.pause10us(1) ' let it settle
!outa[cpin] ' clock the bit
delay.pause10us(1)
!outa[cpin]
MsbFirst:
value <<= (32 - bits) ' pre-align msb
repeat bits
outa[dpin] := (value <-= 1) & 1 ' output data bit
delay.pause10us(1) ' let it settle
!outa[cpin] ' clock the bit
delay.pause10us(1)
!outa[cpin]
PUB shiftoutstr(dpin, cpin, mode, str_addr, count)
repeat count
shiftout(dpin, cpin, mode, byte[str_addr++], 8)
PUB shiftin(dpin, cpin, mode, bits) | value
dira[dpin]~ ' make dpin input
dira[cpin]~~ ' make cpin output
value~ ' clear output
case mode
MsbPre:
repeat bits
value := (value << 1) | ina[dpin]
!outa[cpin] '
delay.pause10us(1)
!outa[cpin]
delay.pause10us(1)
LsbPre:
repeat bits
value := (value >> 1) | (ina[dpin] << 31)
!outa[cpin] '
delay.pause10us(1)
!outa[cpin]
delay.pause10us(1)
value >>= (32 - bits)
MsbPost:
repeat bits
!outa[cpin] '
delay.pause10us(1)
value := (value << 1) | ina[dpin]
!outa[cpin] '
delay.pause10us(1)
LsbPost:
repeat bits
!outa[cpin] '
delay.pause10us(1)
value := (value >> 1) | (ina[dpin] << 31)
!outa[cpin]
delay.pause10us(1)
value >>= (32 - bits)
return value
<code>
'' *****************************
'' * Timing *
'' * (C) 2006 Parallax, Inc. *
'' *****************************
''
'' This object provides time delay and time synchronization functions.
CON
_10us = 1_000_000 / 10 ' Divisor for 10 us
_1ms = 1_000_000 / 1_000 ' Divisor for 1 ms
_1s = 1_000_000 / 1_000_000 ' Divisor for 1 s
VAR
long delay
long syncpoint
long clkcycles
PUB pause10us(period)
'' Pause execution for period (in units of 10 us)
clkcycles := ((clkfreq / _10us * period) - 4296) #> 381 ' Calculate 10 us time unit
waitcnt(clkcycles + cnt) ' Wait for designated time
PUB pause1ms(period)
'' Pause execution for period (in units of 1 ms).
clkcycles := ((clkfreq / _1ms * period) - 4296) #> 381 ' Calculate 1 ms time unit
waitcnt(clkcycles + cnt) ' Wait for designated time
PUB pause1s(period)
'' Pause execution for period (in units of 1 sec).
clkcycles := ((clkfreq / _1s * period) - 4296) #> 381 ' Calculate 1 s time unit
waitcnt(clkcycles + cnt) ' Wait for designated time
PUB marksync10us(period)
delay := (clkfreq / _10us * period) #> 381 ' Calculate 10 us time unit
syncpoint := cnt
PUB waitsync
waitcnt(syncpoint += delay)
</code>
I'm currently putting together a temp sensor (DS1620) using a propeller chip and LCD screen. I've managed to get it to all work using code posted in the propeller obex, but I've noticed a problem with the coding. When the temperature is stable, the temp displays normally...however, as soon as the temp changes it displays the temp as being 0C or 32F. I'm not very experienced with the propeller language so I was wondering if anyone could spot what was causing this error. Any help would be greatly appreciated. Thanks!!
This is the main code:
CON
RdTmp = $AA ' read temperature
WrHi = $01 ' write TH (high temp)
WrLo = $02 ' write TL (low temp)
RdHi = $A1 ' read TH
RdLo = $A2 ' read TL
RdCntr = $A0 ' read counter
RdSlope = $A9 ' read slope
StartC = $EE ' start conversion
StopC = $22 ' stop conversion
WrCfg = $0C ' write config register
RdCfg = $AC ' read config register
#0, TempC, TempF
VAR
word dpin, cpin, rst, started
OBJ
io : "shiftio"
delay : "timing"
PUB start(data_pin, clock_pin, rst_pin)
'' Initializes DS1620 for free-run with host CPU
dpin := data_pin
cpin := clock_pin
rst := rst_pin
high(rst) ' activate sensor
io.shiftout(dpin, cpin, io#LsbFirst, WrCfg, 8) ' write to config register
io.shiftout(dpin, cpin, io#LsbFirst, %10, 8) ' set for CPU, free-run
low(rst) ' deactivate
delay.pause1ms(10) ' allow EE write
high(rst) ' reactivate
io.shiftout(dpin, cpin, io#LsbFirst, StartC, 8) ' start conversions
low(rst)
started~~ ' flag sensor as started
PUB gettempc | tc
'' Returns temperature in 0.1° C units
'' -- resolution is 0.5° C
if started
high(rst) ' activate sensor
io.shiftout(dpin, cpin, io#LsbFirst, RdTmp, 8) ' send read temp command
tc := io.shiftin(dpin, cpin, io#LsbPre, 9) ' read temp in 0.5° C units
low(rst) ' deactivate sensor
tc := tc << 23 ~> 23 ' extend sign bit
tc *= 5 ' convert to 10ths
return tc
PUB gettempf | tf
'' Returns temperature in 0.1° F units
'' -- resolution is 0.9° F
if started
tf := gettempc * 9 / 5 + 320 ' convert to Fahrenheit
return tf
PRI high(pin)
outa[pin]~~ ' write "1" to pin
dira[pin]~~ ' make an output
PRI low(pin)
outa[pin]~ ' write "0" to pin
dira[pin]~~ ' make an output
These are the methods called:
'' *****************************
'' * ShiftIO *
'' * (C) 2006 Parallax, Inc. *
'' *****************************
''
'' Mimics SHIFTOUT and SHIFTIN functions of the BS2. For flexibility,
'' the clock pin is toggled so the user must preset the clock line to
'' the idle state:
''
''
'' data
'' clock0
'' clock1
CON
#0, LsbFirst, MsbFirst ' shiftout modes
#0, MsbPre, LsbPre, MsbPost, LsbPost ' shiftin modes
OBJ
delay : "timing"
PUB shiftout(dpin, cpin, mode, value, bits)
dira[dpin]~~ ' make pins outputs
dira[cpin]~~
case mode
LsbFirst:
value <-= 1 ' pre-align lsb
repeat bits
outa[dpin] := (value ->= 1) & 1 ' output data bit
delay.pause10us(1) ' let it settle
!outa[cpin] ' clock the bit
delay.pause10us(1)
!outa[cpin]
MsbFirst:
value <<= (32 - bits) ' pre-align msb
repeat bits
outa[dpin] := (value <-= 1) & 1 ' output data bit
delay.pause10us(1) ' let it settle
!outa[cpin] ' clock the bit
delay.pause10us(1)
!outa[cpin]
PUB shiftoutstr(dpin, cpin, mode, str_addr, count)
repeat count
shiftout(dpin, cpin, mode, byte[str_addr++], 8)
PUB shiftin(dpin, cpin, mode, bits) | value
dira[dpin]~ ' make dpin input
dira[cpin]~~ ' make cpin output
value~ ' clear output
case mode
MsbPre:
repeat bits
value := (value << 1) | ina[dpin]
!outa[cpin] '
delay.pause10us(1)
!outa[cpin]
delay.pause10us(1)
LsbPre:
repeat bits
value := (value >> 1) | (ina[dpin] << 31)
!outa[cpin] '
delay.pause10us(1)
!outa[cpin]
delay.pause10us(1)
value >>= (32 - bits)
MsbPost:
repeat bits
!outa[cpin] '
delay.pause10us(1)
value := (value << 1) | ina[dpin]
!outa[cpin] '
delay.pause10us(1)
LsbPost:
repeat bits
!outa[cpin] '
delay.pause10us(1)
value := (value >> 1) | (ina[dpin] << 31)
!outa[cpin]
delay.pause10us(1)
value >>= (32 - bits)
return value
<code>
'' *****************************
'' * Timing *
'' * (C) 2006 Parallax, Inc. *
'' *****************************
''
'' This object provides time delay and time synchronization functions.
CON
_10us = 1_000_000 / 10 ' Divisor for 10 us
_1ms = 1_000_000 / 1_000 ' Divisor for 1 ms
_1s = 1_000_000 / 1_000_000 ' Divisor for 1 s
VAR
long delay
long syncpoint
long clkcycles
PUB pause10us(period)
'' Pause execution for period (in units of 10 us)
clkcycles := ((clkfreq / _10us * period) - 4296) #> 381 ' Calculate 10 us time unit
waitcnt(clkcycles + cnt) ' Wait for designated time
PUB pause1ms(period)
'' Pause execution for period (in units of 1 ms).
clkcycles := ((clkfreq / _1ms * period) - 4296) #> 381 ' Calculate 1 ms time unit
waitcnt(clkcycles + cnt) ' Wait for designated time
PUB pause1s(period)
'' Pause execution for period (in units of 1 sec).
clkcycles := ((clkfreq / _1s * period) - 4296) #> 381 ' Calculate 1 s time unit
waitcnt(clkcycles + cnt) ' Wait for designated time
PUB marksync10us(period)
delay := (clkfreq / _10us * period) #> 381 ' Calculate 10 us time unit
syncpoint := cnt
PUB waitsync
waitcnt(syncpoint += delay)
</code>
Comments
You should re-post your code enclosed with "[ CODE ] ... [ /CODE ]" (WITHOUT THE SPACES).
Paul
'' DS1620 Demo
'' -- Jon Williams, Parallax
'' -- 28 MAR 2006
''
'' Uses 2x16 Serial LCD (Parallax) to display temperature
CON
_clkmode = xtal1 + pll16x ' use crystal x 16
_xinfreq = 5_000_000
OBJ
lcd : "serial_lcd"
temp : "ds1620"
delay : "timing"
num : "simple_numbers"
PUB main | tc, tf
if lcd.start(3, 19200, 2)
lcd.putc(lcd#LcdOn1) ' no cursor
lcd.custom(0, @DegSym) ' create degrees symbol
lcd.cls ' setup screen
lcd.str(string("TEMP"))
lcd.backlight(1) ' backlight on
temp.start(0, 1, 2) ' initialize DS1620
repeat
delay.pause1ms(1000) ' wait one second
lcd.putc(lcd#LcdLine0 + 9)
tc := temp.gettempc
lcd.str(num.decf(tc / 10, 3))
lcd.putc(".")
lcd.str(num.dec(tc // 10))
lcd.putc(0)
lcd.putc("C")
lcd.putc(lcd#LcdLine1 + 9)
tf := temp.gettempf
lcd.str(num.decf(tf / 10, 3))
lcd.putc(".")
lcd.str(num.dec(tf // 10))
lcd.putc(0)
lcd.putc("F")
DAT
DegSym byte $0E, $0A, $0E, $00, $00, $00, $00, $00
Would you also provide a schematic of how you have things wired up?
See the post I made above yours for a diagram of how the chip is wired to the prop. Let me know if you need any more details. Thanks!
One more quick question....for future reference, what value should I use for the current limiting resistor before the prop pins?
Thanks for the help and the advice!!
The good thing you got out of it, is you learn something and someone else learned from your mistake.
Maybe the Prop wasn't pulling the pins to a high enough voltage in relation to the input voltage on the DS1620. That's just a guess. I'm a software guy.