Skip to content
This repository has been archived by the owner on Jun 9, 2018. It is now read-only.

Presence pulse #4

Closed
andrewradke opened this issue Feb 10, 2016 · 2 comments
Closed

Presence pulse #4

andrewradke opened this issue Feb 10, 2016 · 2 comments

Comments

@andrewradke
Copy link

I ran into a problem of the presence pulse not being seen by a LinkUSB master.

By adding a Serial.print right before the beginPresence_() call I found is that I was already at 8µs on an ATmega328P and therefore significantly more by the time the bus was brought low inside beginPresence_(). If I reduced PresenceWaitDuration too much is was easy for PresenceWaitDuration - (micros() - now) to be a negative number and therefore end up actually being almost 2^32µs and effectively never trigger. If I didn't reduce it enough the presence pulse would become unreliable.

After reading multiple datasheets and specifications it seems that the time from the end of the reset until when a device brings the bus low as a presence pulse is not well defined. In fact in my reading of the Maxim documents for 1-wire specification I couldn't see the delay defined at all (though I may have missed it somewhere).

The ds18b20 datasheet said: "When the DS18B20 detects this rising edge, it waits 15µs to 60µs and then transmits a presence pulse by pulling the 1-Wire bus low for 60µs to 240µs." Also reading documents about working with long cable lengths in the past (I've supported 600m lines using LinkHubE masters with multiple ds2438) 60µs can be close to the signal propagation time over that distance.

So from my reading and experimentation I think the delay should be removed and the presence pulse should occur immediately. In effect we are going to be at around 10µs plus edge detection time plus signal propagation time after the end of the reset. Also, using the ds18b20 as a guide a PresenceDuration of 200µs seems better than 300µs. Anything over 60-70µs will do and 200 is in the range of probably the most used 1-wire device. I may test with 100µs at some point but it probably isn't worth worrying about.

If this seems reasonable to you here is my suggested diff:

17,18c17,18
<   const unsigned long PresenceWaitDuration = 30;
<   const unsigned long PresenceDuration = 300;

---
>   // const unsigned long PresenceWaitDuration = 30;
>   const unsigned long PresenceDuration = 200;
339c339,340
<           setTimerEvent_(PresenceWaitDuration - (micros() - now), &OneWireSlave::beginPresence_);

---
>           // setTimerEvent_(PresenceWaitDuration - (micros() - now), &OneWireSlave::beginPresence_);
>           beginPresence_();   // we will be a few micros on already so don't wait to signal presence
@JFLaroche
Copy link

Hello,

Same kind of problem here using an Arduino pro mini at 16MHz and a breadboard mockup.
Using a logic analyser, I have compared the streams between a true ds18b20 and the Arduino slave.
With the PresenceDuration equal to 300, the Arduino slave waits approx 60µs before sending a 30µs pulse.
The true ds18b20 waits approx 25µs before sending a 75µs pulse.
By changing the PresenceDuration to 120, the Arduino slave waits approx 25µs before sending a 75µs pulse.

Regards

neuoy added a commit that referenced this issue Apr 30, 2017
@neuoy
Copy link
Owner

neuoy commented Apr 30, 2017

I've changed wait delay to 15µs (from which 10µs are removed as an estimate of the computations overhead, so the actual delay should be very short) and presence duration to 200µs. I'm not too comfortable with the delay reduction, because we need all devices to notice the bus is high level before pulling it low, but with this value it seems to work fine in the quick test I've made.

@neuoy neuoy closed this as completed Apr 30, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants