Shop OBEX P1 Docs P2 Docs Learn Events
Problem with propeller code for DS1620 temp sensor — Parallax Forums

Problem with propeller code for DS1620 temp sensor

fireman508fireman508 Posts: 19
edited 2011-01-12 11:05 in Propeller 1
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>

Comments

  • Paul Sr.Paul Sr. Posts: 435
    edited 2011-01-10 05:47
    Hello,

    You should re-post your code enclosed with "[ CODE ] ... [ /CODE ]" (WITHOUT THE SPACES).

    Paul
  • fireman508fireman508 Posts: 19
    edited 2011-01-11 11:14
    thanks for looking!
    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
    
    '' *****************************
    '' *  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    &#61569;&#61571;&#61579;&#61579;&#61579;&#61568;&#61579;&#61579;&#61579;&#61568;&#61579;&#61579;&#61579;&#61568;&#61579;&#61579;&#61579;&#61568;&#61579;&#61579;&#61579;&#61568;&#61579;&#61579;&#61579;&#61568;&#61579;&#61579;&#61579;&#61568;&#61579;&#61579;&#61579;&#61577;&#61569;&#61569;
    '' clock0  &#61569;&#61569;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61569;
    '' clock1  &#61574;&#61574;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61573;&#61569;&#61570;&#61574;&#61574;
    
    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  
    
    '' *****************************
    '' *  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)
    
  • fireman508fireman508 Posts: 19
    edited 2011-01-11 15:32
    Sorry forgot to add that part...
    PUB TEMP | TC
      
      IF LCD.START(LCDPIN, BAUD, LINES)
        waitcnt(clkfreq / 100 + cnt)
        LCD.CURSOR(3)
        LCD.CLS                                             ' setup screen
        LCD.BACKLIGHT(1)                                    ' backlight on
        TEMP1.START(13, 14, 15)
       
        REPEAT
          DELAY.PAUSE1MS(1000)                              ' wait one second
          LCD.CLS
          LCD.STR(STRING("TEMP:"))
          LCD.PUTC(9)
          TC := TEMP1.GETTEMPC 
          LCD.DEC(TC)
    
  • MD2010MD2010 Posts: 11
    edited 2011-01-11 17:07
    Try this code.

    '' 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
  • fireman508fireman508 Posts: 19
    edited 2011-01-11 17:12
    Thank you for replying! This is what I originally based my code on and unfortunately it does the 0 degree thing as well.....but thanks for trying! If you have any other ideas I'm all ears :)
  • SSteveSSteve Posts: 808
    edited 2011-01-11 18:03
    I've looked through your code and compared it to some working DS1620 code that I have. I don't see any obvious problems. Can you attach an archive of your entire project? Maybe someone can try it out.
  • fireman508fireman508 Posts: 19
    edited 2011-01-11 19:14
    Here is my entire project....if anyone wants to give it a try and let me know if it works for you I would greatly appreciate it. Thanks!!!
  • SSteveSSteve Posts: 808
    edited 2011-01-11 22:01
    I don't have time to look at it tonight but I'll try to find some time tomorrow evening.
  • Paul Sr.Paul Sr. Posts: 435
    edited 2011-01-12 05:06
    fireman508 wrote: »
    Here is my entire project....if anyone wants to give it a try and let me know if it works for you I would greatly appreciate it. Thanks!!!

    Would you also provide a schematic of how you have things wired up?
  • fireman508fireman508 Posts: 19
    edited 2011-01-12 05:46
    It's pretty straightforward :-)

    temp diagram.JPG
    484 x 698 - 29K
  • fireman508fireman508 Posts: 19
    edited 2011-01-12 06:42
    Hi Bruce,

    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!
  • fireman508fireman508 Posts: 19
    edited 2011-01-12 06:58
    Unbelievable, that fixed it! Thanks Bruce!!! But, the data sheet for the DS1620 states that the supply voltage can range from 2.7V to 5.5V, so why wouldn't it work with a 5V supply and does with a 3.3V supply?
  • fireman508fireman508 Posts: 19
    edited 2011-01-12 07:14
    No, the only thing I changed was the voltage to VDD...
  • fireman508fireman508 Posts: 19
    edited 2011-01-12 07:18
    Lol! Well....as long as it works :-)

    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!!
  • bsnutbsnut Posts: 521
    edited 2011-01-12 07:23
    idbruce wrote: »
    Fireman508

    You probably destroyed one of your Prop IO pins by not limiting the current to it when supplying 5V to the chip.

    Bruce
    I agree with Bruce on this 100%. I always use resistors to limit current on the pins.

    The good thing you got out of it, is you learn something and someone else learned from your mistake.
  • SSteveSSteve Posts: 808
    edited 2011-01-12 07:39
    fireman508 wrote: »
    Unbelievable, that fixed it! Thanks Bruce!!! But, the data sheet for the DS1620 states that the supply voltage can range from 2.7V to 5.5V, so why wouldn't it work with a 5V supply and does with a 3.3V supply?

    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.
  • JonnyMacJonnyMac Posts: 9,235
    edited 2011-01-12 07:47
    If you're taking a 5v signal into the Propeller, the minimum recommended current limiter is 2.2K.
  • kf4ixmkf4ixm Posts: 529
    edited 2011-01-12 11:05
    I was working with something similar the other week with the 1620, using a breadboard, i also was having the intermittent 0deg at times, i later found out that even though i had the wires plugged firmly into the breadboard, there was still some sort of short in the data line that was causing the 0deg. once i changed the chip to a different set of holes, the problem went away. even though the wires had plenty of resistance as far as holding the wire firmly, it still gave me problems. not to say that was your problem, but its something to be aware of in the future.
Sign In or Register to comment.