Introduction: Arduino 1-wire Generic Client/Slave Device (Sensor)

Please read the Introduction and Step 2 of my instructable about how to build an Arduino 1-wire Display (144 Chars) in order to get more information about the situation and libraries available. As explained there we will use the OneWire-Hub library (OneWire slave device emulator) by orgua (pay attention there are other forks around) in order to build generic 1-wire devices (e.g. sensors) using an Arduino.

Step 1: Software

The most important thing is to make a device that can return basically any kind of value in a simple manner. Meaning that standard software can be used to read all the values directly (no conversation or binary manipulation needed). For that we need a very simple default 1-wire device that can return floats and is widely supported. The only choice I know of is the DS18B20 Thermometer (the DS2438 Battery Monitor is interesting and useful too but quite complex and thus slow among other drawbacks). The OneWire-Hub library contains an example called DS18B20_asInterface that does exactly what we need. It creates a bunch of DS18B20 of which every one represents one float value we want to return from our sensor(s). The restrictions here are the resolution and the values have to be in the range -55,0 ... 125,0. That can easily be achieved - in the worst case be rescaling - and is actually better than the values that can be represented by e.g. the DS2438 values (1.5 to 10V). Alternatively a bigger range of values can be set by using:

setTemperatureRaw(static_cast(value * 16.0f));

but reading and processing these values might not be supported by all software as it is out of specs.

What you have to be aware of is that initially the maximal number of slaves is restricted to 8 but can be changed in "OneWireHub_config.h" by increasing HUB_SLAVE_LIMIT up to 32. Also you have to be make sure to adopt ONEWIRE_TIME_MSG_HIGH_TIMEOUT if needed by your 1-wire network (e.g. x10), as explained in Step 2 of Arduino 1-wire Display (144 Chars). And to use the IDE Version >= 1.8.3 to compile and upload the code to your Arduino.

Here as an example the code of the device I build very recently. As I assume you not to use the same combination of sensors that I do I will not go further into details here, check the code and ask questions if you need help.

Step 2: Hardware

Basically anything you can connect to an Arduino can be used as your sensor of choice. The only restriction is that reading the sensor should be as fast as possible in order to have plenty of time left for the 1-wire communication to take place (confer Step 2 of my instructable about Arduino 1-wire Display (144 Chars) in order to get an example).

An example of possible hardware could be a weather station like e.g.:

Additionally or instead of you just might want to use the Arduino itself as your sensor. You can read more about that in my instructable about the Arduino Lesser Known Features - possible values are the source voltage and the internal temperature.

Here as an example an image of the device I build very recently. As I assume you not to use the same combination of sensors that I do I will not go further into details here, check the code and ask questions if you need help.

Step 3: Test the Device

Connect it to your network and check your software for all ROM IDs to be present and the values they return as temperature.

Step 4: Appendix: ATtiny85

Single devices (memory limitation) can also be done on an ATtiny85. This needs a few steps as we program the ATtiny85 using Arduino Uno as ISP with help of the Arduino IDE:

  1. use Arduino IDE >=1.8.3
  2. install ATtiny option to IDE
    1. File > Preferences > Additional Boards Manager URLs: http://drazzy.com/package_drazzy.com_index.json
    2. Tools > Board: ??? > Boards Manager...
    3. search for: "tiny" and install
  3. upload ISP sketch to an Uno
    1. File > Examples > ArduinoISP > ArduinoISP
  4. insert ATtiny85 to programming (zero-force) socket and wire it:
    1. Arduino Pin MOSI D11 to ATtiny Pin 5
    2. Arduino Pin MISO D12 to ATtiny Pin 6
    3. Arduino Pin SCK D13 to ATtiny Pin 7
    4. Arduino Pin Reset D10 to ATtiny Pin 1
    5. Arduino Pin GND to ATtiny Pin 4
    6. Arduino Pin VCC to ATtiny Pin 8
    7. (>=10uF cap on Arduino Uno RESET pin might be needed)
  5. select ATtiny85 (see picture):
    • Board: "ATtiny25/45/85"
    • Timer 1 Clock: "CPU"
    • B.O.D.: "B.O.D. Disabled"
    • LTO (1.6.11 + only): "Disabled"
    • Chip: "ATtiny85"
    • Clock: "8 MHz (internal)" (ATtiny85 and ATtiny84 compatible)
    • Clock: "16 MHz (PLL)" (alternative setting for ATtiny85 only)
    • Port: ???
  6. select Programmer:
    1. Tools > Programmer: "Arduino as ISP" (NOT "ArduinoISP" !)
  7. set fuse settings (clock, etc.):
    1. Tools > Burn Bootloader
  8. upload this code (programmer error LED needs to be off, else reset it)
  9. ATtinyX5 Pin Layout (ATtiny85):
    1. Pin 1: PB5 (RST)
    2. Pin 2: PB3 (A3) - optionally connected via 220ohm to 1<-TX
    3. Pin 3: PB4 (A2) - connected to 1-wire DATA

    4. Pin 4: GND - connected to GND

    5. Pin 5: PB0 (PWM) - connected to sensor I2C SDA

    6. Pin 6: PB1 (PWM) - connected to LED with 4.7k to GND

    7. Pin 7: PB2 (A1) - connected to sensor I2C SCL

    8. Pin 8: VCC - connected to 5V

Working with ATTiny85 needs a bit more of work as you need to get additional libraries for I2C comm (adafruit/TinyWireM) and serial output (TinyDebugSerial). Additionally as the memory is quite limited you might want to work a lot with #define e.g. to remove serial debugging. In the example you can see all this thrown together.

For testing the first step is to check whether the LED flashes with the correct frequency, 0.5Hz. Then connect it to the 1wire bus and check for the new device.