Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ __pycache__/
# Distribution / packaging
.Python
env/
venv/
build/
develop-eggs/
dist/
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ Eduard Bröcker <eduard@gmx.de>
Boris Wenzlaff
Pierre-Luc Tessier Gagné
Felix Divo <felix.divo@gmail.com>
Kristian Sloth Lauszus <lauszus@gmail.com>
483 changes: 483 additions & 0 deletions can/viewer.py

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion doc/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ project in 2011. The socketcan interface was helped immensely by Phil Dixon
who wrote a leaf-socketcan driver for Linux.

The pcan interface was contributed by Albert Bloomfield in 2013.
Support for pcan on Mac was added by Kristian Sloth Lauszus in 2018.

The usb2can interface was contributed by Joshua Villyard in 2015.

Expand All @@ -34,13 +35,14 @@ a C++ library by Toby Lorenz.
The slcan interface, ASCII listener and log logger and listener were contributed
by Eduard Bröcker in 2017.

The NeoVi interface for ICS (Intrepid Control Systems) devices was contributed
The NeoVi interface for ICS (Intrepid Control Systems) devices was contributed
by Pierre-Luc Tessier Gagné in 2017.

Many improvements all over the library, cleanups, unifications as well as more
comprehensive documentation and CI testing was contributed by Felix Divo in 2017
and 2018.

The CAN viewer terminal script was contributed by Kristian Sloth Lauszus in 2018.

Support for CAN within Python
-----------------------------
Expand Down
Binary file added doc/images/viewer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 91 additions & 1 deletion doc/scripts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ The following modules are callable from python-can.

They can be called for example by ``python -m can.logger`` or ``can_logger.py`` (if installed using pip).


can.logger
----------

Expand Down Expand Up @@ -84,3 +83,94 @@ Command line help, called with ``--help``::
minimum gap between frames)
-g GAP, --gap GAP <s> minimum time between replayed frames
-s SKIP, --skip SKIP <s> skip gaps greater than 's' seconds

can.viewer
----------

A screenshot of the application can be seen below:

.. image:: ../images/viewer.png
:width: 100%

The first column is the number of times a frame with the particular ID that has been received, next is the timestamp of the frame relative to the first received message. The third column is the time between the current frame relative to the previous one. Next is the length of the frame, the data and then the decoded data converted according to the ``-d`` argument. The top red row indicates an error frame.

Command line arguments
^^^^^^^^^^^^^^^^^^^^^^

By default it will be using the :doc:`/interfaces/socketcan` interface. All interfaces supported are supported and can be specified using the ``-i`` argument.

The full usage page can be seen below::

Usage: python -m can.viewer [-h] [--version] [-b BITRATE] [-c CHANNEL]
[-d {<id>:<format>,<id>:<format>:<scaling1>:...:<scalingN>,file.txt}]
[-f {<can_id>:<can_mask>,<can_id>~<can_mask>}]
[-i {iscan,ixxat,kvaser,neovi,nican,pcan,serial,slcan,socketcan,socketcan_ctypes,socketcan_native,usb2can,vector,virtual}]

A simple CAN viewer terminal application written in Python

Optional arguments:
-h, --help Show this help message and exit
--version Show program's version number and exit
-b, --bitrate BITRATE
Bitrate to use for the given CAN interface
-c, --channel CHANNEL
Most backend interfaces require some sort of channel.
For example with the serial interface the channel
might be a rfcomm device: "/dev/rfcomm0" with the
socketcan interfaces valid channel examples include:
"can0", "vcan0". (default: use default for the
specified interface)
-d, --decode {<id>:<format>,<id>:<format>:<scaling1>:...:<scalingN>,file.txt}
Specify how to convert the raw bytes into real values.
The ID of the frame is given as the first argument and the format as the second.
The Python struct package is used to unpack the received data
where the format characters have the following meaning:
< = little-endian, > = big-endian
x = pad byte
c = char
? = bool
b = int8_t, B = uint8_t
h = int16, H = uint16
l = int32_t, L = uint32_t
q = int64_t, Q = uint64_t
f = float (32-bits), d = double (64-bits)
Fx to convert six bytes with ID 0x100 into uint8_t, uint16 and uint32_t:
$ python -m can.viewer -d "100:<BHL"
Note that the IDs are always interpreted as hex values.
An optional conversion from integers to real units can be given
as additional arguments. In order to convert from raw integer
values the values are multiplied with the corresponding scaling value,
similarly the values are divided by the scaling value in order
to convert from real units to raw integer values.
Fx lets say the uint8_t needs no conversion, but the uint16 and the uint32_t
needs to be divided by 10 and 100 respectively:
$ python -m can.viewer -d "101:<BHL:1:10.0:100.0"
Be aware that integer division is performed if the scaling value is an integer.
Multiple arguments are separated by spaces:
$ python -m can.viewer -d "100:<BHL" "101:<BHL:1:10.0:100.0"
Alternatively a file containing the conversion strings separated by new lines
can be given as input:
$ cat file.txt
100:<BHL
101:<BHL:1:10.0:100.0
$ python -m can.viewer -d file.txt
-f, --filter {<can_id>:<can_mask>,<can_id>~<can_mask>}
Comma separated CAN filters for the given CAN interface:
<can_id>:<can_mask> (matches when <received_can_id> & mask == can_id & mask)
<can_id>~<can_mask> (matches when <received_can_id> & mask != can_id & mask)
Fx to show only frames with ID 0x100 to 0x103:
python -m can.viewer -f 100:7FC
Note that the ID and mask are alway interpreted as hex values
-i, --interface {iscan,ixxat,kvaser,neovi,nican,pcan,serial,slcan,socketcan,socketcan_ctypes,socketcan_native,usb2can,vector,virtual}
Specify the backend CAN interface to use.

Shortcuts:
+---------+-------------------------+
| Key | Description |
+---------+-------------------------+
| ESQ/q | Exit the viewer |
| c | Clear the stored frames |
| s | Sort the stored frames |
| SPACE | Pause the viewer |
| UP/DOWN | Scroll the viewer |
+---------+-------------------------+
14 changes: 14 additions & 0 deletions scripts/can_viewer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python
# coding: utf-8

"""
See :mod:`can.viewer`.
"""

from __future__ import absolute_import

from can.viewer import main


if __name__ == "__main__":
main()
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
'pytest ~= 3.6',
'pytest-timeout ~= 1.2',
'pytest-cov ~= 2.5',
'codecov ~= 2.0'
'codecov ~= 2.0',
'future',
'six'
] + extras_require['serial']

extras_require['test'] = tests_require
Expand Down Expand Up @@ -98,7 +100,7 @@
# see https://www.python.org/dev/peps/pep-0345/#version-specifiers
python_requires=">=2.7,!=3.0,!=3.1,!=3.2,!=3.3",
install_requires=[
'wrapt ~= 1.10',
'wrapt ~= 1.10', 'typing', 'windows-curses;platform_system=="Windows"',
],
extras_require=extras_require,

Expand Down
Loading