DS1820 - Help I'm rusty !


Closed Thread
Results 1 to 21 of 21

Hybrid View

  1. #1
    malc-c's Avatar
    malc-c Guest

    Default DS1820 - Help I'm rusty !

    OK, just received some extra goodies for my easyPIC5 board, one of which is a DS1820 temp sensor. I've used Bruce's example as a starting point and edited it to work with the 2 x 16 LCD on the EasyPIC5 board, but I don't get anything displayed on the screen.

    Its been a while since I did any programming, so I'm a tad rusty, Can someone give me some direction. Here are the main points:

    16F887 running with 20Mhz
    DS1820 output set to RA5
    LCD on portB as per the user manual

    Code:
    TRISA=%11111111                                                 ' set PORTA as all input 
    TRISB=%00000000                                                 ' set PORTB as all output            
    DEFINE OSC 20             
    DEFINE LCD_DREG PORTB                                           ' LCD data port 
    DEFINE LCD_DBIT 0                                               ' LCD data starting bit 0 or 4 
    DEFINE LCD_RSREG PORTB                                          ' LCD register select port 
    DEFINE LCD_RSBIT 4                                              ' LCD register select bit 
    DEFINE LCD_EREG PORTB                                           ' LCD enable port 
    DEFINE LCD_EBIT 5                                               ' LCD enable bit 
    DEFINE LCD_BITS 4                                               ' LCD bus size 4 or 8 
    DEFINE LCD_LINES 2                                              ' Number lines on LCD 
    DEFINE LCD_COMMANDUS 2000                                       ' Command delay time in us 
    DEFINE LCD_DATAUS 50                                            ' Data delay time in us
    
    
    Comm_Pin    VAR	PortA.5                                         ' One-wire Data-Pin "DQ" on PortC.0
    Busy        VAR BIT                                             ' Busy Status-Bit
    TempC       VAR WORD                                            ' Temp in deg C
    TempF       VAR WORD                                            ' Temp in deg F
    Float       VAR WORD                                            ' Holds remainder for + temp C display
    Cold_Bit    VAR  R_Temp.Bit11                                   ' Sign-Bit for +/- Temp. 1 = Below 0 deg C
    Real_Cold   CON 1                                               ' Define Real_Cold = 1
    Deg         CON 223                                             ' Data to display Deg ° symbol
    Sign        VAR BYTE                                            ' +/- sign for temp display
    Dummy       VAR BYTE                                            ' Dummy for Div32
    
    Start_Convert:
        OWOUT   Comm_Pin, 1, [$CC, $44]                             ' Skip ROM search & do temp conversion
        
    Wait_Up:
        OWIN    Comm_Pin, 4, [Busy]                                 ' Read busy-bit
        IF      Busy = 0 THEN Wait_Up                               ' Still busy..?, Wait_Up..!
        OWOUT   Comm_Pin, 1, [$CC, $BE]                             ' Skip ROM search & read scratchpad memory
        OWIN    Comm_Pin, 2, [R_Temp.Lowbyte, R_Temp.Highbyte]      ' Read two bytes / end comms
        GOSUB   Convert_Temp
        GOTO    Start_Convert
        
    Convert_Temp:                                                   ' +32.0 to +257 F 
        IF      Cold_Bit = Real_Cold THEN Yikes                     ' If Cold_Bit = 1, it's below "0" deg C
        Sign  = "+"
        Dummy = 625 * R_Temp                                        ' Multiply to load internal registers with 32-bit value
        TempC = DIV32 10                                            ' Use Div32 value to calculate precise deg C
        Dummy = 1125 * R_Temp
        TempF = DIV32 100
        IF TempF >6795 THEN                                         ' Over 99.5 deg F..?
           TempF = TempF + 3200
           lcdout $FE, 1," TempF = ",Sign,DEC TempF DIG 4,_
           DEC TempF DIG 3,DEC TempF DIG 2,".",DEC2 TempF,Deg,"F "
        ELSE
           TempF = TempF + 3200
           LCDOUT $FE,$C0, " TempF = ",Sign,DEC TempF DIG 3,_
           DEC TempF DIG 2,".",DEC2 TempF,Deg,"F "
        ENDIF
        TempC  = (R_Temp & $0FF0) >> 4                              ' Mask middle 8-bits, shift into lower byte
        Float = ((R_Temp.Lowbyte & $0F) * 625)                      ' Lower 4-bits of result * 625
        RETURN
    
    Yikes:                                                          ' Display full range -C to -F conversion
        Sign   = "-"                                                ' Display - symbol for negative temp
        Dummy  = 625 * ~R_Temp+1                                    ' Multiply to load internal registers with 32-bit value
        TempC  = DIV32 10                                           ' Use Div32 value to calculate precise deg C
        TempF  = ~R_Temp / 16                                       ' Begin conversion from -C to deg +/-F
        IF TempF >=18 THEN                                          ' Check for -degrees F "-18 C = -0.4 F"
           TempF   = ((((TempF + 50) * 9) /5) -122)                 ' -C to -F below -17 deg C
           lcdout $FE, 1," TempF = ",Sign, DEC TempF,Deg,"F     "
           LCDOUT $FE,$C0, " TempC = ",Sign,DEC TempC DIG 4,_
           DEC TempC DIG 3,".",DEC3 TempC,Deg,"C "
    
        ELSE                                                        ' Else result = +deg F
           TempF   = ((((-TempF + 50) * 9) /5) -58)                 ' -C to +F below 32.0 deg F to -17 deg C
         lcdout $FE, 1, " TempF = ","+",DEC TempF,Deg,"F     "
          LCDOUT $FE,$C0 , " TempC = ",Sign,DEC TempC DIG 4,_
           DEC TempC DIG 3,".",DEC3 TempC,Deg,"C "
    
        ENDIF
        RETURN
        
        END
    There are a few compiling errors,
    Cold_Bit VAR R_Temp.Bit11 gives "a bad data type"
    OWIN Comm_Pin, 2, [R_Temp.Lowbyte, R_Temp.Highbyte] gives "expected [" and "expected ]" even though the exist
    and half a dozen "bad expressions"

    The example was for a serial LCD, where as mine is a traditional parallel one in 4 bit mode, so I've tried to convert the example, but its not displaying anything, even though it was cut and pasted from a bit of code I wrote a year ago which worked (just changed portC to port B for the use on the development board)

    I'm sure its missing something really obvious. Should I still configure the chip, or use the settings in the Flash2 programmer software.

    TIA

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Cold_Bit VAR R_Temp.Bit11 gives "a bad data type"
    Not seeing where R_Temp is declared!

    OWIN Comm_Pin, 2, [R_Temp.Lowbyte, R_Temp.Highbyte] gives "expected [" and "expected ]" even though the exist
    and half a dozen "bad expressions"
    Are you using PBP 2.50A? There was a bug in the OWIN/OWOUT that was addressed here on the forums awhile back. Might apply to you if using PBP2.50A, not sure if the A patch covered the bug or not.
    http://www.picbasic.co.uk/forum/show...ighlight=2.50a
    Last edited by skimask; - 10th June 2008 at 21:17.

  3. #3
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Thanks for the comments, I said i was rusty

    Using a some what older version 2.47

  4. #4
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by malc-c View Post
    Using a some what older version 2.47
    Then it's back to declaring R_Temp

  5. #5
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default Now we're getting somewhere

    Ok, with a bit of head scratching I've managed to get the LCD to display some text, and then added an edited section of Bruce's code to get the DEC value of TEMPf displayed on the screen

    Code:
    ANSEL  = 0                             
    ANSELH = 0                                                
    DEFINE OSC 20            
    DEFINE LCD_DREG PORTB
    DEFINE LCD_DBIT 0
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 4
    DEFINE LCD_EREG PORTB
    DEFINE LCD_EBIT 5
    DEFINE LCD_BITS 4
    DEFINE LCD_LINES 2
    DEFINE LCD_COMMANDUS 1000
    DEFINE LCD_DATAUS 100
    
    Comm_Pin    VAR	PortA.5     ' One-wire Data-Pin "DQ" on PortA.5
    Busy        VAR BIT         ' Busy Status-Bit
    R_Temp      VAR	WORD        ' RAW Temperature readings
    TempC       VAR WORD        ' Temp in deg C
    TempF       VAR WORD        ' Temp in deg F
    Float       VAR WORD        ' Holds remainder for + temp C display
    Cold_Bit    VAR R_Temp.Bit11' Sign-Bit for +/- Temp. 1 = Below 0 deg C
    Real_Cold   CON 1           ' Define Real_Cold = 1
    Sign        VAR BYTE        ' +/- sign for temp display
    Dummy       VAR BYTE        ' Dummy for Div32
    
    Start_Convert:
        OWOUT   Comm_Pin, 1, [$CC, $44]                             ' Skip ROM search & do temp conversion
        
    Wait_Up:
        OWIN    Comm_Pin, 4, [Busy]                                 ' Read busy-bit
        IF      Busy = 0 THEN Wait_Up                               ' Still busy..?, Wait_Up..!
        OWOUT   Comm_Pin, 1, [$CC, $BE]                             ' Skip ROM search & read scratchpad memory
        OWIN    Comm_Pin, 2, [R_Temp.Lowbyte, R_Temp.Highbyte]      ' Read two bytes / end comms
        GOSUB   Convert_Temp
        GOTO    Start_Convert
        
    Convert_Temp:                                                   ' +32.0 to +257 F 
    
        Sign  = "+"
        Dummy = 625 * R_Temp                                        ' Multiply to load internal registers with 32-bit value
        TempC = DIV32 10                                            ' Use Div32 value to calculate precise deg C
        Dummy = 1125 * R_Temp
        TempF = DIV32 100
        IF TempF >6795 THEN                                         ' Over 99.5 deg F..?
           TempF = TempF + 3200
    lcdout $FE,1," Temp F = ",Sign,DEC TempF
        ELSE
           TempF = TempF + 3200
           LCDOUT $FE,1, " Temp F = ",Sign,DEC TempF 
        ENDIF
        TempC  = (R_Temp & $0FF0) >> 4                              ' Mask middle 8-bits, shift into lower byte
        Float = ((R_Temp.Lowbyte & $0F) * 625)                      ' Lower 4-bits of result * 625
        RETURN
    The code compiles and loads OK, and I get the value (3199) shown on the screen, but seem to have a few niggles I can't workout what settings I need to change.

    1) - if viewed at an angle, the display seems to be scanning (ie its similar to the effect when filming a TV and you get a black bar slowley moving over the picture)

    2) - holding the DS1820 between fingers I would expect the value to change, but it doesn't

    Any guidance would help

  6. #6
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Cutting and pasting the following from Bruce's example gives a bad expression error at the line beginning DEC TempF DIG 3

    Code:
    lcdout $FE,1," TempF = ",Sign,DEC TempF DIG 4,_
    DEC TempF DIG 3,DEC TempF DIG 2,".",DEC2 TempF,Deg,"F "
    EDIT:
    Resolved (sort of !)
    Code:
    lcdout $FE,1," TempF = ",Sign,DEC TempF DIG 4,DEC TempF DIG 3,DEC TempF DIG 2,".",DEC2 TempF,"F "
    Gives TempF = +031.99 on the LCD. Seems it was the "Deg" statement that was causing the issue. More work to do to get it reading the correct temperature (ie drop the 0) and if I recal 32F is 0 C and its not that cold in here !!!
    Last edited by malc-c; - 11th June 2008 at 10:51. Reason: more progress made

  7. #7
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,651


    Did you find this post helpful? Yes | No

    Talking

    Hi, Malc

    ... Just try this one !!!

    Hits the 10000 characters ... so, no code window !!!


    It's been written for EP5 and DS18B20 ( I suppose you have a 18B20 as the 1820 is off production - if real 1820, ... nothing to change !!! )

    you just have to add the °C to °F feature ...

    I won't do everything for you ... be serious !!! ( LoL )

    Alain
    Attached Files Attached Files
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  8. #8
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default Board and sensor is OK

    Ok, I found the example on the EasyPIC5 CD (I know it should of been the first place to look, but as it was called one-wire and not temp sensor you can understand why I missed it - I said I was rusty !)

    This works and gives a real temp of 25 degree C which rises when I touch the sensor. I apologise now as the following is not PBP - but hopefully someone can tell me why I was having so much trouble with PBP

    Code:
    ' *
    ' * Project name
    '     Onewire_Test (Interfacing the DS18x20 temperature sensor - all versions)
    ' * Copyright
    '     (c) MikroElektronika, 2005-2008
    ' * Description
    '     After reset, PIC reads temperature from the sensor and prints it on the Lcd.
    '     The display format of the temperature is 'xxx.xxxx°C'. To obtain correct
    '     results, the 18x20's temperature resolution has to be adjusted (constant
    '     TEMP_RESOLUTION)
    ' * Test configuration
    '     MCU             PIC16F887
    '     Dev.Board       EasyPIC5
    '     Oscillator      HS, 08.0000 MHz
    '     Ext. Modules    DS18x20 connected to RE2 pin, LCD_2x16
    '     SW              mikroC v8.0
    ' * NOTES
    '     - Pull up and turning off diode on pin used for one wire bus may be required.
    ' *
    
    program Onewire_Test
    
    '  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor
    '  18S20 9  (default setting can be 9,10,11,or 12)
    '  18B20 12
    const TEMP_RESOLUTION as byte = 9
    dim  text as string[8]
         temp as word
    
    sub procedure Display_Temperature(dim temp2write as Word)
    const RES_SHIFT as byte = TEMP_RESOLUTION - 8
    dim temp_whole as byte
        temp_fraction as Word
    
      text = "000.0000"
    
      ' check if temperature is negative
      if (temp2write and $8000) = 0x8000 then
    
         text[0] = "-"
         temp2write = not temp2write + 1
      end if
    
      ' extract temp_whole     0
      temp_whole = temp2write >> RES_SHIFT
    
      ' convert temp_whole to characters
      if (temp_whole/100) then
         text[0] = temp_whole/100  + 48
      end if
      text[1] = (temp_whole/10) mod 10 + 48             ' extract tens digit
      text[2] =  temp_whole mod 10     + 48             ' extract ones digit
    
      ' extract temp_fraction and convert it to unsigned int
      temp_fraction  = temp2write << (4-RES_SHIFT)
      temp_fraction  = temp_fraction and $000F
      temp_fraction = temp_fraction * 625
    
      ' convert temp_fraction to characters
      text[4] =  temp_fraction/1000    + 48         ' extract thousands digit
      text[5] = (temp_fraction/100) mod 10 + 48         ' extract hundreds digit
      text[6] = (temp_fraction/10) mod 10  + 48         ' extract tens digit
      text[7] =  temp_fraction mod 10      + 48         ' extract ones digit
    
      ' print temperature on LCD
      Lcd_Out(2, 5, text)
    end sub'~
    
    main:
      ANSEL  = 0                              ' Configure AN pins as digital I/O
    	ANSELH = 0
      Lcd_Config(PORTB,3,2,1,0,PORTB,4,7,5) ' Lcd_Init_EP5, see Autocomplete
      Lcd_Cmd(LCD_CURSOR_OFF)
      Lcd_Out(1, 1, " Temperature   ")
      ' Print degree character, 'C' for Centigrades
      Lcd_Chr(2,13,223)
      Lcd_Chr(2,14,"C")
    
      '--- main loop
      while TRUE
        '--- perform temperature reading
        Ow_Reset(PORTE,2)            ' Onewire reset signal
        Ow_Write(PORTE,2,$CC)       ' Issue command SKIP_ROM
        Ow_Write(PORTE,2,$44)       ' Issue command CONVERT_T
        Delay_us(120)
    
        Ow_Reset(PORTE,2)
        Ow_Write(PORTE,2,$CC)       ' Issue command SKIP_ROM
        Ow_Write(PORTE,2,$BE)       ' Issue command READ_SCRATCHPAD
    
        temp =  Ow_Read(PORTE,2)
        temp = (Ow_Read(PORTE,2) << 8) + temp
    
        '--- Format and display result on Lcd
        Display_Temperature(temp)
    
        Delay_ms(500)
      wend
    end.
    Maybe its time to learn a new language

  9. #9


    Did you find this post helpful? Yes | No

    Default

    Just some food for thought. This is the code I use for reading the DS18S20.

    Code:
    ReadDS18S20:
        owout sensor,1,[$CC, $44]                       ' Send Start Temperature Conversion command
        owout sensor,1,[$CC, $BE]                       ' Send Read Temperature command
        owin sensor,0,[STR dq\9]                        ' Retrieve all 9 bytes of data
        RawTemp.Byte0 = dq[0]
        RawTemp.byte1 = dq[1]
        if RawTemp.8 = 1 then                           ' Check if temperature is a negative reading
            SignC = Negative
            RawTemp.lowbyte = RawTemp.lowbyte ^ 255     ' Invert data
            else
            SignC = Positive
    	endif
        dummy = RawTemp.0                               ' Store the half degree indicator bit
        TempC = ((RawTemp.lowbyte) >> 1) * 100          ' Divide raw data by 2 to give real temperature
        TempC = TempC + (dummy * 50)                    ' Add the half degree is present
        if SignC = Negative then                        ' Only proceed if temperature is negative
            if TempC => 1770 then   
                SignF = Negative
                TempF = (TempC + 5000) * 900
                TempF = div32 500
                TempF = TempF - 12200
                return 
                else
                SignF = Positive
                TempF = (TempC + 5000) * 900
                TempF = div32 500
                TempF = 12200 - TempF
                return 
            endif    
        endif
        SignF = Positive
        TempF = TempC * 18 / 10 + 3200
        return
    This is the code I use for the DS18B20. This one also includes the CRC calculation.

    Code:
    ReadDS18B20:
        low portb.7 : low portb.6 : low portb.5
        pause 10
        owout sensor,1,[$CC,$44]
        low RailPullUp
        pause 750
        high RailPullUp
        owout sensor,1,[$CC,$BE]
        owin sensor,0,[STR dq\9]
        rawtemp.Byte0 = dq[0]
        rawtemp.Byte1 = dq[1]
        gosub getcrc
        if SensorError[sensor] = 1 and y < 3 then ReadDS18B20
        gosub ConvertTemp
        if SensorError[sensor] = 1 then
            y = 0
            TempC = 0
            TempF = 3200
            Signc = Positive
            SignF = Positive
        endif
        high portb.7 : high portb.6 : high portb.5
        return
        
    ConvertTemp:
        if NegBit = 1 then BelowZero
        SignC = Positive
        SignF = Positive
        dummy = 625 * RawTemp
        TempC = DIV32 100
        dummy = 0
        dummy = 1125 * Rawtemp
        TempF = DIV32 100
        TempF = TempF + 3200
        return
    
    BelowZero:
        SignC = Negative
        dummy = 0
        RawTemp.byte0 = RawTemp.byte0 ^ 255
        RawTemp.Byte1 = RawTemp.byte1 ^ 255
        dummy = 625 * RawTemp + 1
       	TempC = DIV32 100
        TempF = (TempC + 5000) * 900
        TempF = DIV32 500
        if RawTemp >= 285 then
            TempF = TempF - 12199
            SignF = Negative
            else				
            TempF = 12199 - TempF
            SignF = Positive
    	endif
    	return
    
    '------------------------ Calculate the CRC from Byte 9 ------------------------
    
    GetCRC:
        for x = 0 to 7
        DataByte = dq[x]
        gosub CalcCRC
        next x
        if dq[8] <> CRCCalc then
            SensorError[sensor] = 1
            y = y + 1
            else
            SensorError[sensor] = 0
            y = 0
        endif
        CRCCalc = 0                
        return
    
    '--------------------- CRC Bit Calcuation Method -------------------------------
    
    CalcCRC:
        for i = 0 to 7
        DataBit = CRCCalc.0 ^ DataByte.0
        DataByte = DataByte >> 1
        if DataBit = 0 then Shift
        CRCCalc = CRCCalc ^ $18
    
    Shift:
        CRCCalc = CRCCalc >> 1
        CRCCalc.7 = DataBit
        next i
        return

  10. #10


    Did you find this post helpful? Yes | No

    Default

    "Maybe its time to learn a new language "

    He he, don't let Alain hear you say that :-)
    Pbp is somewhat dated, mE basic example is for the new DS 18S20, note the "S".
    It has slightly reduced resolution from the DS 1820, or DS18B20 as it's now known, therefore the code to interrogate the device, and change the data into "English" :-) is different.
    No, I don't have the solution, but at least I have a clear understanding of the problem, I think.

  11. #11


    Did you find this post helpful? Yes | No

    Default

    The DS1820 and the DS18S20 were software interchangeable as we started out using the 1820 and then switched to the 18S20 when we could not get the other. We changed nothing I our code from my memory though.

  12. #12
    malc-c's Avatar
    malc-c Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Copy'nPaste View Post
    "Maybe its time to learn a new language "

    He he, don't let Alain hear you say that :-)
    LOL - only kidding, it's taking me all these years to get my head pbp and I'm still getting it wrong - Alain, I'm not going nowhere

    @coke

    Many thanks for posting your code - I'll give it a try now that I know the hardware is sound.

Similar Threads

  1. Please help with 1-wire DS1820
    By hatuan291 in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 9th March 2010, 13:51
  2. DS1820 with 16f688
    By jessey in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 23rd May 2009, 05:07
  3. DS1820 display with 7-seg 4 digits
    By chai98a in forum Code Examples
    Replies: 12
    Last Post: - 10th April 2008, 13:12
  4. PIC lcd ds1820
    By wchpikus in forum mel PIC BASIC
    Replies: 2
    Last Post: - 24th May 2007, 14:46
  5. DS1820 again
    By paxmowa in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 10th January 2006, 14:49

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts