Dallas 1-wire
Scott Salzman
Posts: 6
I'm new to the microcontroller arena and I'm having trouble finding Dallas 1-wire examples for the SX·anywhere.· I have searched this forum, sxlist.com, the SX download area on Parallax's site, the SX Plus kit books, etc.· I read about people who were using 1-wire devices on the SX and code for Basic Stamps and PIC processors, but no code for the SX.· Could anybody point to some examples?
Specifically, I am trying to read a DS1820 temperature sensor.· Eventually I will need to read two sensors, but not necessarily on the same bus.
Thanks!
Scott [noparse]:)[/noparse]
Specifically, I am trying to read a DS1820 temperature sensor.· Eventually I will need to read two sensors, but not necessarily on the same bus.
Thanks!
Scott [noparse]:)[/noparse]
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
I am getting a valid presence detect code (%10) on reset, but either the write byte or the read byte code does not seem to be working.· (I have not figured out which yet.)· I reviewed the timing of both routines and made some modifications to·the read code based on the DS1820 data sheet, but I am still getting all high bits.· (The data sheet recommended reading the bit from the 1-wire device·near the end of the 15us read slot which starts on the falling edge of the read slot generate by the host.· The code posted was reading it after the 15us time slot, but not by much.)
I have also tried two different DS1820s just to make sure I hadn’t blown the test chip or something.
What am I missing?
DS1820 data sheet: http://info.hobbyengineering.com/specs/ds18s20.pdf
Attached is my modified version of Jon's code.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
Post Edited (Jon Williams) : 2/7/2005 8:00:18 PM GMT
with my attempts at using the 1-Wire stuff.
Before issuing the Read ROM command do you have to issue a Skip ROM command first?
The descriptions and flow charts in the chip documentation are not clear about this.
It certainly would be easy to try sending the 0xCC, then the 0x33...
This entire discussion points out one "cost" of using many 1-Wire devices in a multi-drop
situation; you need some way to read the addresses of each device you want to use
so you can put those address in the code.· I am at the stage of being able to read the
devices one-at-a-time so I can code the correct addresses into the "real" program I am writing.
I will be watching this thread, and will post any progress I have.
Thanks,
Jim Greenhaw
Thanks for the info from Dallas Semi. I was a bit confused at your timing compared to what the data sheet was telling me. I did try the "official" timing first and it didn't work. That's why I tried changing it, which still didn't work. Shoot, I thought I was on to something there!
Jim,
Sending a skip rom before the read rom command didn't seam to make any difference for me. I think you are much further along than I am because I can’t get anything out of the chip except a valid presence pulse. I’d be perfectly willing to put the sensors on different buses if I could even get them to work with the skip rom command.
I know I’m missing something obvious, I just can’t figure it out yet!
Thanks,
Scott [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
what did it... ;-)
Here are some things I did/found out.
I set the timing up as in Jon's posting.· The only critical time delay appears to be
the 5 uS at the beginning of the read cycle.· However, I used values from 2 to 15 uS
and they all worked.· I settled on 3 since the documentation says "... at least 1", and
you must sample the line before 15us after the starting low transtion (I'm using 13uS)...
I think that my reset and writing timing was always OK, and I suspect yours is too.
You may even be reading it correctly, but there are some catches.
For one thing, your debugger may be getting in the way; only a possibility.
Another thing that I did was to add a 10k pull-up to the one-wire data line.
This improved the rise-time of the signal from 5uS to essentially 0uS.· Putting this
resistor in or taking it out did not break it once I got it working, but it removes a lot
of uncertainty about what the signal looks like.· Try it and see what happens...
BTW, using or not using the skip rom command did not make any difference when issuing
the read rom command, however, I did need to use it to start the conversion, or
read the scratchpad ram.
Another thing is that you need to send the reset sequence before every command.
I had tried issuing a reset command then looped on a bunch of read rom commands.
Only the first one worked (since I didn't issue reset again) and I think the correct
reading may have scrolled of the screen before I could read it!
I hope some of this helps; there IS light at the end of the tunnel...
I have attached the C source for the program I tested with.· It isn't pretty, but
you should be able to follow what it does.
Jim
Bean.
Terry's correct: the 1-Wire bus absolutely requires a pull-up. My friend at DalSemi suggests about 1K per volt on your pull-up, so for a 5v system use 4.7K; drop it down if you're using 3.3v.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
Dallas, TX· USA
but it seemed too large of a value, so I added the 10k.
However, as I mentioned above, when I remove the "extra" pull-up, and only
used the built-in one, it still works fine...
I also just noticed a couple of things in your program Scott.
The first has to do with this pull-up resistor business.· You are using RA.0
for you 1-wire data bus, but "intentionally" do not enable its built-in pull-up resistor.
You should probably only enable the one(s) you are using, PLP_A = %1110, and leave
the rest alone, and/or use an external resistor.
Second, even though I am finding the timing requirements to actually be fairly loose,
since you're using a 4MHz clock, it only takes 4 instructions (in turbo) to use up
one of your precious microseconds.· I suspect that the PAUSEUS function takes this
into account, but you may need to account for some of the delays in your code around
the PAUSEUS calls by reducing the pause times.· If none of this other stuff works
maybe you can try a faster clock to eliminate some of the uncertainty.· I suspect you
are right on the edge of having this work...
It is exciting to be past the hurdle of talking to the chip so now I
can actually use it for something.
Thanks for all of the comments,
Jim
I've tried the sxb file and I'm having the same results as Scott. I get a good presents but the Rom returns all F's. I've tweaked the timing up and down on the readbyte sub till I'm about to SCREAM!...
I do know that I have a good ds18s20 device as it works find on another board, though this board does not return me the rom just the temp.
I've got my pullup (5K) on the demo board.
Here is a snip of the read sub:
_OWRDBYTE:
regAddr = __PARAM1 ' save return register
temp2 = 0 ' clear work var
FOR temp3 = 0 TO 7 ' get eight bits
temp2 = temp2 >> 1 ' shift bits (for LSB first mode)
LOW DQ ' pull DQ line to 0
PAUSEUS 5 ' hold 5 uS ***** (5 to 2)
INPUT DQ ' release DQ to Hi-Z
PAUSEUS 10 ' wait for sample window ******* (10 to 6) pg 18
temp2.7 = DQ ' sample OW bit
PAUSEUS 45 ' finish slot and recover ******* (55 to 60)
NEXT
All else in the routine is as posted. Any pointers would really help my hair pulling as there isn't much left...
Regards,
JJ
READROM ONLY works if there is 1 device on the bus.
From reading the datasheets of different devices it seem that this is the usual sequence:
Reset
ROM command
Device command/response
A reset must be send before each ROM command.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Check out· the "SX-Video Display Module"
www.TerryHittConsulting.com
·
Sorry, let me describe my test environment:
SX Demo Board with SX28DP
One DS8S20 One Wire Temp sensor.
Code as follows:
' =========================================================================
'
' File...... read_ow_rom.sxb
' Purpose... Read Dallas 1-Wire 64-bit ROM code
'
' =========================================================================
'
' Program Description
'
'
'
' Device Settings
'
DEVICE SX28, OSCXT2, TURBO, STACKX, OPTIONX
FREQ 4_000_000
'
' IO Pins
'
DQ var RA.0 ' 1-Wire bus (4.7k pull-up)
'
' Constants
'
' 1-Wire constants
ReadROM CON $33 ' read ID, serial num, CRC
'
' Variables
'
idx VAR Byte ' loop counter
owByte VAR Byte ' byte for OW work
owSerial VAR Byte(8) ' OW serial number
regAddr VAR Byte ' register address
temp1 VAR Byte ' work vars
temp2 VAR Byte
temp3 VAR Byte
WATCH owSerial, 64, uhex
WATCH owByte, 8, uhex
'
INTERRUPT
'
' =========================================================================
PROGRAM Start
' =========================================================================
'
' Subroutines / Jump Table
'
OWRESET:
GOTO @_OWRESET
OWWRBIT:
GOTO @_OWWRBIT
OWWRBYTE:
GOTO @_OWWRBYTE
OWRDBIT:
GOTO @_OWRDBIT
OWRDBYTE:
GOTO @_OWRDBYTE
'
' Program Code
'
Start:
PLP_A = %0011 ' enable pull-ups
PLP_B = %00000000 ' .. except RA.0 and RA.1
PLP_C = %00000000
Main:
' check temp sensor
Scan_DQ:
gosub OWRESET, @owByte ' reset and sample presence
IF owByte = %10 THEN GoodPresence ' good presence detection
goto NoGoodPresence
GoodPresence:
\ nop
NoGoodPresence:
\ nop
break
Show_SN:
gosub OWRESET, @owByte ' reset device
gosub OWWRBYTE, ReadROM ' send read rom command
FOR idx = 0 TO 7 ' read serial number
gosub OWRDBYTE, @owByte
owSerial(idx) = owByte
NEXT
Fini:
break
pause 10
GOTO Main
'
' Page 1 Code
'
Page_1:
ADDRESS $200
P1_Start:
' Use: OWRESET @testVar
' -- generates 1-Wire reset
' -- samples for line short and presence
' -- returns reset result in 'testVar'
' -- %00 = line short
' -- %01 = bad connection (not likely return value)
' -- %10 = good presence
' -- %11 = no device connected
_OWRESET:
regAddr = __PARAM1 ' save return register
temp1 = 0 ' clear work var
LOW DQ ' pull DQ line to 0
PAUSEUS 500 ' hold 500 uS
INPUT DQ ' release DQ to Hi-Z
PAUSEUS 5 ' wait 5 uS
temp1.1 = DQ ' test for short
PAUSEUS 70 ' wait for presence
temp1.0 = DQ ' sample presence
PAUSEUS 425 ' wait 150 uS (recovery) ******* (150 to 425) pg 17
__RAM(regAddr) = temp1 ' return bits to caller
RETURN
' Use: OWWRBIT owBit
' -- writes 'owBit' to 1-Wire bus
_OWWRBIT:
temp1 = __PARAM1 ' save bit to write
LOW DQ ' pull DQ line to 0
IF temp1.0 = 1 THEN OWwrite1 ' write 1 slot
goto OWwrite0
OWwrite1:
PAUSEUS 5 ' hold 5 uS
INPUT DQ ' release DQ to Hi-Z
PAUSEUS 65 ' complete slot/recovery
goto OWwriteEnd
OWwrite0:
' ELSE ' write 0 slot
PAUSEUS 60 ' hold 60 uS
INPUT DQ ' release DQ to Hi-Z
PAUSEUS 10 ' complete slot/recovery
OWwriteEnd:
' ENDIF
RETURN
' Use: OWWRBYTE owByte
' -- writes 'owByte' to 1-Wire bus
_OWWRBYTE:
temp2 = __PARAM1 ' save byte to write
FOR temp3 = 0 TO 7 ' write eight bits
gosub _OWWRBIT temp2.0 ' write LSB
temp2 = temp2 >> 1 ' prep for next bit
NEXT
RETURN
' Use: OWRDBIT @owVar
' -- generates read slot on 1-Wire bus
' -- returns 0 or 1 to owVar.0
_OWRDBIT:
regAddr = __PARAM1 ' save return register
temp1 = 0 ' clear work var
LOW DQ ' pull DQ line to 0
PAUSEUS 5 ' hold 5 uS
INPUT DQ ' release DQ to Hi-Z
PAUSEUS 10 ' wait for sample window
temp1.0 = DQ ' sample OW bit
PAUSEUS 55 ' finish slot and recover
__RAM(regAddr) = temp1 ' return bit to caller
RETURN
' Use: OWRDBYTE @owVar
' -- reads eight bits from 1-Wire bus
' -- returns in 'owVar'
_OWRDBYTE:
regAddr = __PARAM1 ' save return register
temp2 = 0 ' clear work var
FOR temp3 = 0 TO 7 ' get eight bits
temp2 = temp2 >> 1 ' shift bits (for LSB first mode)
LOW DQ ' pull DQ line to 0
PAUSEUS 2 ' hold 5 uS ***** (5 to 2)
INPUT DQ ' release DQ to Hi-Z
PAUSEUS 6 ' wait for sample window ******* (10 to 6) pg 18
temp2.7 = DQ ' sample OW bit
PAUSEUS 60 ' finish slot and recover ******* (55 to 60)
break
watch temp2,8,ubin
NEXT
__RAM(regAddr) = temp2 ' return result to caller
RETURN
GOTO P1_Start ' error if Pg0 overruns Pg1
'
' Page 2 Code
'
Page_2:
ADDRESS $400
P2_Start:
GOTO P2_Start ' error if Pg1 overruns Pg2
'
' Page 3 Code
'
Page_3:
ADDRESS $600
P3_Start:
GOTO P3_Start ' error if Pg2 overruns Pg3
Results from watch of variables:
After each reset system responds with %10
After readbyte executed after the $33 sent the system responds with $FF which builds into a serial no of all $F's
DS temperature sensor is known good as well as the sx chip.
Jon,
If this codes works with the Beta Version of the compiler maybe you could post a copy of the Binary file that I could load with my Ver 3.0 using the released patch 1.10 dated 12/15/04.
Regards,
JJ
Move your BREAK outside of the FOR...NEXT loop. Put if AFTER the NEXT. The break will kill alot of time, messing up the timing.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Check out· the "SX-Video Display Module"
www.TerryHittConsulting.com
·
I have moved the break out of the loop and still receive all F's.
I'm still looking for my trouble. Thanks for your input...
JJ
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Think you’re a Big-Shot?
Try ordering someone else’s dog around.
·
Jon K. Zachary
Katy, TX
I'm still not getting this to work. Jim had a great comment about the speed the chip was running at (4 MHz instead of 50 MHz). Unfortunately changing it to 50 MHz didn't seem to affect anything. I'm still getting all F's. (That means I flunked right?) I had already tried putting all the breaks in the main program (as Bean alluded to), but I never had them in critical timing sections anyway. Still no go. I have changed all my timing back to the Dallas engineer recommended timings. Nothing (except F’s that is). I am as frustrated as Jon Z. on this! What are we missing!!?
Scott [noparse]:)[/noparse]
Finally I get to give something back to the group!!!!!
I finally got the code to work!!!!!
There seems to be a problem with the SXB compiler.· In the code where the 'read rom' command it passed to the ds device was failing because the nested soubroutine call
'gosub _OWWRBIT temp2.0'
The value from temp2.0 was not being passed into the '__param1' This value reflected the same value passed in from the parent subroutine :
_OWWRBYTE:
· temp2 = __PARAM1
Where·__PARAM1 is the read rom command 33x or 110011b.··Therefore the code was writing a command of FFx as the bits were not shifted.· Take a look at the code and you should see what I'm referring to.
I would say that the SXB compiler has a problem here, and may be fixed with future versions.· This may be why Jon's code was running.· I understand that he was using a beta version of the sxkey.·
Hey Jon could I get a copy of this bet version????
As far as the reading of the results from the DS device I had no adverse problems and the values delivered in the initial program worked.· The OWRDBYTE routine didnot use nested subroutine calls.
I've attached the resulting code "SXB" for you to view and coment...
Regards,
JJ
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Think you’re a Big-Shot?
Try ordering someone else’s dog around.
·
Jon K. Zachary
Katy, TX
Is there actually any reason to ever read a bit or write a bit to the 1-Wire bus alone?· All the commands and receipts·for the device I have are bytes or multi-bytes.· I simplified my program by eliminating the two bit routines and just kept the byte ones.· Cleaner, less space, and eliminates the problem JonJon found.
Scott [noparse]:)[/noparse]
·
All the other calls have the comma, I guess it was just a typo. But I missed it myself.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Check out· the "SX-Video Display Module"
www.TerryHittConsulting.com
·
Nice to know that there is nothing wrong with the compiler, just a missing comma. I too must have been in a comma, er ah coma... Is is so very nice to have more eyes looking at something....
I might suggest that the compiler pick up these types of errors...
Scott,
Writing one bit is used in search rom routines, et al to find all the devices on a 1-wire net. Take a look at some of the application notes available from Maxim on line. Have fun...
JJ
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Think you’re a Big-Shot?
Try ordering someone else’s dog around.
·
Jon K. Zachary
Katy, TX
Scott [noparse]:)[/noparse]