Hi zusammen, und zwar möchte ich einen CANopen Sensor so schnell wie möglich auslesen. Der Sensor besitzt eine Zykluszeit von 0,5ms (2kHz). Durch den CANopen Eventtimer kann ich lediglich 1ms (=Eventtimer = 1) einstellen. Gibt es eine Möglichkeit die vollen 2kHz gesampleten Messdaten vom Sensor auszulesen? Bin noch nicht der Vollprofi was CANopen angeht ;)
Sanny schrieb: > Durch den > CANopen Eventtimer kann ich lediglich 1ms (=Eventtimer = 1) einstellen. > Gibt es eine Möglichkeit die vollen 2kHz gesampleten Messdaten vom > Sensor auszulesen? Wenn Du das Ausleseprogramm im Source editierst, neu compilierst, und dann nutzt: Ja, prinzipiell möglich.
Hallo, kenne natürlich deinen Sensor nicht, aber du könntest es, sofern die Position als Objekt abgelegt ist über einen SDO Transfer holen. Kann aber sein dass das auch nicht schneller abläuft weil z.B. die Sensorinterne CANopen eventloop nur mit 1ms ausgeführt wird.
Mein Sensor: https://www.jumo.de/produkte/druck/402056/jumo-cantrans-p---druckmessumformer-mit-canopen-ausgang-402056.html
Warum willst du den Sensor unbedingt auslesen? Das schöne bei canOpen ist doch, dass der Sensor von sich aus senden kann, wenn ein neuer Messwert vorliegt. Stichwort PDO
1 | Das PDO-Telegramm enthält den 32-Bit-Messwert und den 8-Bit-Status. Die Messwertausgabe ist über verschiedene Triggerbedingungen steuerbar. |
Zusätzlich bedeutet es nicht wenn das PDO zyklisch konfiguriert ist dass dann auch die Messung mit diesem Zyklus durchgeführt wird.
Mike R. schrieb: > Warum willst du den Sensor unbedingt auslesen? > > Das schöne bei canOpen ist doch, dass der Sensor von sich aus senden > kann, wenn ein neuer Messwert vorliegt. > > Stichwort PDO > Das PDO-Telegramm enthält den 32-Bit-Messwert und den 8-Bit-Status. Die > Messwertausgabe ist über verschiedene Triggerbedingungen steuerbar. Tut er wohl auch: Sanny schrieb: > CANopen Eventtimer kann ich lediglich 1ms (=Eventtimer = 1) einstellen Der Eventtimer lässt sich nun mal nu in 1ms Schritten einstellen. D.h. er kann höchstens versuchen per SDO an den Wert zu kommen oder den PDO auf Synchron zu stellen und per SYNC abzurufen. Ob das dann tatsächlich mit 0,5ms klappt ist allerdings fragwürdig.
Vllt kommt es ja mit dem Delta Event (TimerEvent=off). Sprich, sobald der Messwert sich ändert schickt er die PDO raus. Mein abzutastendes Signal entspricht ca. 400-500Hz. Heißt DeltaEvent=1 bei Auflösung 11bit -> 2048(=10bar) -> 0.005bar ? Oder welches Delta ist da gemeint? Und danke für die schnelle Antworten...
Probier doch mal Objekt 1800sub2 auf 1 zu setzen und per SYNC Nachricht (CAN-ID 80h) an das PDO zu kommen?!
Es ist möglich die Daten schneller als mit 1ms zu erhalten, indem man den EventTimer auf 1ms stellt und zusätzlich den Sensor mit RTR abfrägt. Ich arbeite mit Linux-SocketCAN (C++). Das zusätzliche RTR generiere mit einem linux bash script. Kennt sich einer aus wie man das RTR in C++ sendet? Mit der Doku.: https://www.kernel.org/doc/Documentation/networking/can.txt werde ich nicht wirklich schlau... danke.
Von RTR würde ich die Finger lassen. Damit kannst du dir einen Haufen Probleme einhandeln. Die CiA rät auch von der Verwendung von RTR ab.
Ich habe jeweils nur einen Sensor im "Start" Modus. Da sollte es keine Probleme gegeben.
Meine Erfahrungen mit RTR sind leider sehr negativ. Das ist auch egal wieviele Sensoren da dran hängen. Es sind in jedem Fall 2 CANController an der Kommunikation beteiligt. Die Implementierung vom RTR ist bei den Chips garantiert verschieden.
RTR ist von der CiA nicht empfohlen, weil Nebeneffekte den Bus lahmlegen können. Wenn man es entsprehend verwendet (nur ein Knoten, definierter sendetakt etc.) so funktioniert es jedoch meist sehr robust. Daher ist es einen Versuch wert, damit ein schnelleres Auslesen zu realisieren. Ansonsten ist es ein Versuch mit TimerEvent=off wert. Es kann aber auch hier sein, dass dort ein mindestabstand von 1ms implementiert ist. Aus der Jumo Anleitung, Kap. 5.5, S. 17 geht hervor, dass bei aktivierung des Toggle Mode 0x6150 bei jeder Messertänderung ein PDO gesendet wird. dabei sollte die Inhibot time (0x1800) deaktiviert sein.
Noch ein Hinweis: meist liefern Drucksensoren relative häufig neue Messwerte. Jedoch ist die Reaktionszeit, mit der auf eine Druckänderung eagiert wird, meist mit einer größeren Verzögerung im Millisekunden Bereich verbunden. Das sollte bei der Berechnung der Totzeit in einer Regelschleife beachtet warden.
Martin schrieb: > Wenn man es entsprehend verwendet (nur ein Knoten, definierter > sendetakt etc.) so funktioniert es jedoch meist sehr robust. Die Aussage ist definitv falsch. Lies dir mal die AN802 durch
Sanny schrieb: > Mit der Doku.: > https://www.kernel.org/doc/Documentation/networking/can.txt > werde ich nicht wirklich schlau... Es werden die ganz normalen Socket-Funktionen verwendet wie der Name schon sagt und der can controller taucht als Netzwerkinterface auf und kann in /etc/network/interfaces konfiguriert werden. Kein C++ aber Python3:
1 | FRAME_FMT = "=IB3x8s" |
2 | # The format of this struct is defined by the SocketCan API. |
3 | # Each letter in the comment below represents one byte, |
4 | # the frame struct that we send or receive looks as follows: |
5 | # |
6 | # iiii l... dddddddd |
7 | # |
8 | # where |
9 | # |
10 | # iiii = canid struct (a bitmap containing id and flags) |
11 | # l = dlc (data length in bytes, valid range: 0..8) |
12 | # ... = padding bytes |
13 | # dddddddd = data bytes (always 8, even if dlc < 8) |
14 | # |
15 | # The SocketCan API always needs all 8 data bytes to be |
16 | # present, even when dlc is smaller but of course it will |
17 | # still transmit only as many bytes on the wire as the |
18 | # dlc field says, the remaining bytes will be ignored. |
19 | FRAME_SIZE = struct.calcsize(FRAME_FMT) |
20 | |
21 | self.sock = socket.socket(socket.PF_CAN, socket.SOCK_RAW,socket.CAN_RAW) |
22 | self.sock.bind(("can0",)) |
23 | |
24 | |
25 | # im Schreib-Thread: |
26 | self.sock.send(raw_frame_structure) # always all 16 bytes |
27 | |
28 | |
29 | # im Lese-Thread (blockierend) |
30 | raw_frame_structure = self.sock.recv(FRAME_SIZE) # always 16 bytes |
> Kennt sich einer aus wie man das RTR in C++ sendet?
ich hab leider nur ein Beispiel für die Benutzung von SocketCAN in
Python. Das kann man aber wahrscheinlich 1:1 nach C(++) transferieren.
Irgendwo in der Socketcan doku ist das 16 bytige frame struct
deklariert, da musst Du nachschauen was Du für bits setzen musst um
einen RTR Frame zu erzeugen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.