Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to import an OD-file correctly? #550

Open
ichCANdasnichtmehr opened this issue Nov 25, 2024 · 5 comments
Open

How to import an OD-file correctly? #550

ichCANdasnichtmehr opened this issue Nov 25, 2024 · 5 comments
Labels

Comments

@ichCANdasnichtmehr
Copy link

Hello,
i imported an DCF-File as OD-file and connected it with a node. This DCF-File includes a predefined heartbeat and a predefined PDO, which should be send on sync-messages. This works perfectly in the simulation (CANoe) but not at all on my Raspberry Pi 5. I can't see hearbeat, bootup message or any PDO.
As I understand it, the node should automatically send the contained messages, isn't it? So how should i implement the OD-file correctly to run these messages automatically?

Here is my current code:
`import canopen
import os
import time

os.system('sudo ip link set can1 type can bitrate 125000')
os.system('sudo ifconfig can1 up')

network = canopen.Network()

node = network.add_node(10, '/home/canuser2/Dokumente/PythonFile/EDS Files/D010.DCF')

network.connect(channel='can1', bustype = 'socketcan', bitrate=125000)

network.check()
`

And this is the used dcf file (converted to txt due to upload problems):
D010.txt

@acolomb
Copy link
Collaborator

acolomb commented Nov 25, 2024

There is no mechanism in this library to automatically start such communication based on the DCF contents. You will need to call these methods separately, while giving them the configured values from the parsed OD object:

node.nmt.start_heartbeat(node.od[0x1017].raw)  # from NmtSlave class
node.pdo.read(from_od=True)

For any of this to work, you should be using a LocalNode object, which you get from network.create_node() instead of .add_node().

Sending TPDOs automatically on SYNC reception is not supported out of the box I think. You'll need to subscribe to the SYNC message with a callback and then trigger the PDO's .transmit() method from there.

You're welcome to improve the LocalNode support in the library, if you think some of these features should be available. It is definitely less mature and less feature-complete than the RemoteNode functionality. But keep in mind there are vastly different use-cases for the library, so any automatic communication handling should be opt-in.

@ichCANdasnichtmehr
Copy link
Author

Thank you for your fast answer @acolomb . When i try the start_heartbeat command the compiler says "'LocalNode' object has no attribute 'od'". Furthermore it says the PDO object has no attribute 'transmit'.

@acolomb
Copy link
Collaborator

acolomb commented Nov 25, 2024

Sorry, that should be node.object_dictionary then. That code snippet was from the top of my head, you might need to try some small adjustments. The .transmit() call works on a specific PDO object, such as node.tpdo[1] or whichever you configured. You should examine what was parsed after node.pdo.read(from_od=True) and then start the ones that you need and which are enabled and have a synchronous transmission interval set. Unfortunately, there is quite some work involved on your part, since the whole LocalNode class has not been wired up into a fully-fledged CANopen slave device.

Whatever your application should do later on (keep a main-loop running or similar), you'll need to integrate with that anyways. So better design your code that responds with PDO content to fit your application, and treat the canopen library as only handling the actual encoding and transmission.

@ichCANdasnichtmehr
Copy link
Author

ichCANdasnichtmehr commented Nov 25, 2024

Hello again,
at first thank you very much for your answers. The heartbeat and the bootup messages are working now and i am able to transmit TPDO. Sadly the data field is filled with zeros although the pdo is mapped to an od entry where the default value and the parameter value are both unequal to zero. When I use the tpdo.map I can see that the entry is connected with the tpdo. Do you know maybe how i can connect an entry correctly to a tpdo?

In addition I would like to change a value of an object in the od-file. I couldn't find any commands for this in this library. Is it still possible?

Thank you for your help!

@acolomb
Copy link
Collaborator

acolomb commented Nov 25, 2024

Well there is no automatic connection between the OD values and the local TPDO mappings, as far as I know. You need to update the mapped variables' .raw or .phys properties before calling .transmit(). If you have it configured for periodic sending instead, then you should call .update() after setting new values.

In addition I would like to change a value of an object in the od-file.

You want to update the EDS / DCF file from the Python code? You can always import it, change some values in the resulting ObjectDictionary object, and then export it again as a DCF file using canopen.export_od(), see https://canopen.readthedocs.io/en/latest/od.html#canopen.export_od

In general, please do take a look at the API docs, as most available functionality is described there. Once you get your head wrapped around how the various service classes interact with the OD, it's pretty straightforward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants