Open felixdivo opened 2 years ago
Hmm. We're using the ixxat usb interfaces a lot at work. Let me have a look onto this tomorrow. My guess is that you don't have the driver installed and there is an issue with loading the module. Could you please print the exception that you currently ignore (The pass statement under the comment Connection failed)? This might help with the other backends too.
Just to make it clear, this was
Originally posted by @Kochise in #303 (comment)
Thanks @marcel-kanter for having a look!
Thanks for opening this issue. I don't have access to the hardware anymore, but I'll ask somebody that do.
The drivers were perfectly installed because I could use both adapters and my "discovery" loop worked fine for both of them.
BTW, is there a way to get more infos about an interface ? For instance, the neovi
have two channels (ch1 and ch2) while the ixxat
only have one (ch0). It would be great to have something like :
import can
can.interface.detect_available_configs()
[...]
[{'interface': 'virtual', 'channel': 'channel-3439'},
{'interface': 'neovi', 'serial': '120216', 'channels': {'1': [1000000, 500000, 250000, 125000], '2': [1000000, 500000, 250000, 125000]}},
{'interface': 'ixxat', 'serial': 'abcdef', 'channels': {'0': [1000000, 500000, 250000, 125000]}}]
Hence that would help to know what's possible without having to try all combinations.
Regards.
First the code:
import can
import logging
logging.basicConfig(level = logging.DEBUG)
can.interface.detect_available_configs(['ixxat'])
Then the output:
pydev debugger: starting (pid: 6296)
DEBUG:can.ctypesutil:Wrapped function "vciInitialize", result type: <class '_ctypes.PyCSimpleType'>, error_check <function __check_status at 0x0000029043D0A9D0>
DEBUG:can.ctypesutil:Wrapped function "vciFormatError", result type: <class 'NoneType'>, error_check None
DEBUG:can.ctypesutil:Wrapped function "vciEnumDeviceOpen", result type: <class '_ctypes.PyCSimpleType'>, error_check <function __check_status at 0x0000029043D0A9D0>
DEBUG:can.ctypesutil:Wrapped function "vciEnumDeviceClose", result type: <class '_ctypes.PyCSimpleType'>, error_check <function __check_status at 0x0000029043D0A9D0>
DEBUG:can.ctypesutil:Wrapped function "vciEnumDeviceNext", result type: <class '_ctypes.PyCSimpleType'>, error_check <function __check_status at 0x0000029043D0A9D0>
...
DEBUG:can.ctypesutil:Wrapped function "canSchedulerStopMessage", result type: <class '_ctypes.PyCSimpleType'>, error_check <function __check_status at 0x0000029043D0A9D0>
DEBUG:can.interface.detect_available_configs:interface "ixxat" does not support detection of available configurations
Now the explanation:
I know for sure, there are adapters made by ixxat that have one or two interfaces. I use some of them and maybe there are some with more channels.
Back to the problem: detect_available_configs does not simply open the interface and tries all combinations. It forwards the work to the backends. Each bus interface needs to implement a method called '_detect_available_configs'. The function _detect_available_configs is not implemented for ixxat interface. So it falls back to the BusABC implementation, which raises the NotImplementedError. The logger used by detect_available_configs logs on level debug, so you don't see it normally.
From my point of view some working points arise:
import can
import logging
log = logging.getLogger('can.interface')
log_autodetect = log.getChild('detect_available_configs')
log_autodetect.setLevel(logging.DEBUG)
can.interface.detect_available_configs()
Can be used to get info about which interface implements the detection:
DEBUG:can.interface.detect_available_configs:interface "usb2can" can not be loaded for detection of available configurations
DEBUG:can.interface.detect_available_configs:interface "ixxat" does not support detection of available configurations
ERROR:can.interfaces.nican:Failed to load NI-CAN driver: Could not find module 'nican' (or one of its dependencies). Try using the full path with constructor syntax.
DEBUG:can.interface.detect_available_configs:interface "nican" does not support detection of available configurations
WARNING:can.interfaces.iscan:Failed to load IS-CAN driver: Could not find module 'iscandrv' (or one of its dependencies). Try using the full path with constructor syntax.
DEBUG:can.interface.detect_available_configs:interface "iscan" does not support detection of available configurations
DEBUG:can.interface.detect_available_configs:interface "virtual" detected 1 available configurations
WARNING:can.interfaces.ics_neovi.neovi_bus:You won't be able to use the ICS NeoVi can backend without the python-ics module installed!: No module named 'ics'
WARNING:can.interfaces.ics_neovi.neovi_bus:Using ICS NeoVi can backend without the filelock module installed may cause some issues!: No module named 'filelock'
DEBUG:can.interface.detect_available_configs:interface "neovi" detected 0 available configurations
WARNING:can.interfaces.vector.canlib:Could not import vxlapi: Could not find module 'vxlapi64' (or one of its dependencies). Try using the full path with constructor syntax.
DEBUG:can.interface.detect_available_configs:interface "vector" detected 0 available configurations
WARNING:can.interfaces.slcan:You won't be able to use the slcan can backend without the serial module installed!
DEBUG:can.interface.detect_available_configs:interface "slcan" does not support detection of available configurations
DEBUG:can.interface.detect_available_configs:interface "canalystii" does not support detection of available configurations
WARNING:can.systec:Cannot load SYSTEC ucan library: Could not find module 'usbcan64.dll' (or one of its dependencies). Try using the full path with constructor syntax..
WARNING:can.systec:The SYSTEC ucan library has not been initialized.
DEBUG:can.interface.detect_available_configs:interface "systec" detected 0 available configurations
Better than nothing, yet doesn't nicely solve my problem, though.
Having some interfaces not being fully supported jeopardize their use unless we know for sure what they can do before connecting them to the bus. The CAN interface being live, trying combinations blindly kills the bus.
Better stick to known channels' identifier and compatible baud-rates. I'll have to store known working combinations locally.
Thank.
5. Listing all available baudrates would blow up the list. Especially with CAN-FD (many arbitration-bitrate and data-bitrate combinations lead to a long list). Maybe test and include the standard baudrates only? E.g. 10, 20, 50, 100, 125, 250, 500, 800 1000 kbaud ? For can-fd I think we should go for the 250, 500, 1000 kBaud with a multiplier of 2, 4, 8, 10 (I don't list all the commonly used ones here). The standard may include some recommended combos.
I understand that there may be many baudrates available, it was mostly to feed a combobox with "standard" rates. Yet some can adapters do not support 1M hence it would be pointless to pretend the user can select that speed if in fact it cannot.
I also reiterate
It would be great to have something like :
import can
can.interface.detect_available_configs()
[...]
[{'interface': 'virtual', 'channel': 'channel-3439'},
{'interface': 'neovi', 'serial': '120216', 'channels': {'1': [1000000, 500000, 250000, 125000], '2': [1000000, 500000, 250000, 125000]}},
{'interface': 'ixxat', 'serial': 'abcdef', 'channels': {'0': [1000000, 500000, 250000, 125000]}}]
Because as you can see, not all adapters count the channels the same way, and again, it would be super handy to know in advance what an adapter can do without having to trash the can bus trying every combination.
Don't the adapters' driver have a declarative interface you can probe their capabilities with ?
Regards.
OK. I'm working on this. And I made an generalized addition to the BusABC which should be rolled out to all interfaces. The term serial in the example above is a bit too specific, but the idea is good. I changed it to adapter - this can be used for tree structures (like the port in USB tree oder PCI too and does not imply that there is something like an serializing number for the actual interface device. For serial ports you might use the com-port number or the place in device tree (windows has adopted this concept from linux many years ago but hides it).
Current state is that it is possible to list all adapters.
>>> from can.interfaces.ixxat import IXXATBus
>>> for hwid in IXXATBus.list_adapters():
... print("Found IXXAT adapter with hardware id '%s'." % hwid)
Found IXXAT adapter with hardware id 'HW441489'.
Found IXXAT adapter with hardware id 'HW107422'.
Generating the the configurations will be the next step.
Looks promising...
Yeah, 'serial' is more 'sn', which the adapters are often identified with a sticker on them. Helps to identify them apart when you have several attached on your computer.
The 'ixxat' interface is not detected with
python-can 3.3.4
:If I loop on all interfaces, I can detect it though :
Yet trying all channels and all baud-rates pretty much hurts the CAN bus a lot (if not resilient to such invasion).
Regards.
Originally posted by @Kochise in https://github.com/hardbyte/python-can/issues/303#issuecomment-964886754