DS18B20 ROM Search

MartinM57

Moderator
I've searched around for a while and the best I can find is a promise from Technical to write up a solution "one day" - see http://www.picaxeforum.co.uk/showthread.php?t=6726&highlight=search+rom

The code might be complex (and large) but with the SLOT facility it could be nicely farmed off into its own slot and run during, say, user installation.

Has that ever been done and/or has anyone got exemplar code that would do it please? For a 28-X2 by the way, with say 6 devices on one wire.

I'd have a go myself, but if someone's already done it...

Ta
Martin
 

BeanieBots

Moderator
Can't remember the exact thread or unfortunatley who did it but it has been done and has been posted here. I think it was in the finished projects section.
Hopefully the author will respond.
 

retepsnikrep

Senior Member
I did quite a bit of work on this for my battery management project.

I wrote two bits of code.

One to get the serial number out of the sensors. You have to do this one at a time and write it down.
I connected each one in turn to an input and ran my program.

One to utilise several of the sensors on the same input using the info from the above to interogate them.

Code:
SensorSerial:

`The readowsn command reads the serial number and then puts the family code
`in b6, the serial number in b7 to b12, and the checksum in b13

`Note that you should not use variables b6 to b13 for other purposes in your
`program during a readowsn command.


	serout Video,Baud9600,(27,67,"Sensor Serial No",10,13) 		;Video Display	
	
Main:
	readowsn TempSensor			;Read serial number on input2

	serout Video,Baud9600,(#b6," ",#b7," ",#b8," ",#b9,10,10,13) 	;Video Display

	serout Video,Baud9600,(#b10," ",#b11," ",#b12," ",#b13,10,10,13) 	;Video Display
	
	serout Video,Baud9600,("Note the 8 No's!") 			;Video Display
Code:
CheckTemp:			;Check Battery Pack temperature routine (Multiple DS18B20 I2C Sensors) Once per minute

`The owout lines become TempSensor,%1001,($55,xx,xx,xx,xx,xx,xx,xx,xx,$44) where xx = decimal serial no's for the I2C chips

`Sensor 1 (Front Battery Block)

	owout TempSensor,%1001,($55,40,16,70,22,1,0,0,170,$44)	;Send ‘reset’ then ‘Match ROM’
	pause 1500						;Wait 750ms (8mhz) with strong pullup
	owout TempSensor,%0001,($55,40,16,70,22,1,0,0,170,$BE)	;Send ‘reset’ then ‘Match ROM’

	gosub calculatetemp                                     ;Gosub Calculate Temperature routine
			
	poke Temp1, CountE					;Store Front Battery Temperature in Temp1 Ram Byte
	poke Temp1S, CountA					;Store Temperature Sign byte (+ or -)

`Sensor 2 (Rear Battery Block)

	owout TempSensor,%1001,($55,40,14,45,234,0,0,0,75,$44)	;Send ‘reset’ then ‘Match ROM’
	pause 1500						;Wait 750ms (8mhz) with strong pullup	
	owout TempSensor,%0001,($55,40,14,45,234,0,0,0,75,$BE)	;Send ‘reset’ then ‘Match ROM’
	
	gosub calculatetemp                                     ;Gosub Calculate Temperature routine
	
	poke Temp2, CountE					;Store Rear Battery Temperature in Temp2 Ram Byte
	poke Temp2S, CountA					;Store Temperature Sign byte (+ or -)

	return							;Return to main program loop	

;**************************************************************************************************************

CalculateTemp:

	owin  TempSensor,%0000,(b16,b17) 	;Read temp sensor result into w8 (b16,b17) PackTemp12
	

	If PackTemp12 > 2047 Then		;If PackTemp12 > 2047 then temperature reading is Negative
    	PackTemp12 = PackTemp12 ^ $ffff + 1	;Take twos complement of reading
	CountA = 45				;Set CountA to 45 (-) if temperature is negative
	else	
	CountA = 43				;Set CountA to 43 (+) if temperature is positive
	endif

	`Convert 12bit DS18B20 value to a valid temperature reading 
	CountW =  PackTemp12 * 6		;TC = value * 0.0625
	PackTemp12 = PackTemp12 * 25 / 100
	PackTemp12 = CountW + PackTemp12
	CountE = PackTemp12 / 100

`	CountE = 47				;Test Temp Over Max
`	CountE = 55				;Test Temp Over AbsMax	

	if CountE > AbsMaxPackTemp then 	;If Temp > AbsMaxPackTemp set Alarm Bit
	Alarm4 = 1				;Set Alarm4 Bit to 1 (Indicates Temp over AbsMax Temp condition)
	endif 	

	if CountE > MaxPackTemp then		;If Temp > MaxPackTemp set Warning Bit
	Warn3 = 1				;Set Warn3 Bit to 1 (Indicates Temp over Max Temp condition)
	endif

	return					;Return to CheckTemp
I hope you can work out what's happening from my code. Peter
 
Last edited:

MartinM57

Moderator
Thanks Peter - that all seems pretty straightfoward to follow :)

What I was really after is the code for the "process of elimination" on page 12 of the DS18B20 data sheet - http://www.rev-ed.co.uk/docs/DS18B20.pdf - which derives the serial numbers of an unknown(?) number of sensors on a one-wire bus i.e means that your first piece of code and 'writing down' isn't needed - your second piece of code would use the serial numbers found by the "process of elimination" task...
 

hippy

Ex-Staff (retired)
The code on page 12 of the DS18B20 datasheet looks very interesting. It is really a binary chop algorithm to determine what branches of the tree of ROM codes are available and which are not. I'm not sure that would be particularly easy to implement on a PICAXE in a traditional iterative way; data storage mainly as each has a 64-bit ROM code and you need to distinguish all the bits.

It could be done as a recursive subroutine call but you'd need a 64 deep call stack and data held for each level of depth. It should be notionally easy when treated as a recursive problem with quite compact code.

As Technical noted in the link in Post #1 ... So you've got the ROM codes, you can get each serial number, you can get all data from your sensors ... but what good does it do you if you cannot identify which physical sensor is which ?

For a handful of sensors in a room or enclosure where you wanted an average reading it may not matter which was which. For a board of uniquely different function 1-wire devices it would be handy, as reading what they are enables arbitrary ROM code and serial umbers to be automatically related to device to use for each function, but I cannot think of other applications where it wouldn't be necessary to have some idea of where each sensor was physically placed.

It's a similar problem with identical PC's on a network where each is given an IP address through DHCP. You can determine MAC address, IP address, of everyone of those PC's, but you cannot tell which one is on the desk next to you to copy a file over the network to from just that information.

If you want to do this for academic interest I'd say it was doable, and a worthy challenge with good rewards with its success. In practical terms I'm not sure how it would really be worthwhile. Perhaps an explanation of what problem you're trying to solve would enlighten me ?
 

hippy

Ex-Staff (retired)
This should do the job, but has to be turned into PICAXE code and actual interaction with 1-wire bus added ...

Code:
Dim knownRomCode()
Dim romBit()
knownPtr = 0
Call Find(1,0)
Call Find(1,1)
End

Sub Find( depth, bitVal )
  If depth = 1 Then
    Call StartRomIdentification
  End If
  romBit(depth) = bitVal
  If RomExistsWithBitVal(bitVal) Then
    If depth = 64 Then
      Call Found
    Else
      Call Find( depth+1, 0 )
      Call Find( depth+1, 1 )
    End If
  End If
End Sub

Sub Found
Dim i
Dim romCode
  romCode = 0
  For i = 1 To 64
    romCode = romCode * 2 + romBit(i)
  Next
  knownPtr = knownPtr + 1
  knownRomCode( knownPtr ) = romCode
End Sub
 
Top