6

A commonly used library is the DallasTemperature library, used to access DS18B20 sensors on a 1-Wire bus. When creating a DallasTemperature object you pass a reference to a OneWire object. OneWire can create a 1-Wire bus on pretty much any port of an Arduino.

An example of this is like so:

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

However, there are some issues with using OneWire to drive a 1-Wire bus, mainly around driving longer bus lengths, dealing with shorts, and other errors.

There is a commonly available chip called the DS2482-100 that can drive longer busses (hundreds of feet), deals with shorts and other errors. It is also less CPU heavy and it deals with a number of the slower aspects of 1-Wire.

For this reason, I would like to be able to pass a reference to a library that I have created instead. Currently, I am doing this by:

  • Calling the library OneWire
  • Replicating all the methods called by the DallasTemperature library
  • Swapping out the OneWire library for mine

This is relatively messy. I would ideally like to be able to pass either a reference to my library or a 1-Wire library, so that people can chose which interface to use.

How would I go about doing this?

  • This might be quite C++ and more appropriate for StackOverflow. But, in defence of this question, this is a very specific Arduino/hardware library, and in trying to solve it, I have come up against some other issues (arduino.stackexchange.com/questions/322/…) that seem specific to the Arduino environment. – Cybergibbons Feb 20 '14 at 14:40
  • What do you mean by "there are some issues with using OneWire like this"? How should it then be used actually? I find it hard to understand how the way to instantiate an object as in your code cn have a bad impact as you describe. – jfpoilpret Feb 20 '14 at 18:46
  • Clarified in original question. – Cybergibbons Feb 20 '14 at 19:18
  • Can't you just use the DallasTemperature library exclusively? – Heiko Rupp Dec 4 '15 at 14:26
4

The typical way to achieve what you want would normally be to create your own subclass of OneWire class and override the methods you need to change, then pass a pointer to an instance of your class to the DallasTemperature constructor.

However, for this to work, the OneWire class must have been developed with extensibility (subclassing) in mind, i.e. use virtual methods that you can override.

Unfortunately, a quick look at OneWire.h shows that no method is virtual in there.

So that means in the end you will have to perform some hacks, just as you do now.

What you could potentially do (that's still a hack, but maybe a bit less dirty) is:

  • replace OneWire.h to make all methods virtual (at least those you need to override)
  • keep the original OneWire.cpp that should still compile with the newly adapted header file
  • create a new MyOneWire.h / MyOneWire.cpp to define your own OneWire subclass that overrides all necessary methods as you want

Then you can pass either a OneWire or a MyOneWire instance to DallasTemperature constructor.

NB: when I see my answer, this makes me think your question is more a general C++ question than an Arduino-related one.

  • Thanks. I think your hack is cleaner - and doesn't involve moving files in and out of the library folder. I'm coming to the realisation that the C++ aspects of Arduino aren't really used to great effect. Thankyou for a great answer - I will leave open for a while anyway. – Cybergibbons Feb 20 '14 at 21:08
  • 1
    I should add one point to the defense of OneWire library authors: there can be a reason to not use virtual methods in a class: performance of method calls and code size. I haven't tried yet to measure such impact on Arduino (on a PC this is of course negligible and unnoticeable). – jfpoilpret Feb 20 '14 at 21:12
0

The DS2482-100 is an I2C-to-1-Wire®bridge device that interfaces directly to standard (100kHz max) or fast (400kHz max) I2C masters to perform bidirectional protocol conversion between the I2C master and any downstream 1-Wire slave devices.

It uses a higher level protocol over I2C which does not directly match the bit-banged OneWire interface above.

A possible solution is to "only" reuse the OneWire interface and reimplement it. Sub-classing will not work as the member functions are not virtual. Unfortunately this will not work directly due to error handing, timing, etc. The DallasTemperature class will also need modifying.

Please see the DS2482-100 product description and protocol.

To achieve your goal of allowing either bit-banged or DS2482-100 based 1-Wire master would require 1) an abstract interface (class) used by 1-Wire master device drivers, 2) sub-classes for each implementation master variant.

As the 1-Wire protocol has a number of common commands a delegation pattern is more useful. Please see the Cosa OWI::Driver and DS18B20 device driver for an example of the delegation pattern.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.