Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

DS18B20 Code Question / 1-Wire Bus Reset

Status
Not open for further replies.

rmain1972

Member
@JakeElectronics or anyone else who wants to answer.

I am building a well house thermostat based on Jakeselectronics project Digital Temperature Sensor. My question is a section of code which checks for device presence on the 1-Wire bus. It will hang if no device is present. It seems to be that way because my call to DS18B20_RESET is not returning, ie my test LED is not turning on. Which probably means I'm not seeing the sensor. I can post all my code as an attachment if needed.

Code:
;**************************************************
; DS18B20_RESET
;
; Purpose: RESET the One-Wire bus
; Input: None
; Output: None
;
;**************************************************
DS18B20_RESET
	call DQ_LL				; Force the DQ Line to a Logic Low
	movlw (D'480'-5)/5		; Leave it low for 480us
	movwf del
	call Delay_us			
	bsf PORTA, DQ;			; Set DQ to HIGH
	movlw (D'60'-5)/5		; Wait for recovery
	movwf del
	call Delay_us
	call DQ_HIZ				; Force DQ
	banksel PORTA
	btfsc PORTA, DQ			; Get Presense signal
	goto DS18B20_RESET		; If not present, RESET <-- Could this cause an infinate loop?
	movlw (D'420'-5)/5		; Wait for End of Timeslot
	movwf del
	call Delay_us
	return

I also wrote a test program in MikroC to test the sensor. The test program turns on the test LED to indicate that the device is present, although the device still reads 0C, so maybe my device_present if statement is wrong?

C:
/************************************************************************
 DS18B20 Test Program
 
 This program uses the one-wire library and LCD library to communicate
 with a DS18B20 sensor.
 
*/

#define DS18B20_PIN 1

// LCD module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB2_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB2_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

// End LCD module connections

//  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 unsigned short TEMP_RESOLUTION = 12;

char *text = "000.0000";
unsigned temp;
int device_present;

void Display_Temperature(unsigned int temp2write) {
  const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
  char temp_whole;
  unsigned int temp_fraction;

  // Check if temperature is negative
  if (temp2write & 0x8000) {
     text[0] = '-';
     temp2write = ~temp2write + 1;
     }

  // Extract temp_whole
  temp_whole = temp2write >> RES_SHIFT ;

  // Convert temp_whole to characters
  if (temp_whole/100)
     text[0] = temp_whole/100  + 48;
  else
     text[0] = '0';

  text[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  text[2] =  temp_whole%10     + 48;             // Extract ones digit

  // Extract temp_fraction and convert it to unsigned int
  temp_fraction  = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;

  // Convert temp_fraction to characters
  text[4] =  temp_fraction/1000    + 48;         // Extract thousands digit
  text[5] = (temp_fraction/100)%10 + 48;         // Extract hundreds digit
  text[6] = (temp_fraction/10)%10  + 48;         // Extract tens digit
  text[7] =  temp_fraction%10      + 48;         // Extract ones digit

  // Print temperature on LCD
  Lcd_Out(2, 5, text);
}

void main() {
     // Switch internal OSC to 8 Mhz
     OSCCON = 0x70;
     
     //Setup PORTA
     ADCON1 = 0x06;     //Configure all pins as digital
     TRISA =  0xC0;      // b'11000000'  RA7 RA6 Input, all others Output
     
     //Setup PORTB
     TRISB = 0x00;       // All Output

     //LED Off
     PORTA.RA0 = 0;

    Lcd_Init();                                    // Initialize LCD
    Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
    Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
    Lcd_Out(1, 1, " Temperature:   ");
    
    // Print degree character, 'C' for Centigrades
    Lcd_Chr(2,13,223);                             // Different LCD displays have different char code for degree
                                                 // If you see greek alpha letter try typing 178 instead of 223

    Lcd_Chr(2,14,'C');

    //Reset Ow Bus
    device_present=Ow_Reset(PORTA, DS18B20_PIN);
    
    if (device_present == 1) {
       PORTA.RA0 = 1;  // Turn On Test LED
    }

  //--- Main loop
  do {
    //--- Perform temperature reading
    Ow_Reset(&PORTA, DS18B20_PIN);                         // Onewire reset signal
    Ow_Write(&PORTA, DS18B20_PIN, 0xCC);                   // Issue command SKIP_ROM
    Ow_Write(&PORTA, DS18B20_PIN, 0x44);                   // Issue command CONVERT_T
    Delay_us(120);

    Ow_Reset(&PORTA, DS18B20_PIN);
    Ow_Write(&PORTA, DS18B20_PIN, 0xCC);                   // Issue command SKIP_ROM
    Ow_Write(&PORTA, DS18B20_PIN, 0xBE);                   // Issue command READ_SCRATCHPAD

    temp =  Ow_Read(&PORTA, 2);
    temp = (Ow_Read(&PORTA, 2) << 8) + temp;

    //--- Format and display result on Lcd
    Display_Temperature(temp);

    Delay_ms(500);
  } while (1);


Thanks in advance
 
Last edited:
I don't have a pull up resistor on the DQ line. Let me try that. Oops. ;) 4.7K resistor on the DQ line still no go. :( I'll take closer look at both programs tomorrow.
 
Last edited:
Hey rmain1972!
Yeah that resistor is a must! That may solve your problems...

Keep us posted.

(just FYI, Im currently updating my software for a Fahrenheit version and will post them on my website... The versions currently on there may be a little scattered, but will be in order soon)
 
I put my original DS18B20 code in the chip, and I got '1' on the display, so now I'll write the Celsius number display. So I'm making progress. ;)
 
Status
Not open for further replies.

Latest threads

Back
Top