socketcand Interface¶
Socketcand is part of the Linux-CAN project, providing a Network-to-CAN bridge as a Linux damon. It implements a specific TCP/IP based communication protocol to transfer CAN frames and control commands.
The main advantage compared to UDP-based protocols (e.g. virtual interface) is, that TCP guarantees delivery and that the message order is kept.
Here is a small example dumping all can messages received by a socketcand daemon running on a remote Raspberry Pi:
import can
bus = can.interface.Bus(interface='socketcand', host="10.0.16.15", port=29536, channel="can0")
# loop until Ctrl-C
try:
while True:
msg = bus.recv()
print(msg)
except KeyboardInterrupt:
pass
The output may look like this:
Timestamp: 1637791111.209224 ID: 000006fd X Rx DLC: 8 c4 10 e3 2d 96 ff 25 6b
Timestamp: 1637791111.233951 ID: 000001ad X Rx DLC: 4 4d 47 c7 64
Timestamp: 1637791111.409415 ID: 000005f7 X Rx DLC: 8 86 de e6 0f 42 55 5d 39
Timestamp: 1637791111.434377 ID: 00000665 X Rx DLC: 8 97 96 51 0f 23 25 fc 28
Timestamp: 1637791111.609763 ID: 0000031d X Rx DLC: 8 16 27 d8 3d fe d8 31 24
Timestamp: 1637791111.634630 ID: 00000587 X Rx DLC: 8 4e 06 85 23 6f 81 2b 65
This interface also supports detect_available_configs()
.
import can
import can.interfaces.socketcand
cfg = can.interfaces.socketcand._detect_available_configs()
if cfg:
bus = can.Bus(**cfg[0])
The socketcand daemon broadcasts UDP beacons every 3 seconds. The default
detection method waits for slightly more than 3 seconds to receive the beacon
packet. If you want to increase the timeout, you can use
can.interfaces.socketcand.detect_beacon()
directly. Below is an example
which detects the beacon and uses the configuration to create a socketcand bus.
import can
import can.interfaces.socketcand
cfg = can.interfaces.socketcand.detect_beacon(6000)
if cfg:
bus = can.Bus(**cfg[0])
Bus¶
- class can.interfaces.socketcand.SocketCanDaemonBus(channel, host, port, tcp_tune=False, can_filters=None, **kwargs)[source]¶
Bases:
BusABC
Connects to a CAN bus served by socketcand.
It implements
can.BusABC._detect_available_configs()
to search for available interfaces.It will attempt to connect to the server for up to 10s, after which a TimeoutError exception will be thrown.
If the handshake with the socketcand server fails, a CanError exception is thrown.
- Parameters:
channel – The can interface name served by socketcand. An example channel would be ‘vcan0’ or ‘can0’.
host – The host address of the socketcand server.
port – The port of the socketcand server.
tcp_tune – This tunes the TCP socket for low latency (TCP_NODELAY, and TCP_QUICKACK). This option is not available under windows.
can_filters – See
can.BusABC.set_filters()
.
- can.interfaces.socketcand.detect_beacon(timeout_ms=3100)[source]¶
Detects socketcand servers
This is what
can.detect_available_configs()
ends up calling to search for available socketcand servers with a default timeout of 3100ms (socketcand sends a beacon packet every 3000ms).Using this method directly allows for adjusting the timeout. Extending the timeout beyond the default time period could be useful if UDP packet loss is a concern.
Socketcand Quickstart¶
The following section will show how to get the stuff installed on a Raspberry Pi with a MCP2515-based CAN interface, e.g. available from Waveshare. However, it will also work with any other socketcan device.
Install CAN Interface for a MCP2515 based interface on a Raspberry Pi¶
Add the following lines to /boot/config.txt
.
Please take care on the frequency of the crystal on your MCP2515 board:
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=12000000,interrupt=25,spimaxfrequency=1000000
Reboot after /boot/config.txt
has been modified.
Enable socketcan for can0¶
Create config file for systemd-networkd to start the socketcan interface automatically:
cat >/etc/systemd/network/80-can.network <<'EOT'
[Match]
Name=can0
[CAN]
BitRate=250K
RestartSec=100ms
EOT
Enable systemd-networkd
on reboot and start it immediately (if it was not already startet):
sudo systemctl enable systemd-networkd
sudo systemctl start systemd-networkd
Build socketcand from source¶
# autoconf is needed to build socketcand
sudo apt-get install -y autoconf
# clone & build sources
git clone https://github.com/linux-can/socketcand.git
cd socketcand
./autogen.sh
./configure
make
Install socketcand¶
make install
Run socketcand¶
./socketcand -v -i can0
During start, socketcand will prompt its IP address and port it listens to:
Verbose output activated
Using network interface 'eth0'
Listen adress is 10.0.16.15
Broadcast adress is 10.0.255.255
creating broadcast thread...
binding socket to 10.0.16.15:29536