Onewire sensor scanning problem

Discussion in 'Programmer's Corner' started by motzey, May 9, 2012.

  1. motzey

    Thread Starter New Member

    Apr 22, 2011
    1
    0
    I am using the EasyPIC6 dev board & MikroC to program a 16F887 to scan the DS18S20 temp. sensor and display it on a 4X16 LCD. I then modified the code to drive the LCD from PORTD on a 18F4685 MCU and it compiled and ran OK on the EasyPIC6 board. I then put the 18F4685 into a prototype board I built and the LCD displays the temperaure and 000.0000 text OK, but the temp. from the DS18S20 never comes up on the display. The RE2 PORTE pin is used to scan and control the sensor and I have tried other PORT pins with no luck. I feel the PORT latch function may be where I am coding it wrong. I have checked & double checked my prototype board wiring & it all looks OK. At wits end on this one. Thanks HD

    Code ( (Unknown Language)):
    1.  
    2. /*
    3.  * Project name:  Modified from 18F8520 to 18F4685
    4.      OneWire (Interfacing the DS1820 temperature sensor - all versions)
    5.  * Copyright:
    6.      (c) mikroElektronika, 2008.
    7.  * Revision History:
    8.      20081218:
    9.        - initial release;
    10.  * Description:
    11.      This code demonstrates one-wire communication with temperature sensor
    12.      DS18x20 connected to RE5 pin.
    13.      MCU reads temperature from the sensor and prints it on the LCD.
    14.      The display format of the temperature is 'xxx.xxxx°C'. To obtain correct
    15.      results, the 18x20's temperature resolution has to be adjusted (constant
    16.      TEMP_RESOLUTION).
    17.  * Test configuration:
    18.      MCU:             P18F4685
    19.                       [URL]http://ww1.microchip.com/downloads/en/DeviceDoc/39609b.pdf[/URL]
    20.      Dev.Board:       EasyPIC6
    21.                       [URL]http://www.mikroe.com/en/tools/bigpic6/[/URL]
    22.      Oscillator:      HS, 8.0 MHz
    23.      Ext. Modules:    DS18S20, LCD_2x16
    24.      SW:              mikroC PRO for PIC
    25.                       [URL]http://www.mikroe.com/en/compilers/mikroc/pro/pic/[/URL]
    26.  * NOTES:
    27.      - //Turn on DS1820 switch SW12.8
    28.  -// Pull up(jumper J5) and turning off diode (switch SW10) on pin RE5
    29.        // ( board specific) used for one wire bus may be required.
    30. */
    31.  
    32. // ******************** Code for using PORTB for LCD ************************
    33.  
    34. sbit LCD_RS at LATB4_bit;
    35. sbit LCD_EN at LATB5_bit;
    36. sbit LCD_D4 at LATB0_bit;
    37. sbit LCD_D5 at LATB1_bit;
    38. sbit LCD_D6 at LATB2_bit;
    39. sbit LCD_D7 at LATB3_bit;
    40.  
    41. sbit LCD_RS_Direction at TRISB4_bit;
    42. sbit LCD_EN_Direction at TRISB5_bit;
    43. sbit LCD_D4_Direction at TRISB0_bit;
    44. sbit LCD_D5_Direction at TRISB1_bit;
    45. sbit LCD_D6_Direction at TRISB2_bit;
    46. sbit LCD_D7_Direction at TRISB3_bit;
    47.  
    48.  
    49.  
    50. // LCD module connections
    51. //sbit LCD_RS at LATD2_bit;  // for writing to output pin always use latch (PIC18)
    52. //sbit LCD_EN at LATD3_bit;  // for writing to output pin always use latch (PIC18)
    53. //sbit LCD_D4 at LATD4_bit;  // for writing to output pin always use latch (PIC18)
    54. //sbit LCD_D5 at LATD5_bit;  // for writing to output pin always use latch (PIC18)
    55. //sbit LCD_D6 at LATD6_bit;  // for writing to output pin always use latch (PIC18)
    56. //sbit LCD_D7 at LATD7_bit;  // for writing to output pin always use latch (PIC18)
    57.  
    58. //sbit LCD_RS_Direction at TRISD2_bit;
    59. //sbit LCD_EN_Direction at TRISD3_bit;
    60. //sbit LCD_D4_Direction at TRISD4_bit;
    61. //sbit LCD_D5_Direction at TRISD5_bit;
    62. //sbit LCD_D6_Direction at TRISD6_bit;
    63. //sbit LCD_D7_Direction at TRISD7_bit;
    64. // End LCD module connections
    65.  
    66. //  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
    67. //  18S20: 9  (default setting; can be 9,10,11,or 12)
    68. //  18B20: 12
    69. const unsigned short TEMP_RESOLUTION = 9;
    70.  
    71. char *text = "000.0000";
    72. unsigned temp;
    73.  
    74. void Display_Temperature(unsigned int temp2write) {
    75.   const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
    76.   char temp_whole;
    77.   unsigned int temp_fraction;
    78.  
    79.   // check if temperature is negative
    80.   if (temp2write & 0x8000) {
    81.      text[0] = '-';
    82.      temp2write = ~temp2write + 1;
    83.      }
    84.  
    85.   // extract temp_whole
    86.   temp_whole = temp2write >> RES_SHIFT ;
    87.  
    88.   // convert temp_whole to characters
    89.   if (temp_whole/100)
    90.      text[0] = temp_whole/100  + 48;
    91.   else
    92.      text[0] = '0';
    93.  
    94.   text[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
    95.   text[2] =  temp_whole%10     + 48;             // Extract ones digit
    96.  
    97.   // extract temp_fraction and convert it to unsigned int
    98.   temp_fraction  = temp2write << (4-RES_SHIFT);
    99.   temp_fraction &= 0x000F;
    100.   temp_fraction *= 625;
    101.  
    102.   // convert temp_fraction to characters
    103.   text[4] =  temp_fraction/1000    + 48;         // Extract thousands digit
    104.   text[5] = (temp_fraction/100)%10 + 48;         // Extract hundreds digit
    105.   text[6] = (temp_fraction/10)%10  + 48;         // Extract tens digit
    106.   text[7] =  temp_fraction%10      + 48;         // Extract ones digit
    107.  
    108.   // print temperature on LCD
    109.   Lcd_Out(2, 5, text);
    110. }
    111.  
    112. void main() {
    113.  
    114.   ADCON1 |= 0x0F;                                // Configure AN pins as digital
    115.   CMCON  |= 7;                                   // Disable comparators
    116.   TRISD =0;
    117.   Lcd_Init();                                    // Initialize LCD
    118.   Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
    119.   Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
    120.   Lcd_Out(1, 1, " Temperature:   ");
    121.   // Print degree character, 'C' for Centigrades
    122.   Lcd_Chr(2,13,178); // different LCD displays have different char code for deg.
    123.                   // if you see greek alpha letter try typing 178 instead of 223
    124.  
    125.   Lcd_Chr(2,14,'C');
    126.  
    127.   //--- main loop
    128.   do {
    129.     //--- perform temperature reading
    130.     Ow_Reset(&PORTE, 2);                         // Onewire reset signal
    131.     Ow_Write(&PORTE, 2, 0xCC);                   // Issue command SKIP_ROM
    132.     Ow_Write(&PORTE, 2, 0x44);                   // Issue command CONVERT_T
    133.     Delay_us(120);
    134.  
    135.     Ow_Reset(&PORTE, 2);
    136.     Ow_Write(&PORTE, 2, 0xCC);                 // Issue command SKIP_ROM
    137.     Ow_Write(&PORTE, 2, 0xBE);                 // Issue command READ_SCRATCHPAD
    138.     Delay_ms(400);
    139.  
    140.     temp =  Ow_Read(&PORTE, 2);
    141.     temp = (Ow_Read(&PORTE, 2) << 8) + temp ;
    142.      PORTD = 1;
    143.     //--- Format and display result on Lcd
    144.     Display_Temperature(temp);
    145.  
    146.     Delay_ms(3000);
    147.     PORTD = 0;
    148.   } while (1);
    149. }
    150.  
     
    Last edited by a moderator: May 10, 2012
  2. coldpenguin

    Active Member

    Apr 18, 2010
    165
    9
    Are you running in powered or parasitic mode? If parasitic, I think that you are missing a hard pull-up after your 0x44
    Also, I reckon your timings are the wrong way around. The s20 will require much longer after the 0x44 than after the 0xbe, I would swap over your timings.
    In fact, what I do (however others don't like my coding), is to perform the 0xcc, 0x44 at the end of the while loop,
    i.e.
    temp=(OW_read...)
    OW_Reset()
    OW_Write(0xcc)
    OW_Write(0x44)
    Display_Temperature();
    Delay_ms(3000);
    } /end while

    You will of course be running 3 seconds lag in this setup.....
    I don't see a TRISE statement, but I guess this is dealt with by the OW routines.

    Do you have a logic analyser? I found one very useful for debugging this protocol.

    One thing to note, which kind-of ties in with what I said above about timings, if a sensor has not completed its conversion, it returns 0x00 for every read command that it receives.
    If the s20 does not manage a conversion, it returns 85, given that you are seeing a temperature of 0 degrees, this suggests a conversion has not completed.
    However, this doesn't make sense as being the fault if all you have done is move from one port to another.
    It does make sense if you have moved from normal to parasitic power, as the conversion takes longer (however in theory 0x00 shouldn't be returnable in parasitic mode).
    Have you double-checked you haven't attached the pull-up resistor to ground instead of +ve by accident, and what value of pull-up are you using?
     
Loading...