I’ve modified Paul Stoffregen’s OneWire library (version 2.2) to support OneWire overdrive. The credit should go mostly to Patrik Jonsson who implemented most of this onto an older version of Paul’s library. All I did is merge the two libs and fix some timing issues. Patrik Jonsson’s version can be found here.
I figured I’d share this with you and hope that some other people will test it and contribute to an even more stable overdrive communication. I also hope that Paul will merge this back into his next version if it proves to be stable.
General info about OneWire overdrive
Overdrive mode is about 6-7 times faster than normal mode. This is handy if you have many sensors that need frequent polling. With overdrive, a DS2408 (8 channel switch) or DS2413 (2 channel switch) can be polled in roughly 1.1ms, compared to ~7ms without overdrive. Non-overdrive and overdrive slaves can be operated on the same bus, but it needs some consideration (see separate section).
How overdrive works
Not all OneWire slaves support overdrive. If it does, a slave can be put into overdrive mode in two ways, namely:
0x69(Overdrive Match ROM command) in normal speed followed by the 8-byte ROM identifier in overdrive speed. This is done by the new function
select_and_overdrive(or of course, manually).
0x3c(Overdrive Skip ROM command) in normal speed. This immediately puts all overdrive capable slaves on the bus into overdrive mode.
Once a slave is in overdrive mode, all subsequent communication must take place at overdrive speed (especially future Overdrive Match ROM commands must be sent at overdrive speed). The only way to take a slave out of overdrive mode is performing a normal speed
How do I know which slaves are overdrive capable?
Perform a Overdrive Skip ROM command followed by a
search at overdrive speed. Only overdrive capable slaves will answer to the search.
Non-overdrive and overdrive devices on the same bus
Communication to a non-overdrive slave need to begin with a normal speed
reset, which will take all overdrive devices out of overdrive mode. Therefore, at the end of communication with a normal speed slave, you should execute another normal speed reset, followed by an Overdrive Skip ROM command (at normal speed) to put all overdrive devices back into overdrive mode.
See OneWire.h and the example for details. Basically, most commands (
select, read, write, read_bytes, write_bytes, reset, skip) now require an additional
bool overdrive parameter, indicating whether the command should be executed at overdrive speed or not. Here’s the quick list:
Development and Testing
OneWire overdrive is very timing sensitive (we sometimes need timings in the single microsecond area). I’ve optimized the timings to work with an Arduino DUE, which has a 84MHz processor - it’s possible that slower Arduinos will need slightly different (i.e. shorter) delays because they will need more time to process the “overhead” of communication and have less time for waiting. Once we understand the timings and processing overheads a little better - with your testing feedback -, we can adjust the lib’s timings, perhaps even to be based on the processor clock frequency.
The timings are found in structs in OneWire.h
I’ve tested the library with an Arduino DUE on a OneWire bus of 80meters and four overdrive slaves (master at 0, client1 at 20 meters, client2 at 40, client3 at 60 and client4 at 80 meters distance - the wire was a very cheap unshielded 0.2mm2 ISDN wire) over a period of 24 hours with about 800 read/write commands per second. It was relatively stable (see error checking and correction section). My data-bus was powered by the DUE’s 5V outlet with a 4.7k Pull-Up resistor. This lead to a ~3.5V input voltage on the DUE’s analogue in port, which is slightly out of the DUE’s specs - this was more stable than using the 3.3V output for long bus distances. A higher pullup resistor was suggested by Dallas for long buses, which would potentially reduce the input voltage further. Note: This wiring could damage your DUE.
Error checking and Correction
On average, about .01% of all commands failed (this is about 1 command every minute). However, the distribution of failures was very uneven. Sometimes I had no errors for hours, sometimes I just received a single CRC error, sometimes the bus kind of “locked up” and half to all following commands failed. In my testing, I implemented a “full reset” routine, to be triggered after 5 consecutive errors, which performed 2 normal speed resets with 5ms of delay in between them, before executing another Overdrive Match ROM command. This helped to get the slaves working again - once, a few of those resets were necessary. It might also be effective to perform a very long reset (i.e. pulling the bus to low for 5ms or so), though I haven’t tested this.
All in all, it’s crucial that you check the responses of your slaves (for DS2413 / DS2408, writings: do you get a proper 0xAA back? readings: is the read-back correct and/or does the CRC16 match). This is of course true for both overdrive and non-overdrive communication.
Debug the timings
It’s important to know what kind of errors you get.
- if you get only 1s as answer (the answer-byte is 0xff), it’s likely that the slave hasn’t received your command or thinks the command is not finished yet. This means that the slave won’t answer at all, never pull the bus to low, and the Arduino will only read 1s. Also, your tW1L might be too long.
- if you mistake some 1s for 0s, your tMSP is probably too short (or your pull-up resistor too slow).
- if you mistake some 0s for 1s, your tMSP is probably too long.
Hope some of you find this helpful,
OneWire.zip (12.9 KB)