Please I Need Tutorial For @westaust55-1-wire-Code

HaraldWien

New Member
Hallo, Servus aus Wien!
(Hi, greetings from Vienna!)
My Name is Harald and i am a older Boy which operate first time with picaxe.
And i am a coding-Thief ;-)
My Problems:
PICAXE20X2 and 6 DS18B20 heat sensors.
I have copied the Programcode "1-Wire Network search & validation core program Variable usage.pdf " from this Forum (http://www.picaxeforum.co.uk/showthread.php?15306-One-Wire-Devices-Networks/page10&highlight=one-wire+network+search on my Computer.
I think the author is @westaust55. The Program works fine on my Testboard with my 6 DS18B20.
I wanted to modify the code for my application. I have some experience (> 30 years) in the programming of commercial programs (last PowerBuilder).
But microcontroller I program for the first time.
It's about following program part:
Code:
;=========================================================================
; Subroutine to search a One-Wire network for connected devices. 
; Stores all valid serial Numbers in EEPROM
;
;
; First set pointers/ counters and check if there are any devices on the 1-Wire network  	
OW_Net_Search:  	
	errors = 0						; clear the error counter/flag
	devices	= 0					; clear the connected and valid 1-Wire device counter 
	EE_Addr	= 1					; set the EEPROM address to location for first Serial Number
								; start at location 1 as EEPROM location 0 is used for count of 
								; valid stored 1-wire  device serial numbers.
	SERTXD( "Searching for 1-Wire devices ...", CR, LF )
	GOSUB Any_Device					; test if there are ANY devices connected to the 1-Wire network
	IF errors = 0 THEN Proceed
	RETURN						; return immediately if no devices were found

; At least one device so proceed with the 1-Wire Network search
Proceed:
  	OWOUT OW_Net, owresetbefore, ( Search_ROM ) ; send a reset pulse and then the Search_ROM command
	ptr = Start_Scr_Arry				  ; set the pointer to the start of the scratchpad array
	
Cont_Search:
	DO
		OWIN  OW_Net, ownoreset_bit_pu, ( id_bit, comp_id_bit )
		OWOUT OW_Net, ownoreset_bit_pu, ( id_bit )
		IF id_bit = comp_id_bit THEN
			@ptrInc = 2				; value set to 2 to record a collision occurred at this bit
		ELSE
			@ptrInc = id_bit			; if no collision then save current bit value for serial number
		ENDIF
	LOOP UNTIL ptr > End_Scr_Arry			; repeat until all 64 bits of serial number are found

	crc8 = 0						; clear the CRC8 accumulator
	ptr = Start_Scr_Arry				; set the pointer to the start of the scratchpad array
	SERTXD( CR, LF, "Found : " )
		
	DO							; read in serial number bits form scratchpad array lsb first
		SNo_Result = SNo_Result >> 1		; Shift SNo right as next more significant bit is about to be added
		SNo_bit = @ptrInc				; set the next most significant bit
		SNo_Byte = ptr // 8 			; if 8 bits now retrieved then display the full byte and save to EEPROM 
		IF SNo_Byte = 0 THEN
			GOSUB Displ_Byte			; display the current byte of serial number
			WRITE EE_Addr, SNo_Result 	; save the current byte of serial number
			INC EE_Addr			  	; increment the EEPROM address pointer
			IF ptr <= End_Scr_Arry THEN GOSUB Crc8Add ; add the current byte into the CRC8 check accumulator
		ENDIF
	LOOP UNTIL ptr > End_Scr_Arry			; repeat until all 64 bits (8 bytes) are retrieved

	SERTXD (TAB, "Checksum ")			; the last byte read should now be equal to the CRC8 checksum
	IF crc8 = SNo_Result THEN
		SERTXD("Okay" )
		INC devices
	ELSE
		SERTXD("Failed" )
    		INC errors
    		IF EE_Addr > 1 THEN
      		EE_Addr = EE_Addr - 8		; if there was an error then reset the EEPROM pointer to start of SNo slot
    		ENDIF
  	ENDIF
  	
	DO
		DEC ptr 					; step back through the scratchpad array
		IF @ptr = 2 THEN				; check if last bit was a collision - new branch if there was a collision
			@ptr = 1
			OWOUT OW_Net, owresetbefore, ( Search_ROM ) ; send a reset pulse and then the Search_ROM command
			SNo_Byte = ptr			; temporarily save bit at which last collision occurred
			ptr = Start_Scr_Arry		; reset pointer to start of scratchpad array
			DO					; read in each bit until reach point of the last S/No bit collision
        			OWIN  OW_Net, ownoreset_bit_pu, ( id_bit, comp_id_bit )
        			OWOUT OW_Net, ownoreset_bit_pu, ( @ptrInc )
      		LOOP WHILE ptr <= SNo_Byte
      		GOTO Cont_Search			; then resume the search at the bit where last collision occurred
    		ENDIF
	LOOP UNTIL ptr = Start_Scr_Arry		; repeat until pointer is back at the first bit = all connected devices found		;

	WRITE OWDevCnt, devices				; save the count of all valid 1-Wire devices found
	
  	SERTXD(CR, LF, "Finished Search", CR, LF, CR, LF) 
  	SERTXD( #devices, " S/No's for devices saved to PICAXE EEPROM", CR, LF )
  	SERTXD( #errors,  " were found with device S/No errors.", CR, LF )
	RETURN
I understand not what the reason for the bitvalue-2-procedure in the lower part of the subroutine.
The program line "GOTO Cont_Search" is the only way to ensure that the program running again continues at label "Cont_Search:".
(My IT-Teacher say: "Never with goto outside a loop-structure" ;-)
That means, a "Bit-Collosion" (then set bit to 2) appears on every reading Device-Record except the data from the last Device.
If no bit-2 error occurs, then there is no return to the point "Cont_Search"?
Now I have created a program that handles the device records in a similar manner.
Unfortunately it does not work - here is the important part of the program:
Code:
Ow_ToEeprom:
;
; 	Liest die ROM-Daten (8 Byte) der 1-wire-Devices vom 1-wire-Netz ein
;     und schreibt sie in den EEPROM
;
;     Scratchpad   0 -   7 = ROM-Byte-Daten des aktuellen 1-wire-Devices
;     Scratchpad   8 -  71 = ROM-Bit-Daten  des aktuellen 1-wire-Devices
;	b0 = Aktuelles Byte, welches verarbeitet wird
;	b1 = Hilfsspeicher
;     b2 = merker
;	b3 = CRC8_Wert
;     b4 = Pointer fuer EEPROM-Abspeicherung

	Antwort	= 0 
	Fehler 	= 0 
		
	OwOut OwPin,owresetbefore,(OwSearchRom)
	ptr 		= 0

Ow_ToEepromResume:
	b2 = 0
	do	; liest die 64 Bits der ROM-Daten ins Scratchpad (Byte 8 bis 71)
		OwIn OwPin,OwNoResetBitPu,(bit0,bit1)
		OwOut OwPin,OwNoResetBitPu,(bit0)
		if bit0 = bit1 then
			@ptrInc = 2		; Bit = Kontrollbit = Bit-Kollision
			b2 = 1
		else
			@ptrInc = bit0	; Bit != Kontrollbit = OK
		endif
	loop until ptr > 63

	ptr = 0
	b1 = 1
	do
		bintoascii @ptr,b41,b42,b43
		sertxd (b43)
		pause 5
		inc b1
		inc ptr
		if b1 > 8 then
			b1 = 1
			sertxd ("/")
			pause 5
		endif
	loop until ptr > 63
	sertxd (13,10)
	pause 1000
		
	if b2 != 0 then			; da oben hat's Probleme gegeben (an bit=2 erkennbar)
		ptr = 64
		do
			dec ptr
			if @ptr = 2 then
				@ptr = 1
				OwOut OwPin,owresetbefore,(OwSearchRom)
				b1 = ptr
				ptr = 0
				do
					OwIn OwPin,OwNoResetBitPu,(bit0,bit1)
					OwOut OwPin,OwNoResetBitPu,(@ptrinc)
				loop while ptr <= b1
				goto Ow_ToEepromResume				
			endif
		loop until ptr < 1
	endif
	return
The @westaust55-program read all 6 DS18B20-Devices very well.
But my stinky-program read only 2 lines and they are mutilated.
I know the processing of "normal" data records. But that is here is not to.
Is there a time-Problem?
Please give me a Little tutorial.
Thank you!
Harald from today sunny Vienna

Addendum-1: Why is always in Byte 2 of Device-ROM-Data a Bit-Collision? Strange Thing!
Addendum-2: If I "0 then if b2! =" And the corresponding "endif" delete the line, then it works. But still the thing would me interested with the bit errors.
 
Last edited:

westaust55

Moderator
Have you read through the Maxim application note for 1-Wire Search Algorithm?>
http://www.maximintegrated.com/en/app-notes/index.mvp/id/187

This explains the principles for performing a search.

Both hippy and I developed 1-wire search routines for the PICAXE in parallel.
As I recall my later work was based more upon the method used initially by hippy as it resulted in smaller program space requirements.
Reading back at the first threads in my 1-Wire Netowrk thread, trying to use the code exactly as per the Maxim examples does not store sufficient clash information and if searching for more than 2 devices then the routine fails. I corrected this by setting up a 64 bit clash register using scratchpad memory.

Sorry but I do not have time to write further explanations for you at this time.
 

HaraldWien

New Member
First thank you for the answer.
On your basic-program my program now work well.

I wish you and all others a fine week!
Harald

Addendum:
My problem is, i did not understand, how this picaxe-program-part "Proceed" works.
The "goto Cont_Search" Command outside the do-loop-construct makes me crazy.
It must have something to do with the stack logic.
Too many devices are detected, perhaps there is a stack Overflow. Or Not?
I was wondering how many devices the tests were performed.
 
Last edited:

westaust55

Moderator
The test routine to find what 1-Wire devices are present must test a total 64 bits for a single serial number.

For each bit there can be three states in the program code, 0 or 1 if all present devices have the same bit sequence thus far and all present are the same for the current serial number bit, or I use a value of 2 to record a clash (when the 1-Wire device returns the ID_bit and ID_Compliment_Bit with the same value )which means we must later return to this same point in the sequence of bits and follow the alternate &#8220;branch&#8221;.

For one device, there would only be 64 tests to perform but as more devices are present, the maximum could be 2^64 = 18446000000000000000 (a very big number).
However with the tree structure and by using the values 0, 1 and 2 we only need to keep track of 64 bits of information at any time.

Yes in the last main DO&#8230;LOOP structure, the program is searching for previous clash flags and when one if found it follows the same bit pattern to the point of the bit_clash and then branches out of the DO&#8230;LOOP back to the Cont_Search: label the continue along the alternate &#8220;Branch&#8221;.
 

HaraldWien

New Member
Yeah, this is a other level as

select W1.FAMILY, W1.CRC8, W1.TEMP from W1NET
where W1.FAMILY = :family_cd
order by W1.FAMILY, W1.CRC8;

;-)
 
Top