You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+34-1Lines changed: 34 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,5 +4,38 @@ Unofficial Python userspace driver for the low cost USB analyzer "Canalyst-II".
4
4
5
5
Uses [pyusb](https://pyusb.github.io/pyusb/) library for USB support, should work on Windows, MacOS and Linux.
6
6
7
-
This driver is based on black box reverse engineering and the original python-can canalystii source.
7
+
This driver is based on black box reverse engineering and the original python-can canalystii source. It's mostly intended for use with python-can, but can also be used standalone.
8
8
9
+
## Usage
10
+
11
+
```py
12
+
import canalystii
13
+
14
+
# Connect to the Canalyst-II device
15
+
dev = canalystii.CanalystDevice(bitrate=500*1000)
16
+
17
+
# Receive all pending messages on channel 0
18
+
for msg in dev.receive(0):
19
+
print(msg)
20
+
21
+
# The canalystii.Message class is a ctypes Structure, to minimize overhead
22
+
new_message = canalystii.Message(can_id=0x300,
23
+
remote=False,
24
+
extended=False,
25
+
data_len=8,
26
+
data=(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08))
27
+
# Send one copy to channel 1
28
+
dev.send(1, new_message)
29
+
# Send 3 copies to channel 0 (argument can be any iterable, or single instance of canalystii.Message)
30
+
dev.send(0, [new_message] *3)
31
+
```
32
+
33
+
## Performance
34
+
35
+
Because the Canalyst-II USB protocol requires polling, there is a trade-off between CPU usage and both latency and maximum receive throughput. The host needs to constantly poll the device to request any new CAN messages.
36
+
37
+
The hardware seems able to buffer 1000-2000 messages (possibly a little more) per channel. The maximum number seems to depend on relative timing of the messages. Therefore, a 1Mbps (maximum speed) CAN channel receiving the maximum possible ~7800 messages/second should call `receive()` at least every 100ms in order to avoid lost messages. The USB protocol doesn't provide any way to tell if any messages in the hardware buffer were lost.
38
+
39
+
Testing Linux CPython 3.9 on an older i7-6500U CPU, calling `receive()` in a tight loop while receiving maximum message rate (~7800 messages/sec) on both channels (~15600 messages/sec total) uses approximately 40% of a single CPU. Adding a 50ms delay `time.sleep(0.05)` in the loop drops CPU usage to around 10% without losing any messages. Longer sleep periods in the loop reduce CPU usage further but some messages are dropped. See the `tests/can_spammer_test.py` file for the test code.
40
+
41
+
In systems where the CAN message rate is lower than the maximum, `receive()` can be called less frequently without losing messages. In systems where the Python process may be pre-empted, it's possible for messages to be lost anyhow.
0 commit comments