OneWire timing - DS18B20
Moderators: adafruit_support_bill, adafruit

OneWire timing - DS18B20

by RyanPierce on Fri Oct 26, 2012 1:20 pm

I'm trying to build a proportional thermostat that dims AC devices on an Arduino Uno. I'm using simple triac dimming; an interrupt tells me when I have a zero crossing of the AC wave, and based on the percent I want to dim the device, I know I need to wait between 0 and 8333 microseconds (60 Hz AC, so 120 half phases) before firing the triac.

8333 us isn't a lot to play with.... I need to get temperatures from multiple DS18B20 probes. From what I can gather, 1-Wire operations require a reset (480 us + 480 us for devices to respond) and at least 60 us to clock a bit in or out. In order to read the scratchpad of one DS18B20 with multiple DS18B20's on the bus, I've got to do:

1. Reset (960 us)
2. Send Match ROM (9 bytes = 4320 us)
3. Send Read Scratchpad (1 byte = 480 us)
4. Read 9 bytes (4320 us)

Total: 10,080 us

In other words, if my math is right, it's longer than the AC cycle I'm trying to dim. Blocking for 10 ms to read the scratchpad isn't acceptable. So it seems like what I need to do is modify or rewrite Paul Stroffregen's OneWire library based around a polling loop. I would loop and check if it's time to fire the Triac, check if it's time to bang a OneWire bit, etc. (And I need to throw in the PID calculation, output to an LCD panel via I2C, possible input/output from serial....)

So I'm wondering:

1. It seems like the timing on banging a OneWire bit must be very precise. The OneWire library code disables interrupts. I don't have a problem disabling interrupts for, say, 60 us, and delaying my check for firing the triac by that much. Compared to the AC sine wave, it isn't a lot of error. But I'd like to write code that would bang a bit in or out, check to see if something else needed to be done (e.g. the triac), bang another bit, etc. As the master determines the clocking of bits in or out, I'd think that some variable delay between individual bits would be acceptable. But what I can't find is an upper limit for that delay. What is the maximum time between reading or writing consecutive bits to a DS18B20 before the device gives up or considers this an error?

2. Has anyone done anything like this before?

Posts: 11
Joined: Thu Aug 23, 2012 7:12 pm

Re: OneWire timing - DS18B20

by adafruit_support_bill on Sat Oct 27, 2012 5:39 am

I moved this topic to "Microcontrollers". There are more low-level programming experts there.
User avatar
Posts: 32621
Joined: Sat Feb 07, 2009 10:11 am

Re: OneWire timing - DS18B20

by adafruit_support_mike on Sat Oct 27, 2012 6:30 pm

Page 9 of this datasheet:

..says you can suspend a transaction for any length of time as long as you leave the line HIGH. If you hold the line LOW for more than 480uS, all devices on the bus will reset.
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
Posts: 11329
Joined: Thu Feb 11, 2010 2:51 pm

Re: OneWire timing - DS18B20

by BruceF on Sun Oct 28, 2012 12:18 pm

Presumably you're not looking to use external hardware or you'd be looking at a 1-Wire master chip, but just in case...

I just saw an app note referenced at Dangerous Prototypes that might be of interest; give the problem to a UART and let it handle the low level timing issues for you. Clever implementation, I thought.
- Bruce
Posts: 213
Joined: Tue May 03, 2011 4:51 pm

Re: OneWire timing - DS18B20

by RyanPierce on Sun Nov 11, 2012 12:05 pm

For some reason, I didn't get a reply notification on this, and just now saw the responses.

I missed that part on Page 9 allowing for infinite recovery time occurring between bits. That's perfect. I think what confused me is that I was looking at the timing diagram on p. 16 showing a "MASTER WRITE "0" SLOT" of 60 us < Tx "0" < 120 us. I'd previously interpreted that as requiring the next bit to come within 120 us. Now I see that they're just saying that pulling the line down for a "0" can't be longer than 120 us, or there's a risk the devices will consider it a reset.

So far I've had success in extending the OneWire library to support calls returning in a minimal amount of time, where one repeatedly calls a poll() function until the I/O operation completes. The reset function saves a timer, and calls to poll() check the timer, so one isn't required to lock up the processor for nearly a whole millisecond. And reading and writing single bytes or strings uses a buffer within the class; each call to poll() clocks a single bit in or out. The result is that at most, the Arduino is blocked for about 80 us, so I can do other things like check the state of the timers for the AC dimming triacs. This is a pretty specialized application, so I don't know if anyone else cares, but if they do, I can make the source code available.

Posts: 11
Joined: Thu Aug 23, 2012 7:12 pm