Shop OBEX P1 Docs P2 Docs Learn Events
DS18s20 temp sensor — Parallax Forums

DS18s20 temp sensor

uosamor007uosamor007 Posts: 21
edited 2012-05-17 12:52 in Accessories
i am trying to get a temperature read out from this temperature sensor to the PST. i am new to spin programming and not sure how to proceed with this. any suggestions would be helpful
thank you.

sample code

CON
_clkmode = xtal1 + pll16x ' Change to xtal1 + pll8x for Propeller Backpack.
_xinfreq = 5_000_000 ' Change to 10_000_000 for Propeller Backpack.
OW_DATA = 0 ' 1-wire data pin
SKIP_ROM = $CC ' 1-wire commands
MATCH_ROM = $55
READ_SCRATCHPAD = $BE
CONVERT_T = $44
MAX_DEVICES = 10 ' maximum number of 1-wire devices
DEG = 176 ' degree symbol
CR = 13

VAR
byte myTemp[9] ' 9 Byte array to hold the DS1820 registers
long addressList[MAX_DEVICES*2] ' 64-bit address buffer

OBJ
pst : "parallax serial terminal"
ow : "OneWire" ' Define Dallas 1-Wire routines
PUB Start
ow.start(OW_DATA) ' start 1-wire object on pin define as OW_DATA
DS1wire
getTemperature
tempDS1820


PUB getTemperature : temp | idx2
'term.Str(String("getTemperature", CR))
ow.reset ' reset 1-Wire buss
ow.writeByte(MATCH_ROM) ' send match ROM command
ow.writeAddress(@addressList) ' Works now|***** can't get this to work
ow.writeByte(CONVERT_T) ' send command to initiate a single temperature conversion
repeat ' wait for conversion
waitcnt(cnt + clkfreq / 1000 * 25)
if ow.readBits(1)
quit

ow.reset ' reset 1-Wire buss
ow.writeByte(MATCH_ROM) ' send match ROM command
ow.writeAddress(@addressList) ' Works now|***** can't get this to work
'sendSerialNumber ' send serial number of the DS1820
ow.writeByte(READ_SCRATCHPAD) ' send command to read the contents of the scratchpad
idx2 := 0 ' zero loop counter variable
repeat 9 ' read 9 bytes from 1-Wire buss
mytemp[idx2++] := ow.readByte ' store byte in array

PUB tempDS1820 |tempC , fract
tempC := getTemperature ' get temperature in celsius
repeat
pst.str(alt.formatn(tempC, alt#Centigrades | alt#CECR, 8))
if (pst.rxcount) Respond to any key by clearing screen.
pst.rxflush
pst.char(pst#CS

to be honest i'm not even sure if any of this is right but am i in the right direction or not?

thank you

Comments

  • uosamor007uosamor007 Posts: 21
    edited 2012-02-16 08:20
    any sample code will be appreciated

    thank you
  • lfreezelfreeze Posts: 174
    edited 2012-02-23 05:47
    Attached is program based on Micah Dowtys one wire object. I use it for testing single sensors. In that mode it has worked without a problem.

    Please check other threads on the forums as there have been problems when using this object with multiple sensors at high temperatures.

    Hope this helps....

    Larry
  • uosamor007uosamor007 Posts: 21
    edited 2012-02-23 09:44
    ok thank you so i just have one question i want the output out the Paralax serial terminal just to make sure i am getting the right readings....so which variable is the temperature..from reading the code would it be tempC or tempF or both?

    thanks again for the help
  • Paul Sr.Paul Sr. Posts: 435
    edited 2012-02-23 11:57
    tempC = Celsius Temperature
    tempF = Fahrenheit Temperature
  • uosamor007uosamor007 Posts: 21
    edited 2012-02-23 15:50
    actually please disregard my previous post...i am using the code by lFreeze with no modifications and i am having an issue..nothing comes up on the pst..however i notice when i comment out this particular line

    tempC := getTemperature

    in the main pub i get a output...what could be the issue???

    thank you once again for your help
  • ElectricAyeElectricAye Posts: 4,561
    edited 2012-02-23 21:17
    lfreeze wrote: »
    ...
    Please check other threads on the forums as there have been problems when using this object with multiple sensors at high temperatures....

    Yes, you might want to have a look at the following:

    http://forums.parallax.com/showthread.php?136782-How-to-use-the-One-Wire-(1-Wire)-object-in-the-Obex&
  • lfreezelfreeze Posts: 174
    edited 2012-02-24 08:10
    Please post the exact code you are using and I will try and help....
  • ElectricAyeElectricAye Posts: 4,561
    edited 2012-02-24 08:18
    lfreeze wrote: »
    Please post the exact code you are using and I will try and help....

    And when you do post the code, use the code tags as described below:


    attachment.php?attachmentid=78421&d=1297987572

    That will help keep the alignment in your code.
  • uosamor007uosamor007 Posts: 21
    edited 2012-02-24 23:23
    ok here is what i have so far. i am using the DS18s20 temp sensor. i noticed the code lfreeze posted was for the DS18b20. i changed one line of code in the onewire program to reflect the DS18s20 family.
      CONVERT_T         = $44
      COPY_SCRATCHPAD   = $48
      RECALL_EE         = $B8
      READ_POWER_SUPPLY = $B4
      ' 1-wire family codes
      FAMILY_DS18S20    = $10
    
    

    and i am using the same code that he posted
    }}
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      
      SKIP_ROM          = $CC    '1 wire commands
      READ_SCRATCHPAD   = $BE    '1 wire commands
      CONVERT_T         = $44    '1 wire commands
      DEG               = $B0    'temp degree symbol
      
    OBJ
      ser           : "fullduplexserial"
      ow            : "OneWire"
      fp            : "FloatString"
      f             : "FloatMath"                          
       
    PUB main | TEMPC, tempd, tempF
      ser.start(31, 30, 0, 9600) 
    '--------------------------------------------------------------------------------------------------------------
       repeat 
             
            'SENSOR ON PIN 19   
                 
          ow.start(19)   ' start 1-wire object data pin on propeller is 19 
          tempC := getTemperature                     ' starts "pub gettemperature" get temperature in celsius
          tempF := f.FAdd(f.FMul(tempC, 1.8), 32.0)           ' fahrenheit = (celsius * 1.8) + 32 
         ' waitcnt (1_000_000 + cnt)    
          ser.str(STRING("TEMPERATURE = ")) 
           if tempf < 0.0  'displays "-" minus sign for temperatures less than zero
             tempf:=f.FNeg(tempf)
        
           fp.SetPrecision(6)      'DETERMINES NUMBER OF DECIMAL POINTS
           ser.str(fp.FloatToString(tempf))
          ' ser.str(string("°F "))    
          SER.tx(13)
    '--------------------------------------------------------------------------------
           
    PUB getTemperature : temp
      ow.reset   
      ow.writeByte(SKIP_ROM)
      ow.writeByte(CONVERT_T)
      repeat                      
        waitcnt (1_000_000 + cnt) 
        if ow.readBits(1)
           quit
      ow.reset                                              ' read DS1822 scratchpad
      ow.writeByte(SKIP_ROM)
      ow.writeByte(READ_SCRATCHPAD)
      temp := ow.readByte + ow.readByte << 8                ' read temperature
      temp:=~~temp
      
      temp := F.FDiv(F.FFloat(temp), 16.0)                  ' convert to floating point
     
    

    that should be enough to have my sensor working correct?
  • lfreezelfreeze Posts: 174
    edited 2012-02-25 07:55
    I downloaded the code from your last post and ran it successfully on a DS18B20. I always thought the one wire driver would
    work correctly on a DS18S20 or a DS18B20. I am probably wrong, hopefully someone else can comment on that aspect.

    The only other problem may be a missing pullup resistor (usually 4.7K), have you included the resistor
    In your circuit?
  • FranklinFranklin Posts: 4,747
    edited 2012-02-25 11:59
  • uosamor007uosamor007 Posts: 21
    edited 2012-02-25 13:36
    wow the pull up resistor worked like a charm and i am actually getting a reading from my sensor. the only issue i have now is that it is reading 38.6 F in a 70+ F room. i know the conversion is off as the Ds18B20 and the DS18S20 are two different sensors. so what i am asking now is please explain this part of the code as to how it reads the temperature
    PUB getTemperature : temp
      ow.reset   
      ow.writeByte(SKIP_ROM)
      ow.writeByte(CONVERT_T)
      repeat                      
        waitcnt (1_000_000 + cnt) 
        if ow.readBits(1)
           quit
      ow.reset                                              ' read DS1822 scratchpad
      ow.writeByte(SKIP_ROM)
      ow.writeByte(READ_SCRATCHPAD)
      temp := ow.readByte + ow.readByte << 8                ' read temperature
      temp:=~~temp
      
      temp := F.FDiv(F.FFloat(temp), 16.0)                  ' convert to floating point
    
    

    what could i change if anything to get a more accurate reading. i know the conversion factors are different but i am not sure what to change and i am scared to mess up the code
  • uosamor007uosamor007 Posts: 21
    edited 2012-02-25 15:34
    ok how would i use the code for multiple sensors. i know lfreeze stated earlier that it would have issues at high temperatures. the application i will be using it for however will be at low temperatures. i read up on the 1-wire help but i am not sure how to connect multiple sensors
  • ElectricAyeElectricAye Posts: 4,561
    edited 2012-02-25 21:39
    uosamor007 wrote: »
    ok how would i use the code for multiple sensors.... i read up on the 1-wire help but i am not sure how to connect multiple sensors

    To read multiple sensors, you will need to address each sensor by its ROM code, which is unique for each sensor chip. You might want to look at JonnyMac's code posted in the following link:


    http://forums.parallax.com/showthread.php?136782-How-to-use-the-One-Wire-(1-Wire)-object-in-the-Obex&

    From that thread:
    "...To get started, you will want to wire up only one DS18B20 at a time and run DS18B20jmReadROM1a.spin to get each serial number, then you will have to manually type the serial numbers into the software that runs more than one of the sensors at the same time, using DS18B20jm1d.spin...."


    JonnyMac's code is different and, in my opinion, much more stable than Micah's code. I think there are methods in JonnyMac's code that allow you to read the ROM off an individual chip placed on the 1-wire line. After you have read the ROM code off of each sensor chip by placing each sensor individually on the 1-wire line one by one, you can then manually write all of those ROM addresses into the DAT section of your code. (You place them into the DAT section because they are too big to fit into a LONG, etc.)

    Later, you can then make reference to each sensor when you want to ask that particular sensor to read a temperature even when multiple sensors are on the 1-wire line. So you have multiple sections of code that call up the individual ROM addresses stored in the DAT section, and each of these gives a separate reading.

    I hope that makes some sense. I have an example of how this works on my other computer, but probably can't get to it until late Sunday.
  • uosamor007uosamor007 Posts: 21
    edited 2012-02-27 16:33
    ok thank you for the link and the code electricaye i will be testing them out tomorrow on my project. i looked over the code and it seems straight forward the only thing is the output is on a VGA while i want the output on the parallax serial terminal but i will see how it goes. a working code on the pst will be much appreciated
  • AcquaLifeAcquaLife Posts: 19
    edited 2012-05-15 15:51
    I have a quick question. In the Con block you say
    SKIP_ROM = $CC ' 1-wire commands
    MATCH_ROM = $55
    READ_SCRATCHPAD = $BE
    CONVERT_T = $44
    In the data sheet it says theses commands are CCh, 55h, BEh,44h respectively. So if there is an h at the end to you just put a $ at the front? Where did that come from. I tried to look in the propeller manual for the $ but didn't see it.
  • ElectricAyeElectricAye Posts: 4,561
    edited 2012-05-15 16:18
    AcquaLife wrote: »
    I have a quick question. In the Con block you say
    SKIP_ROM = $CC ' 1-wire commands
    MATCH_ROM = $55
    READ_SCRATCHPAD = $BE
    CONVERT_T = $44
    In the data sheet it says theses commands are CCh, 55h, BEh,44h respectively. So if there is an h at the end to you just put a $ at the front? Where did that come from. I tried to look in the propeller manual for the $ but didn't see it.

    Look in the Prop manual v1.2 on page 207. It mentions the $ sign as a hexadecimal indicator, which is what the h indicates in some documents you find.
  • AcquaLifeAcquaLife Posts: 19
    edited 2012-05-16 20:02
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
      
      SKIP_ROM          = $CC    '1 wire commands
      READ_SCRATCHPAD   = $BE    '1 wire commands
      CONVERT_T         = $44    '1 wire commands
      DEG               = $B0    'temp degree symbol
      
    OBJ
      ser           : "fullduplexserial"
      ow            : "SpinOneWire"
      fp            : "FloatString"
      f             : "FloatMath"
      pst           : "Parallax Serial Terminal"                          
       
    PUB main | TEMPC, tempd, tempF
      pst.start(115200) 
    '--------------------------------------------------------------------------------------------------------------
       repeat 
             
            'SENSOR ON PIN 19   
                 
          ow.start(0)   ' start 1-wire object data pin on propeller is 19 
          tempC := getTemperature                     ' starts "pub gettemperature" get temperature in celsius
          tempF := f.FAdd(f.FMul(tempC, 1.8), 32.0)           ' fahrenheit = (celsius * 1.8) + 32 
         ' waitcnt (1_000_000 + cnt)    
          pst.str(STRING("TEMPERATURE = ")) 
    
    
           if tempf < 0.0  'displays "-" minus sign for temperatures less than zero
             tempf:=f.FNeg(tempf)
        
           fp.SetPrecision(6)      'DETERMINES NUMBER OF DECIMAL POINTS
           pst.str(fp.FloatToString(tempf))
           pst.str(string(" ",pst#NL))
          ' pst.str(string("°F "))    
          
    '--------------------------------------------------------------------------------
           
    
    
    PUB getTemperature : temp
      ow.reset   
      ow.writeByte(SKIP_ROM)
      ow.writeByte(CONVERT_T)
    
    
      repeat                      
        waitcnt (1_000_000 + cnt) 
        if ow.readBits(1)
           quit
    
    
      ow.reset                                              ' read DS1822 scratchpad
      ow.writeByte(SKIP_ROM)
      ow.writeByte(READ_SCRATCHPAD)
      temp := ow.readByte + ow.readByte << 8                ' read temperature
    
    
      temp:=~~temp
      
      temp := F.FDiv(F.FFloat(temp), 2)                  ' convert to floating point
     
    '-------------------------------------------------------------------------------------------------------------------
    
    That is the code i am using. Basically the same as the one provide by lfreeze. Ijust changed the term part to pst. The problem i have is my reading is a constant number and it is way wrong. I get 6.126e+98 as my temperature. It also doesn't change. I have the DS18S20+ PAR set up as followed. NC pin not connected. GND--> ground. DQ-->Pin 0 and 4.7k resist to VSS. Any help would be appreciated
  • ElectricAyeElectricAye Posts: 4,561
    edited 2012-05-16 22:05
    One thing leaps out at me:

    if tempf < 0.0

    The < operator (and its friends >, <>, etc.) can only work with integers.
  • AcquaLifeAcquaLife Posts: 19
    edited 2012-05-17 12:52
    That didn't fix the problem :( Do you have any other suggestions. I've been trying to get this to work for a few days now. I've read the Datasheet and looked over the code posted and other codes i've found.
Sign In or Register to comment.