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.

1 Wire Protocol Code Issue

Status
Not open for further replies.

Gayan Soyza

Active Member
Hi I'm using DS18S20.I'm confused with the scratchpad.

When I use

Code:
	movlw	H'BE'
	call	DS_Transmitt	;Read Scratch pad

Read Scratch pad command according to the datasheet it says it will reads the whole memory in the scratchpad.

How I read the temperature? Is it ok if I read the DS (Data Pin) after the above command?Will it automatically select the result registers?
 
You have to send SkipRom or MatchRom before you send ReadScratchPad. Once you have sent these you can read back 9 bytes (8 data + crc). To do a conversion you need to send a convert command (again proceeded by match or skip rom). The convert command takes about 750mS but you can poll to see when it is finished, just read bits in until you get a 1 bit.

Mike.
 
Thanks Mike

Once you have sent these you can read back 9 bytes (8 data + crc)

This is the place I got stucked.

Code:
	call	DS_Reset	;reset the DS
	btfss	STATUS,Z	;if set recep ok
	goto	Bad_Temp
	movlw	H'CC'		;skip ROM
	call	DS_Transmitt
	movlw	H'BE'		;read Scratchpad
	call	DS_Transmitt

	[COLOR="Red"]call	DS_Recieve	;
	movwf	Temp1	[/COLOR]
 
Yes, you call your read routine on the data pin next and you get the scratchpad results. The dallas one wire sensors read in LSB first. So the simple way is just to read in the first byte, and ignore the sign bit for now. Right shift the result once and you have your whole integer temperature.

EDIT: thought process was using a SkipRom command, single sensor.
 
Last edited:
Yes, you call your read routine on the data pin next and you get the scratchpad results. The dallas one wire sensors read in LSB first. So the simple way is just to read in the first byte, and ignore the sign bit for now. Right shift the result once and you have your whole integer temperature.

EDIT: thought process was using a SkipRom command, single sensor.

Ahh that means after reading the scratchpad when I call the DS_Receive it will automatically reads the first byte?

I found this in the data sheet.

Code:
When reading the scratchpad, data is transferred over the 1-Wire bus starting with the least significant bit of byte 0.

That means after read scratchpad command sends when I read the sensor it will give the 0 bytes result.And after When I read the sensor again it will read the 1 bytes result so & so....Until I reset.
 
Last edited:
Yes, you've got it. When you send the "read scratchpad" command you're just telling the DS18x20 to prepare to send 9 bytes. But you don't have to read all 9 bytes. You can simply receive two bytes, the temperature data bytes, if you wish...

Mike
 
Yes, you've got it. When you send the "read scratchpad" command you're just telling the DS18x20 to prepare to send 9 bytes. But you don't have to read all 9 bytes. You can simply receive two bytes, the temperature data bytes, if you wish...

Mike

Excellent thanks for confirming that thing.

I was no used this 1 wire thing due to unavailability & the price.All I worked with commonly available LM series temperature sensors.

Will see how the 1 wire things works like :D
 
Hi guys I worked on that.I did a temperature display using DS18S20 & showed the temperature on SSDs.

It worked well but not much speed than I expected :D

Temperature is stable because due to its slowliness.

The problem is its with 0.5C increments.I don't like that.I need 0.1C increments.

Is anyone worked with 0.1C increments with this device?
 
Last edited:
The DS18S20 will only work to 0.5°C the DS18B20 will work to 0.0625 (1/16th) of a degree. However, without calibration they are only accurate to 0.5°C.

Mike.
 
With a bit of **broken link removed** you can get 12-bit results out of an 18S20. See page 3 of the datasheet. I've forgotten the details of how it works, but it does work.

You mean this line?

miketemp=(miketemp/2)*16+(16-countremain);

I think "miketemp" means the temperature (Lower byte) after right shifting once.
 
Thanks, I missed that bit in the data sheet. Just changed my VB program to display 1/16 of a degree.

Mike.
 
Code:
;miketemp=(miketemp/2)*16+(16-countremain);	
;---------------------------------------------
;(miketemp/2)*16

	movf	Mike_Temp,W	;DS temperature lower byte (LSB removed)
	movwf	Mike_TempL	;lower byte
	clrf	Mike_TempH	;Higher byte

	bcf	STATUS,C
	rlf	MiketempL,F
	rlf	MiketempH,F
	bcf	STATUS,C
	rlf	MiketempL,F
	rlf	MiketempH,F
	bcf	STATUS,C
	rlf	MiketempL,F
	rlf	MiketempH,F
;-------------------------------------------
;(16-countremain)

	movlw	D'16'
	movwf	Fix_Val
	movf	Count_R,W	;countremain from scratchpad
	subwf	Fix_Val,W

	addwf	MiketempL,F
	btfsc	STATUS,C
	incf	MiketempH,F
	movf	MiketempL,W
	movwf	ResultL		;resultL
	movf	MiketempH,W
	movwf	ResultH		;resultH

I did a simple math part for that mikes formula.Just want to verify that.I hope this ResultL is the fraction part & the ResultH is the temperature.
 
Dropping the bottom bit is wrong, you should only drop half the bottom bit (-¼°).

I make the calculation,

Temperature = ReadTemp<<3+(16-CountRemain)-4

The bottom 4 bits of temperature are now the fractional part.

Mike.
 
Hi mike

Code:
miketemp=([COLOR="Red"]miketemp[/COLOR]/2)*16+(16-countremain)

In the above code "miketemp" means, "ReadTemp-0.25 D"? or right shift once the ReadTemp?

If it is "ReadTemp-0.25" then I need another two variables to calculate the math.

In your one

Code:
Temperature = ReadTemp[B][COLOR="Red"]<<[/COLOR][/B]3+(16-CountRemain)-4

Whats that sign <<?
 
Shift left 3 bits.

:D now I got it.

I worked with Mikes (pommies) new formula.

Code:
;Temperature = ReadTemp<<3+(16-CountRemain)-4
;----------------------------------------------------------------------
;(ReadTemp<<3)
;----------------------------------------------------------------------
	movf	ReadTemp,W	;DS Temperature (lower byte) with 0.5LSB
	movwf	TempLow
	clrf	TempHigh
	bcf	STATUS,C
	rlf	TempLow,F
	rlf	TempHigh,F
	bcf	STATUS,C
	rlf	TempLow,F
	rlf	TempHigh,F
	bcf	STATUS,C
	rlf	TempLow,F
	rlf	TempHigh,F

;(16-countremain)
;----------------------------------------------------------------------
	movlw	D'16'
	movwf	Fix_Val
	movf	Count_R,W	;countremain from scratchpad
	subwf	Fix_Val,W
	movwf	Temp
	movlw	.4
	subwf	Temp,W

	addwf	TempLow,F
	btfsc	STATUS,C
	incf	TempHigh,F
	movf	TempLow,W
	movwf	ResultL		;resultL	
	movf	TempHigh,W
	movwf	ResultH		;resultH
 
Last edited:
Hi Gayan,

Sorry I was away for a couple days.

Here's how I do that little formula in assembler ("remain" is the "count_remain" byte from the DS18S20 scratchpad memory);

Code:
;******************************************************************
;
;  convert DS18S20 TempH:TempL to full resolution DS18B20 format
;
;  TempH:L = (TempH:L / 2) * 16 + (16 - Count_Remain)
;
        rlf     TempL,F         ;                                 |B0
        rlf     TempH,F         ;                                 |B0
        rlf     TempL,F         ;                                 |B0
        rlf     TempH,F         ;                                 |B0
        rlf     TempL,F         ;                                 |B0
        rlf     TempH,F         ;                                 |B0
        movlw   0xF0            ;                                 |B0
        andwf   TempL,F         ;                                 |B0
        movf    remain,W        ; get DS18S20 remainder           |B0
        sublw   16              ;                                 |B0
        iorwf   TempL,F         ; now DS18B20 format              |B0
        return                  ;                                 |B0
And by the way, here's the formula I use to convert the 12 bit DS18B20 format temperature word into decimal with 3 decimal places;

Code:
;******************************************************************
;
;  BC2DC - binary °C*16 to decimal °C*1000 (3 decimal places)
;
;  °C*1000 = 1000 * 16 * (Celsius*16) / 256
;          = 16000 * TempH:TempL / 256
;          =   125 * TempH:TempL / 2        // 3 dec places
;
;  Bcd2:0 packed bcd output -055000 to +125000 (°C*1000)
;
        radix   dec
BC2DC                           ; 3 dec places, mult8x16div2
        movlw   125             ; multiplier = 125                |B0
        call    Mult8x16div2    ; multiplicand = TempH:TempL      |B0
        call    AbsFunc         ; make positive, setup NegFlag    |B0
        goto    Bin2bcd         ; output is 6 digit packed BCD    |B0
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top