Introduction: Arduino 1-wire Display (144 Chars)
From the first day I started playing around and working with 1-wire networks and devices I wanted to have a nice display for all kind of information, like e.g. current temperatures in- and outside the house. I use owfs to access my 1-wire devices and thus the display needs to be supported as I don't want to figure out how to fiddle around with the PIC or DS2408 devices by myself.
Looking around for displays I found this owfs page listing supported LCDs designs:
- Louis Swart PIC based
- Hobby Boards DS2408 based (Apparently no longer produced)
- Maxim DS2408 based
- AagElectronica DS2408 based (optional DS2890 for contrast control)
These are basically DS2408 based but most of them are not produced anymore (or expensive). The exception is the PIC based Louis Swart design. I also found another one:
- esera automation LCD Display 163 DS2408 based
This one is not supported by owfs (yet! contributions welcome!) and thus not a solution to my needs.
In this instructable I will show you now how to use an Arduino/AVR to build a 144 chars 1-wire display yourself. This is possible thanks to the great work of orgua in publishing the OneWire-Hub library (OneWire slave device emulator).
Step 1: Build the Hardware
This step is the one you have to think first. What functions do you need to include in your display design to suit you best?
For me the answer was that I need at least 1 button in order to be able to change display modes from "normal" to "inverted" and "off".
You might decide to need more functions, like buttons for counters/triggers, some LEDs, some light sensor or a temperature sensor. You can come up with whatever you want as the source code is modular and allows you to emulate basically any number of 1-wire devices within 1 single Arduino/AVR! You can update and change this later at any time but you might not be able to adopt your hardware depending on what you soldered and how - so think first!
Material and stuff needed:
- Arduino Uno (R3) and the IDE >= 1.8.3
- Grove-OLED Display 1.12inch and Grove cables/connectors
- connector for 1-wire network, typically a 8P8C usually called "RJ-45"
- additional stuff you might like to include, e.g. an Arduino shield, a casing, some buttons, etc.
For my design the wiring, building and soldering was straight forward as there are only the OLED I2C interface including power supply, the button and the 1-wire port. In this current design the Arduino/AVR is externally powered. On how to power it from the 1-wire network/bus directly more in step 4 (Planned Improvements).
[draw and add fritzing schematic here]
Step 2: Upload the Code
In order to make the display working we need now some code for the Arduino/AVR. This is actually the crucial step as there are not many libraries around that can implement a working software 1-wire slave device (code for an Arduino/AVR to act as 1-wire master is available however). The code that is most mature and does work very nicely for me is:
- OneWire-Hub library (OneWire slave device emulator) by orgua (pay attention there are other forks around)
This library can emulate quite a bunch of standardized 1-wire slave devices as can be seen in the README or by looking at the examples folder. The best thing is that it can even emulate multiple devices on 1 single Arduino/AVR chip. The great thing about this library is that as it emulates standardized devices you can use the 1-wire hard- and software of your choice as anyone will support at least some of these devices. Currently the most recent version also used here is 2.2.0. Furthermore it is a sketch and allows add your own code for communicating and reading sensors which is super cool but dangerous if your code is too slow. The speed issue is mentioned below and the reason why other libraries like M-o-a-T/owslave do not allow to add your own code.
For this instructable we need a device that can store at least 144 bytes (128 bytes = 1 kbit). From looking at the list we can find several ones that feature 4 kbit of EEPROM or RAM. I decided to go for the DS2433. In owfs this device has a "memory" item that can be written and allows us to transfer data to the device. This data will then be written to the OLED using its library from Seed-Studio. A button added (pin 2) allows to change the displays status (normal, inverted and off) without needing to receive and send command over the 1-wire bus, as needed e.g. with the Louis Swart LCD. Of course we are still free to add or mimic this behaviour if preferred (using pages e.g.).
To make this device working we have to take care of several subtle issues. First the OneWire-Hub library config file called "OneWireHub_config.h" has to be edited in order to 10x the value ONEWIRE_TIME_MSG_HIGH_TIMEOUT such that it reads "150000_us". This makes the device more compatible with e.g. my LinkHubE (and other masters), confer the README for more info about that as your master might not need this change. Next thing is that writing to the OLED display is extremely slow compared to 1-wire bus latency times etc. Writing the whole display as needed for the first update takes in the order of seconds. Therefore the code has to be smart enough not to write the full display all the time but changed lines only - otherwise this will mess up 1-wire timings. If you choose to use another display you have to pay attention to write a performant and fast code that does not block the device for too long times (low latency).
Step 3: Test the Device
After uploading the code to your Arduino/AVR the display will show some startup information for your convenience in order to simplify identification of the device during tests and debugging. If you did everything correct, the LED (pin 13) will now start to flash with a 4 second period to show operation. Now you can connect the device to your 1-wire bus respective master and check for presence. Using owfs you could use commands like:
$ owwrite 23.00003324DA00/memory "Hello World!"
$ owget 23.00003324DA00/memory
As this is a rather short message it has to work almost immediately. If you test with longer messages up to 144 chars you might need to retry a second time as sometimes the transmission of such long messages gets interrupted. But usually no more than 2 attempts are needed (2 only in case of changes in all 12 lines, as this takes long to be written to the slave and even longer to the OLED).
As your display works now, you might want to include it into you 1-wire infrastructure. E.g. writing a python script for control that takes care of reading the written data back and in case it's needed re-issue sending of the data. Also for formatting of the output this can come in very handy.
Powering from 1-wire bus 5V line is desirable. Current measurements show the device to draw 46 - 90mA (0.25 - 0.5W) in total depending on how many pixels are activated. My bus is able to deliver that much power so I just connected the 5V from bus to the Arduino 5V pin (not Vin) using a plug that allows to disconnect for debugging. Until here no attempts whatsoever have been taken to reduce the power consumption to a minimum (e.g. building a Arduino board PCB with minimal components, use attiny if possible). Alternatively it can be powered from 12V (1-wire bus or external) via Vin pin, as specified in Arduino: What Adapter?
Actually now you can use your display and the instructions on how to build it thus have come to an end. However you can of course modify and change the hardware and software as you want - enjoy!
Please leave a comment at the bottom of this page describing how you implemented this instructable, what you liked or disliked and how you changed my design to suit your needs.
Step 4: Add Arduino Internal Sensors
Another very cool thing is that OneWire-Hub can emulate more than one 1-wire device per Arduino/AVR chip. So I added another sketch to the download that exposes the Arduino supply voltage and internal temperature as two DS18B20 to the network. By reading their temperature values you can access those measurements. Other external sensors can be added in this manner to (e.g. temp and humidity sensors, light sensor/LED, buttons, etc). See also Arduino 1-wire Generic Client/Slave Device (Sensor).
This code also contains a watchdog (avr/wdt.h) and counter that count the number of RESET and power-ups in order to see how often the watchdog triggered.
Step 5: Planned Improvements
Things that are still work-in-progress and that I will include into this instructable as soon as I have time to test the properly are listed here. Feel free to work on them yourself and post your solutions in the comments section if you like.
clean up the Arduino/AVR code and comments
add fritzing schematic
maybe build chasing
- adopt timing by finding the best value for ONEWIRE_TIME_MSG_HIGH_TIMEOUT such that it is something between the default "15000_us" and the here used "150000_us" (10x) and report it to: https://github.com/orgua/OneWireHub/issues/43
- test the compatibility with other systems, e.g. masters, software, etc.: OWFS, FHEM (supported through OWFS)
- add buttons and/or additional 1wire functionality by adding sensors; e.g. use a button to switch between 3 different pages to show (3 x 144 <= 512)
use I2C fast mode to speed up data transfer to OLED: https://forum.arduino.cc/index.php?topic=16793.0
- add low power features: http://www.rocketscream.com/blog/2011/07/04/light...