Hallo,
um Analogwerte einer DMS-Messbrücke auszuwerten bekomme ich bald diesen
Can-Bus A/D Wandler:
http://www.microcontrol.net/produkte/io-module/trs/1-x-druck-in/
Die Kommunikation läuft über eine Art Raspberry Pi (ARM A7 Prozessor mit
Linux OS und integriertem CAN Port). Ich möchte allersings "nur" den
Analogwert zyklisch (50 Hz) auslesen. Ich habe bisher keinerlei
Erfahrung mit CANopen und möchte für dieses Projekt die Implementierung
sehr einfach halten. Ich benötige die speziellen Heartbeat und
Statusabfragen nicht die mit CANopen liefern könnte.
In der EDS Datei vom Hersteller finde ich folgende Einträge:
;--- 7100h: AI Field Value 16Bit ------------------------------------
[7100]
SubNumber=2
ParameterName=AI Field Value 16Bit
ObjectType=0x08
[7100sub0]
ParameterName=Number of entries
ObjectType=0x7
DataType=0x5
AccessType=ro
DefaultValue=0x1
PDOMapping=0
[7100sub1]
ParameterName=Channel 1
ObjectType=0x7
DataType=0x6
AccessType=ro
DefaultValue=0x00
PDOMapping=1
;--- 7130h: AI Process Value 16Bit ----------------------------------
[7130]
SubNumber=2
ParameterName=AI Process Value 16Bit
ObjectType=0x08
[7130sub0]
ParameterName=Number of entries
ObjectType=0x7
DataType=0x5
AccessType=ro
DefaultValue=0x1
PDOMapping=0
[7130sub1]
ParameterName=Channel 1
ObjectType=0x7
DataType=0x3
AccessType=ro
DefaultValue=0x00
PDOMapping=1
In meiner bisherigen Suche habe ich öfter gelesen, dass man die Daten
einfacher über SDO auslesen kann. Warum?
http://stackoverflow.com/questions/1232624/how-to-program-a-simple-canopen-layer
Ich habe jetzt schon einige Handbücher und Foreneinträge gelesen, steige
aber mit den PDO und SDO von CANopen nicht so richtig durch. Wie läuft
so eine Kommunikation denn genau ab?
Wenn ich das richtig verstanden habe, dann sieht ein CANopen Telegramm
so aus:
Identifier - DLC - DATA (byte0 - byte7)
wobei der Identifier mit den ersten 4 Bit den Service (zB 1100 für SDO
lesen) und den restlichen 7 Bit die Node-ID festlegt. Aber wo genau
finde ich denn den Analogwert wieder?
Ich stelle mir mein Programm im Moment so vor, dass ich eine fest
definiertes Anfrage-Telegramm über CAN sende und im Anschluss die
Antwort mit dem Analogwert erhalte. Ich nutze dabei SocketCAN unter
Linux.
Als "Vorlage" könnte ich mir dieses Projekt vorstellen:
https://www.raspberrypi.org/forums/viewtopic.php?p=444938
Hier wäre der Code-Teil für das CAN-Telegramm:
struct can_frame frame_led;
frame_led.can_id = 0x300 + NodeId; // use all led 8 bit resolution
TPDO output
frame_led.can_dlc = 3; // only 3 bytes Red,Green and blue
frame_led.data[0]=Red;
frame_led.data[1]=Green;
frame_led.data[2]=Blue;
write(sfd,&frame_led,sizeof(struct can_frame));
Deine Vorlage scheint aber für eine PDO zu sein.
Bei den PDOs bestimmt nur die ID den Inhalt und alle 8 möglichen
Daten-Bytes können auch Daten enthalten.
Bei CANopen sind die IDs in feste Bereiche eingeteilt:
Eine ID wird aus einer Basis und einer Bus ID gebildet.
Die Basis für SDO Anfragen von deinem Master wäre 0x600 + die ID des
Sensors. Bei 3 Sensoren z.B. 0x601, 0x602, 0x603
Ein SDO Transfer zur Abfrage des Sensorwertes würde aus einem Request
CO_REQ_SDO_RD und einer Response CO_RES_SDO_RD_x bestehen.
Bei SDOs sind die ersten 4 Bytes der Daten gar keine Daten, sondern
Identifyer. Das erste wäre zum Beispiel der REQUEST, der Beschreibt, was
für einen Zugriff gemacht werden soll. (Lesen, schreiben und wie viel
Bytes)
Dann kommen zwei OBJECT-Bytes und ein SUBINDEX die praktisch die Adresse
des Parameters (z.B. DMS Daten) angeben.
Einer von mir verwendete Nachrichten-Struktur sieht so aus:
1
typedefstruct{
2
CANOPEN_COBIDcobID;
3
CANOPEN_RTF_DLCrtf_dlc;
4
union{
5
struct{
6
CANOPEN_REQrequest;
7
quint16object;
8
quint8subindex;
9
quint32data_sdo;
10
};
11
struct{
12
quint64data_pdo;
13
};
14
};
15
}CANOPEN_MESSAGE
Für den Request gibt es zum Beispiel folgende Möglichkeiten:
Vielen Dank. Aber worin besteht denn der Unterschied die Daten per SDO
oder PDU abzufragen?
Ich habe nun aus dem Raspberry und deinem Code etwas zusammengebastelt:
1
#include<stdio.h>
2
#include<stdlib.h>
3
#include<unistd.h>
4
#include<string.h>
5
#include<ctype.h>
6
#include<stdint.h>
7
8
#include<sys/types.h>
9
#include<sys/socket.h>
10
#include<sys/ioctl.h>
11
#include<sys/uio.h>
12
#include<net/if.h>
13
14
#include<linux/can.h>
15
#include<linux/can/raw.h>
16
17
#define node_id 127;
18
19
typedefenum{
20
COBID_NMT=0x000,
21
COBID_SYNC=0x080,
22
COBID_TIMESTAMP=0x100,
23
COBID_EMERGENCY=0x080,
24
//Prozessdatenobjekte
25
COBID_RXPDO1=0x180,//RX Empfangs-PDO
26
COBID_TXPDO1=0x200,//TX Sende-PDO
27
COBID_RXPDO2=0x280,
28
COBID_TXPDO2=0x300,
29
30
COBID_RXSDO=0x580,//Servicedatenobjekte
31
COBID_TXSDO=0x600,
32
COBID_NMT_LNG=0x700
33
}CANOPEN_COBID;
34
35
typedefenum{
36
CMD_TX=0x22,
37
CMD_TX_4=0x23,
38
CMD_TX_3=0x27,
39
CMD_TX_2=0x2B,
40
CMD_TX_1=0x2F,
41
CMD_RX=0x40,
42
CMD_RX_1=0x40,
43
CMD_RX_2=0x40,
44
CMD_RX_3=0x40,
45
CMD_RX_4=0x40
46
}CANOPEN_CMD;
47
48
structCANopen_message{
49
CANOPEN_COBIDid;
50
uint8_tdlc;
51
CANOPEN_CMDcmd;
52
uint16_tindex;
53
uint8_tsubindex;
54
chardata[4];
55
};
56
57
intmain(intargc,char*argv[])
58
{
59
structsockaddr_canaddr;
60
structifreqifr;
61
intsfd,ai_val;
62
63
// open part SocketCAN
64
sfd=socket(PF_CAN,SOCK_RAW,CAN_RAW);
65
if(sfd<0){
66
perror("socket : ");
67
return-1;
68
}
69
70
strcpy(ifr.ifr_name,"can0");// "can0" is the name of the CAN network interface
Ich kann das Programm leider noch nicht testen, da ich den Sensor erst
in 2 Wochen bekomme. Da ich auch in C-Programmierung noch recht
unerfahren bin, bin ich für jegliches Feedback dankbar :)
Die PDOs werden automatisch in gewissen Zeitabständen geschickt.
(nachdem man das so konfiguriert hat)
Es gibt keine Requests, Index/Subindex. Die Daten beginnen sofort.
Anhand der PDO Nr. weiß man um welche Daten es sich handelt.
Wenn der DMS Messwert auf PDO1 gemappt ist und der Sensor die Busadresse
1 hat, dann bekommt man in regelmäßigen Zeitabständen automatisch die
Nachricht
id -> 0x181
dlc -> 2
daten -> 16bit Messwert
Hendrik S. schrieb:> Aber worin besteht denn der Unterschied die Daten per SDO> oder PDU abzufragen?
SDO - Service Data Object :
- Ist ein bestätigter Dienst. Du erhälst eine Bestätigung, ob der Wert
übernommen wurde, gültig ist oder der Wert überhaupt existiert.
- Kann für beliebige Einträge im Objektverzeichnis entsprechend der
Zugriffsrechte genutzt werden.
- Es gehen auch Daten größer 8 Byte.
- Es wird ein Gerät direkt angesprochen.
- Wird häufig zur Konfiguration genutzt.
PDO - Process Data Objekt :
- Wird für Echtzeitdaten genutzt.
- Es kommt auf das Mapping der PDOs ab, welche Daten übertragen werden.
Diese sind nicht beliebig.
- max. 8 Byte
- mehrere Objekte (Werte) gleichzeitig möglich, solange die 8 Byte nicht
überschritten werden.
- Es gibt verschiedene Events, die das Senden/Empfangen der PDOs steuern
können.
- PDOs müssen konfiguriert werden
- PDOs gehen nur im NMT Operational State
- PDOs ist Broadcast Dienst, d.h. es kann mehrere Empfänger geben.
(Man verzeihe mir, das einiges etwas lax fomuliert ist.)
http://www.can-cia.org/standardization/specifications/#
Der Standard CiA 301 beschreibt die Kommunikation. Du must dich
registrieren, ansonsten ist der Download aber kostenfrei.
Der Standard ist weniger zum Lernen geeignet. Aber wenn es um Details
geht gut zum Nachschlagen. Wer CANopen macht, sollte ihn liegen haben.
wäre ja auch nicht schlecht. So eine Einstellung macht man am besten
über einen CANopen Manager am PC? Ich habe mir den Kickdrive Zero dazu
installiert und die EDS Datei eingelesen.
Hendrik S. schrieb:> So eine Einstellung macht man
Wenn der Sensor das Speichern der Konfiguration erlaubt, kann man diese
am PC erstellen, runterschaffen und speichern. Manchmal kann man die
Geräte auch Selbststartend konfigurieren, d.h. sie gehen eigenständig
nach NMT Operational.
Hierfür muß man in die Gerätebeschreibung sehen oder den Hersteller
befragen.
Wenn man sich auskennt, kann man es auch einfach ausprobieren. Als
Anfänger ist man aber häufig am zweifeln, ob man alles richtig gemacht
hat.
Steffen R. schrieb:> Wenn der Sensor das Speichern der Konfiguration erlaubt, kann man diese> am PC erstellen, runterschaffen und speichern. Manchmal kann man die> Geräte auch Selbststartend konfigurieren, d.h. sie gehen eigenständig> nach NMT Operational.
Ja, die "NMT Startup" Konfiguration gibt es für die MicroControl
A/D-Wandler. Dazu gibt es auch den "PDO Event Timer", der wohl für
meinen Zweck richtig wäre.
Zur Konfiguration kann ich mich dann einfach mit einem USB/CAN-Adapter
mit dem Gerät verbinden und die entsprechenden Parameter anpassen. Ich
habe als Freeware CANopen Programm bis jetzt nur den Kickdrive Zero
http://www.kickdrive.de/en/index.html?products_kickdrive_zero.htm
gefunden. Gibt es da auch etwas für Linux?
Hast du denn schon einen USB/CAN Adapter?
Du kannst doch die Konfiguration direkt von deiner "Art Raspberry" aus
durchführen. Dazu müssen nur die entsprechenden Objekte (über SDO)
richtig beschrieben werden.
Die Kommunikation musst du doch eh programmieren. Die ersten Schritte
kannst du ja über die SDOs machen. Wenn du das drauf hast, dann ist die
Konfiguration kein Problem mehr...
Hendrik S. schrieb:> Zur Konfiguration kann ich mich dann einfach mit einem USB/CAN-Adapter> mit dem Gerät verbinden
Die API ist nicht standardisiert. Insofern müßtest Du schauen, welchen
CAN Adapter du nutzen möchtest.
Unter Linux ist die socketCAN API weit verbreitet und Teil des Kernels.
Volker S. schrieb:> Hast du denn schon einen USB/CAN Adapter?
ich habe mir gestern den USBtin von Thomas Fischl bestellt:
http://www.fischl.de/usbtin/Volker S. schrieb:> Du kannst doch die Konfiguration direkt von deiner "Art Raspberry" aus> durchführen. Dazu müssen nur die entsprechenden Objekte (über SDO)> richtig beschrieben werden.> Die Kommunikation musst du doch eh programmieren. Die ersten Schritte> kannst du ja über die SDOs machen. Wenn du das drauf hast, dann ist die> Konfiguration kein Problem mehr...
Naja, wenn ich den Sensor vorher am PC so einstelle, dass er zyklisch
die Daten per PDO sendet, brauch ich ja auf dem Raspberry nur noch den
entsprechenden Teil der CAN Message auswerten. Wäre vielleicht etwas
"eleganter".
Steffen R. schrieb:> Unter Linux ist die socketCAN API weit verbreitet und Teil des Kernels.
Ja die socketCAN unter Linux kenn ich, aber das ist ja kein CANopen
Manager mit dem ich ESD Dateien direkt einlesen kann. Aber mit dem
Windows Tool von Kickdrive werde ich wohl auch zurecht kommen.
Hendrik S. schrieb:> Volker S. schrieb:>> Hast du denn schon einen USB/CAN Adapter?> ich habe mir gestern den USBtin von Thomas Fischl bestellt:> http://www.fischl.de/usbtin/
Na dann hast du ja auch PC Software, welche du verwenden kannst...
Hendrik S. schrieb:> Ja die socketCAN unter Linux kenn ich, aber das ist ja kein CANopen> Manager mit dem ich ESD Dateien direkt einlesen kann.
Da aber nicht jedes Tool alle Interfaces unterstützt, ist die
Entscheidung für eine API (socketCAN, can4linux usw.) relevant.
Freie CANopen Master Tools kenne ich nicht. Und ein freier CANopen
Master Stack hilft Dir ja nicht weiter.