Ethernet Interface

How to build an Ethernet interface for TakkTile sensors

by Nuno Sucena Almeida

This system allows you to connect TakkTile sensors to the internet using an ethernet interface and query the status of those sensors using a simple UDP protocol. In addition, there's also a ROS node that uses this functionality and publishes the information through a few topics.

Hardware

The hardware required is the following:
teensy 3.1 - Freescale MK20DX256 ARM Cortex-M4 dev board.
enc28j60 - ethernet module using the Microchip enc28j60 ethernet controller. You can find these ethernet modules at your favorite electronics part distributor. The code can be adapted to other modules.

Software

The code uses a mix of embedded C/C++ support code, arduino code and a few extra libraries:

ethercard
Driver for the above ethernet module.
There's quite a few changes I had to make for this library to work properly, so in the meanwhile, please checkout my teensy31 branch.
spi4teensy3
alternative SPI library for the teensy 3.x (only needed for SPI initialization for now).
firmware
ethernet firmware, ROS UDP node , Python UDP host driver, TakkTile Arduino class.

Wiring

This setup uses the regular i2c and spi pinout connections for the teensy. The connections to the ethernet module depend on what you have, but should be similar to what's below. The system requires 5V for the teensy and 3.3V for the ethernet module and i2c bus. The teensy 3.1 (but not 3.0!) IO ports are 5V tolerant, but have 3.3 logic levels. There's some exceptions to these, so please check the manual!

takktile-ethernet.sch.pdf

Installation

For a successful installation, make sure to follow these steps, described here for a GNU/Linux based system:

  • Download and install the Arduino 1.0.5 IDE.
  • Download teensyduino and follow the instructions from that webpage. Don't forget to setup the udev rules.
  • Download all the extra libraries above to your arduino sketchbook library location, usually ~/sketchbook/libraries
  • Download the firmware code and within ~/sketchbook/libraries, make a link to it:
wget -O takktile_ethernet.tar.xz 'http://git.aeminium.org/~nuno/?p=electronics/takktile.git;a=snapshot;h=HEAD;sf=txz'
tar xfa takktile_ethernet.tar.xz
cd ~/sketchbook/libraries
ln -s PATH/firmware/Takktile

where PATH is the directory with the contents of the takktile_ethernet.tar.xz file.
  • Open the arduino IDE, select the teensy 3.1 board and 24MHz as clock rate.
  • Connect the teensy 3.1 board to your computer system.
  • Open the TakktileArduinoUDP31 example, compile it and upload it to the board.

The system should be ready to run. To debug it, you can use something like:

minicom -D /dev/ttyACM0 -o -b 57600

Network and Sensor Configuration

The module can use DHCP or static IP addressing if you don't have a DHCP server running on your network. For reliability purposes, static IP addressing is recommended. In this case, you should set the static IP address of the module and use the IP address of the PC host system as gateway IP address. If running several of these ethernet modules, you should also set a different ethernet MAC address for each module. Check the definitions at the top of the TakktileArduinoUDP31.ino code.

The module automatically detects connected sensors at startup or when it's reset / power cycled. An easy way of adding/removing sensors is to stop network querying the module (stop the ROS node) until the watchdog fires (see Notes below).

Protocol

The UDP payload has dynamic size, dependent on the number of connected sensors and is arranged in the following way:

byte start byte end description byte order
0 0 number of sensors (NS) little-endian
1 NS array of byte-sized sensor addresses of size NS little-endian
NS+1 1+NS*4 array of float-type sensor pressure raw values, with size NS little-endian
2+NS*4 2+NS*8 array of float-type sensor temperature raw values, with size NS little-endian

When the MCU receives any packet on UDP port 31337, it will reply with the current sensor values in the above format. The UDP port can also be changed to a different value.

Testing

The software package comes with a simple utility that can be used to check the proper functioning of the setup:

./takktile_udp.py -h
usage: takktile_udp.py [-h] [--version]
                       [--log-level {debug,info,warning,critical,error}]
                       [--remote-host REMOTEHOST] [--remote-port REMOTEPORT]
                       [--local-host LOCALHOST] [--local-port LOCALPORT]
                       [--timeout TIMEOUT] [--samples SAMPLES]

Query tool for Takktile UDP based sensor

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --log-level {debug,info,warning,critical,error}, -l {debug,info,warning,critical,error}
  --remote-host REMOTEHOST, -H REMOTEHOST
                        remote host
  --remote-port REMOTEPORT, -P REMOTEPORT
                        remote port
  --local-host LOCALHOST, -M LOCALHOST
                        local host
  --local-port LOCALPORT, -L LOCALPORT
                        local port
  --timeout TIMEOUT, -t TIMEOUT
                        how long to wait for a response [seconds]
  --samples SAMPLES, -s SAMPLES
                        how many sample queries

Example of use:

./takktile_udp.py -H 192.168.36.101 -s 1 -l debug -t 1
2014-03-02 21:27:47,397 - takktile_udp.py - INFO - Listening on 0.0.0.0:31337
2014-03-02 21:27:47,397 - takktile_udp.py - INFO - Requesting from 192.168.36.101:31337
2014-03-02 21:27:47,397 - takktile_udp.py - DEBUG - Starting sampling
2014-03-02 21:27:47,413 - takktile_udp.py - DEBUG - numberSensors=19, data=172
2014-03-02 21:27:47,428 - takktile_udp.py - DEBUG - numberSensors=19, data=172
Alive: 19 sensors: set([0, 1, 2, 54, 40, 41, 10, 11, 12, 13, 14, 50, 51, 20, 21, 22, 52, 42, 53])
2014-03-02 21:27:47,444 - takktile_udp.py - DEBUG - numberSensors=19, data=172
   0 Data: {0: (400, 520), 1: (407, 528), 2: (412, 525), 54: (440, 528), 40: (0, 521), 41: (439, 524), 10: (464, 523), 11: (504, 531), 12: (499, 526), 13: (470, 524), 14: (423, 533), 50: (473, 527), 51: (479, 525), 20: (471, 525), 21: (328, 530), 22: (296, 527), 52: (490, 525), 42: (370, 528), 53: (412, 526)}
Took 0.015526 seconds to finish. 64.408 Hz
2014-03-02 21:27:47,444 - takktile_udp.py - DEBUG - Stopping sampling
  • If you are running a firewall, you should allow UDP communication to/from the 31337 port or whatever port you set if you changed it in the code. On ubuntu, it would be something like:
sudo ufw allow 31337

You can also debug the system at the network protocol level using the tcpdump utility:

sudo tcpdump -n -i eth0 port 31337 -XX

where eth0 is the appropriate ethernet interface that shares the network with this module. If querying the module using the above python utility, you should see packets being sent from your host and right after a response packet from the module with the above UDP payload.

listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
22:45:17.395690 IP 192.168.36.208.43669 > 192.168.36.101.31337: UDP, length 1
    0x0000:  7469 692d 3033 3085 a994 a351 0800 4500  tii-030....Q..E.
    0x0010:  001d cf66 4000 4011 a0e3 c0a8 24d0 c0a8  ...f@.@.....$...
    0x0020:  2465 aa95 7a69 0009 caa0 74              $e..zi....t
22:45:17.408954 IP 192.168.36.101.31337 > 192.168.36.208.31337: UDP, length 172
    0x0000:  3085 a994 a351 0018 39ea 79fc 0800 4500  0....Q..9.y...E.
    0x0010:  00c8 0000 4000 3f11 709f c0a8 2465 c0a8  ....@.?.p...$e..
    0x0020:  24d0 7a69 7a69 00b4 c491 1300 0102 0a0b  $.zizi..........
    0x0030:  0c0d 0e14 1516 2829 2a32 3334 3536 0080  ......()*23456..
    0x0040:  c643 0000 ca43 0080 cb43 0080 e743 0000  .C...C...C...C..
    0x0050:  fc43 0000 f943 0000 e943 0080 d243 0000  .C...C...C...C..
    0x0060:  ec43 0080 a343 0080 9443 0000 0000 0080  .C...C...C......
    0x0070:  db43 0080 b743 0080 ec43 0080 ed43 0080  .C...C...C...C..
    0x0080:  f443 0080 cd43 0000 dc43 0040 0244 0080  .C...C...C.@.D..
    0x0090:  0344 0040 0344 0000 0344 0000 0544 00c0  .D.@.D...D...D..
    0x00a0:  0344 0080 0344 0000 0544 00c0 0344 0080  .D...D...D...D..
    0x00b0:  0444 0040 0444 0040 0244 0040 0344 0040  .D.@.D.@.D.@.D.@
    0x00c0:  0444 0000 0444 0080 0344 0040 0344 00c0  .D...D...D.@.D..
    0x00d0:  0344 00c0 0344                           .D...D

ROS

Follow the Ros Takktile installation instructions, then copy the ethernet/takktile_udp.py and ros/takktile_node_udp.py files from my repo into that package src directory. Edit the ros/takktile_node_udp.py and set the appropriate IP address for the sensor, search for remoteHostname="takktile-01". Compile it again and if all is setup properly, you can now run the UDP ROS node:

rosrun takktile_ros takktile_node_udp.py

Notes

  • The teensy 3.1 main clock can run at 24MHz, 48MHz, 72MHz or 96MHz. You can select any of these, 24MHz works fine, the current sample rate limitation is the i2c clock rate.
  • The i2c bus clock rate is set at 400kHz, but it can be set to higher speeds if the i2c cable is sufficiently short, if you can manage the load capacitance, use different pull-up resistors,etc.
  • The network sample rate is limited by the i2c clock rate, as mentioned above. If you add more sensors, this rate will decrease. With about 30 sensors you can get 30Hz sample rate.
  • There's a watchdog timer (WDT) running that will reset the system if there's no query from a remote host within 20 seconds. This value can be changed in the code to suit your setup. It can also be disabled, but it's not recommended to do so, since it protects against any problem with the sensors, ethernet module, internet connectivity , and any other issue that the MCU might run into.
  • If the watchdog timer resets the MCU, you will see both the ethernet link green led and the teensy orange led go temporarily off and back on.
  • The ethernet module negotiates a speed of 10Mbit/s. Some 1Gb switches take 20 to 30 seconds to auto-negotiate this speed, by which the system will not be able to respond to queries or pings, so take this into consideration when querying the sensor right after reset / power cycle. If this is the case you also need to increase the watchdog timeout to a value higher than the auto-negotiate time.

Questions ?

Contact us: here

wordpress com stats

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial 3.0 License