How to dance a 64 bit One-Wire address through a Propeller, DS18B20 digital the
Hello all,
I've been using Micah Dowty's SpinOneWire-test.spin object to work with DS18B20 digital thermometers.· Dowty's program works great and displays the unique 64-bit serial code of each DS18B20 onto a TV screen.· My own program was to simply call up·his temperature reading method and pass each 64-bit serial code to it one thermometer at a time.· Problem is, the Propeller is a 32 bit device.· Although I can (kinda) see how Dowty's program reads the 64-bit serial code (calling up some assembly lingo routine)·and I can (kinda) understand how he breaks it up so it can be displayed on TV, I can't understand how he gets way with apparently passing the entire 64-bit serial code to his temperature reading method.· It seems to me that his addr variable is passing the entire code.· What am I missing here?
I've been using Micah Dowty's SpinOneWire-test.spin object to work with DS18B20 digital thermometers.· Dowty's program works great and displays the unique 64-bit serial code of each DS18B20 onto a TV screen.· My own program was to simply call up·his temperature reading method and pass each 64-bit serial code to it one thermometer at a time.· Problem is, the Propeller is a 32 bit device.· Although I can (kinda) see how Dowty's program reads the 64-bit serial code (calling up some assembly lingo routine)·and I can (kinda) understand how he breaks it up so it can be displayed on TV, I can't understand how he gets way with apparently passing the entire 64-bit serial code to his temperature reading method.· It seems to me that his addr variable is passing the entire code.· What am I missing here?
repeat i from 0 to MAX_DEVICES-1 debug.out(13) if i => numDevices ' No device: Blank line repeat 39 debug.out(" ")
else addr := @addrs + (i << 3)
' Display the 64-bit address
debug.hex(LONG[noparse][[/noparse]addr + 4], 8) debug.hex(LONG[noparse][[/noparse]addr], 8) debug.str(string(" "))
if BYTE[noparse][[/noparse]addr] == ow#FAMILY_DS18B20 ' It's a DS18B20 temperature sensor. Read it. readTemperature(addr)
else ' Nothing else to show... debug.str(string(9,9))
PRI readTemperature(addr) | temp, degC, degF '' Read the temperature from a DS18B20 sensor, and display it. '' Blocks while the conversion is taking place.
ow.reset ow.writeByte(ow#MATCH_ROM) ow.writeAddress(addr)
Comments
when it calls up the method ow.writeAddress(addr) in a different (SpinOneWire) object, that method uses longmove, which goes to the address of addr and starts heaving huge numbers of bits around.
In other words, although it looks like only the value of addr is being passed, what's really being passed is the value of addr and its memory location. When the ow.writeAdress method gets hold of the passed addr, it then grabs the address of addr and starts looking at the start of the addr address and then moves around collecting all 64 bits of the DA18B20's unique code which is loaded in that zone of memory.
At least I think that's what it's doing. True?
Mark
Right. It's pass-by-reference rather than pass-by-value. In C, this would be like passing a pointer to a large data structure. You only have to pass in the pointer, but the routine you're calling can use that pointer as a destination for writing a larger return value.
So, the parameter you pass to writeAddress() is the address of a grouping of 2 longs (low and high). You can do this in multiple ways, but the easiest way is to treat the two as an array:
--Micah
Thanks to your program using the DS18B20, and how easily I got it to work on a TV, I got inspired to seriously work with this Propeller chip. I can't thank you enough for posting that object and for confirming my comment, above. Learning how it works continues to be fun and keeps me going on the other routines.
a thousand thanks,
Mark
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
It might be the Information Age but the Eon of Ignorance has yet to end.