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.
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?
Thanks in advance
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: