While working on a 1-wire bus system - e.g. building an Arduino Uno 1-wire slave device using an OneWireSlave library or doing general development and debugging - a logic analyzer to evaluate and interpret the bit traffic on the bus might come in handy. I will show you here how to easily and fast build a sniffer using just a serial/RS-232 USB adapter. This adapter can be build from an Arduino Uno board by putting one jumper only.
Using an Arduino Uno we get immediately several interesting options:
- the SUMP compatible logic analyzer code for Arduino Uno consisting of the logic_analyzer sketch and a 1-wire compatible GUI like OLS - of course any better SUMP system like the original Open Bench Logic Sniffer or Bus Pirate works too (actually better due to more memory)
- read Tutorial 214; Using a UART to Implement a 1-Wire Bus Master to understand how to use any serial interface (UART) like a serial/RS-232 USB adapter built from an Arduino Uno board
Comparing what we have seen to 1-wire communication interface which is an implementation of the DS9097 Passive Serial Adapter ("the original serial 1-wire adapter") we get an idea that in the old days commercial 1-wire Masters where build similar to our sniffer. The UART is a perfect match for 1-wire bus communication since it provides the synchronization needed. And we see a small subtlety; the Arduino Uno board does actuall not give a true serial/RS-232 USB adapter because of the "wrong" voltage levels (Arduino and 1-Wire are 0 to 5V whereas RS-232 is between 3 and 15V negative and positive).
Step 1: Arduino Uno ("1-wire Bridge")
We need to connect the 1-wire bus to the Arduino Uno board and set it up in order to serve as a UART respective serial/RS-232 USB adapter or "1-wire bridge".
- 1-wire bus: connect the pin TXD/1 from Arduino Uno board to the 1-wire data line (blue) and GND to 1-wire GND (black)
- Arduino Uno board: we have at least 3 Ways to Use Arduino as USB Serial Adapter Converter and here the most simple (avoids creating and maintaining a sketch) is just to jumper RESET to GND (yellow) - this is elegant since you can leave the current sketch on the Arduino and by that disable it temporarily while using the Arduino as sniffer
Connect the Arduino Uno board with an USB cable to your PC and then you are ready to continue.
(You can now also see we I called it always Arduino Uno board. The main "Arduino" ATmega chip is disabled, we use other parts of the board here. This is also the reason why the pin is called TX; it is the main chips TX but UART/ATmega8U RX pin, confer the Arduino UNO Reference Design.)
Step 2: PC - Miniterm (first Contact)
In Tutorial 214; Using a UART to Implement a 1-Wire Bus Master it is described how to generate/retrieve 1-wire bus pulse sequences. Unfortunately the RESET & PRESENCE pulses have to be generated at 9600 baud whereas all other (READ, WRITE of 0 and 1) need to be created using 115200 baud. As pointed out in App. Note 74; Reading and Writing 1-Wire Devices Through Serial Interfaces: "Although efficient under operating systems such as DOS, modern operating systems make the access to UART registers quite inefficient." and since we don't want to use a DS2480B, we have to live with the fact that a fast switch of the baud rate at a controlled buffer position is impossible.
For the system I used this was not a problem since I could reliably detect RESET & PRESENCE pulses at a baud rate of 115200 as 0x00 0x00 sequence. Actually going from 9600 to 115200 would result in 12 bytes instead of 1, but in this case we have only 2 start bits - thus 2 bytes only. Even though 0x00 could be a WRITE 0 - I never saw values below 0x80 on the bus and thus could discriminate between WRITE 0 and RESET & PRESENCE. In case of other systems used (Master & Slaves) the exact timing and thus this fact could change.
(I used an OW Server 2 ENET with 1 DS2438 as a system for these tests.)
That all said, for a first contact we actually don't have to care too much, we just have to decide what we want to see and then select the proper baud rate. I used the Python script miniterm.py that comes with the pySerial module (used later anyway - Interface Python and Arduino with pySerial is very useful in general) in order to open the port and watch the incoming traffic:
$ miniterm.py -D -D -D /dev/ttyACM0 9600
$ miniterm.py -D -D -D /dev/ttyACM0 115200
(The other port settings are: 8 bits, no parity, 1 stop bit which is default in miniterm.)
Once we have a connection established and see data coming in, we can start to analyze the bus traffic. Look at the hex values appearing (should be about 5 different values only coming over and over again), convert the hex to bit sequences and study the bus timing, try to distinguish between WRITE and READ operations, etc.
If you want to have a look at a very crappy, early and simple ("proof of concept state like") script in order to get an idea on how to continue from here, then proceed to the next step.
Step 3: PC - Python Script (get Serious)
This python script shows how to interpret the data from the Arduino Uno board (acting as UART) to recover 1-wire bus bit sequences, convert and print these as hex values. It goes one step further and does a interpretation of the byte data as well (currently for MATCH_ROM, SEARCH_ROM only).
Please be aware that this script is a very early "proof of concept like" state and leaves a lot of room open for improvement of the basic functions as well as the python coding style. (I will happily reproduce any improved code here if you mail it to me.)
The script features 2 functions:
- sniff_TUT214: sniffer according to official Standards/Specs given in TUTORIAL 214 (RESET @9600)
- sniff_115200: sniffer always @115200 (possible to implement)
of which the first was just a try without any real ambitions to get it working (may be in C++ with some assembler code - could be done as python module then). The second one however works quite good, is stable and reliable in the sense of that it returns useful and reproducable data.
Step 4: That All Said...
I hope these instructions have been or will be useful to you either in implementing a sniffer and setup you own custom made 1-wire MicroLan network or understand the 1-wire bus a bit better.
Please leave comments and feel free to send me feedback by mail (or any other means you can come up with ;).
All the best!