CANopen - Schnelles auslesen von Messdaten

Gast #5446094
Lesenswert?

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 ;)
#5446175
Lesenswert?

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.
Persönliche Seite #5446214
Lesenswert?

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.
Gast #5446231
Lesenswert?

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...
Gast #5447309
Lesenswert?

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.
Gast #5447510
Lesenswert?

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.
Gast #5447519
Lesenswert?

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.
#5447596
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren