Forum: PC-Programmierung CANopen mit ftd2xxj unter Linux


von Vladimir W. (Firma: Student) (vladimir)


Lesenswert?

Hallo liebe Forummitglieder,

ich habe ein generelles Problem, mit der Funktionalität des CANs unter 
Linux und meiner Wissensmangel in dieser Fachrichtung.

Ich habe die Aufgabe bekommen unter Linux, eine komplette 
Maschinensteuerung zu realisieren. Diese soll über ein CAN-Protokoll 
gesteuert werden. Dazu wurde die Hardware von Lawicel bestellt.

Der Link: http://www.canusb.com/

Die Hardware und den Treiber habe ich bereits eingerichtet, funktioniert 
wunderbar. Da ich aber ein Java Programmierer bin, habe ich nach 
Möglichkeiten gesucht diesen Treiber über JNI oder JNA in Java 
einzubinden.
Diese Möglichkeit habe ich ebenfalls gefunden in dem ich bereits fertige 
Bibliothek von Mike Werner genommen habe.

Von FTDI: http://www.ftdichip.com/
Direkt: http://sourceforge.net/projects/ftd2xxj/

Nach dem einbinden, lief auch dieser Part.

Jetzt kommt mein Problem, ich hatte noch nie Umgang mit dem CAN. Ich 
weiß auch nicht wie ich diesen anspreche. Aus den Beispielen habe ich 
mir folgende Testklasse zusammengebastelt:

package nativeifc;

import com.ftdichip.ftd2xx.*;
/**
 *
 * @author ******
 */
public class Main
{
    public static void main(String args[])
    {
        try
        {
             //Deviceliste erstellen
             Device[] devices = Service.listDevices();
             //Das erste gefundene Device verwenden
             Device device = devices[0];
             //Device oeffnen
             device.open();
             //Den Port von dem Device, bestimmen
             Port port= device.getPort();
             System.out.println("Port: "+port);

             //Die Bbadrate setzen
             port.setBaudRate(0x0500);

             byte[] CAN_Identifier= new byte[6];
             int i=0;
             while(i<10000)
             {
                 CAN_Identifier[0]=02;

                 CAN_Identifier[1]=02;
                 CAN_Identifier[2]=00;
                 CAN_Identifier[3]=10;
                 CAN_Identifier[4]=10;
                 CAN_Identifier[5]=10;

                 device.write(CAN_Identifier,0,6);
                 i++;
             }
             device.close();
        }
        catch(Exception e)
        {
            System.err.println("!!!FEHLER!!! :"+e);
        }
    }
}

In dieser starte ich meine Versuche, dies allerdings ohne Erfolg, an der 
Hardware passiert einfach nichts. Vielleicht hat sich Jemand mit 
ähnlichen Themen beschäftigt und kann mir ein wenig auf die Sprünge 
helfen.

Gruß Vladimir

von Mark B. (markbrandis)


Lesenswert?

Nix gegen Java, aber gerade für einen Hardware-Treiber bietet sich die 
Sprache nicht unbedingt an. Nimm C oder meinetwegen C++, wenn's 
unbedingt ein objektorientierter Treiber sein muss :-)

von Vladimir W. (Firma: Student) (vladimir)


Lesenswert?

Der Treiber ist doch bereits in C, ich habe nur die Einbindung an Java 
mittels JNI implementiert. Was mir Schwierigkeiten bereitet, ist die 
Kommunikation mit dem CAN und die Ansteuerung der Geräte. Auch mit C 
oder C++ wüsste ich jetzt nicht wie ich meine Maschinerie in Bewegung 
setze. Deswegen die Frage ob überhaupt der Ansatz richtig gewählt wurde. 
Unter Windows funktioniert diese Hardware dort wird aber ein anderer 
Treiber geladen.
Link:  https://jd2xx.dev.java.net/

Problem der Läuft nicht unter Linux! Ich hoffe dennoch das mir jemand 
erzählen kann wie ich mittels ftd2xxj über CAN kommuniziere.

von Mark B. (markbrandis)


Lesenswert?

Hm, die Zeile versteh ich nicht ganz:
1
while(i<10000)

Warum zehntausend mal?
Ansonsten, CAN ID setzen klingt gut, aber dann willst Du ja noch mit 
dieser ID ein Telegramm senden. Für den Empfang verwendet man 
üblicherweise einen Ringpuffer. Schon mal so einen angelegt? Schau auch 
mal in den Sourcecode vom Treiber, falls noch nicht geschehen.

Siehe auch hier:
http://en.wikipedia.org/wiki/Controller%E2%80%93area_network#Frames

von Vladimir W. (Firma: Student) (vladimir)


Lesenswert?

Es ist nur ein Test, ich wollte nur probieren ob überhaupt was auf der 
Leitung passiert. Ich weiß auch nicht, ob ich das ganze richtig aufbaue.
Die while Schleife hat da prinzipiell nichts zu suchen, ist nur eine 
Testmassnahme.

von Volker Z. (vza)


Lesenswert?

Vladimir Petrenko schrieb:

>              //Die Bbadrate setzen
>              port.setBaudRate(0x0500);

Bist du sicher das du die Bitrate des CAN-Kontrollers setzt?
Wenn, wie üblich die baudrate in kb/s angegeben wird ist 1280 kb/s weder 
eine übliche bitrate, noch liegt sie innerhalb der max. bitrate.

>
>              byte[] CAN_Identifier= new byte[6];

Ein CAN-Identifieer hat entweder 11 bit oder 29 bit. Du brauchst also 
entweder ein 2-Byte oder ein 4-Byte Datentyp, nie ein 6-Byte Datentyp.
Desweiteren fehlen die Länge der Daten und die Daten (bis zu 8 Bytes) 
selber. Stellt der Treiber keine Strucktur zur Datenübertragung bereit?

Der Einstieg in den CAN-Bus ist sehr hart. Wenn man ihn erstmal zum 
laufen gebracht hat, ist er einfacher zu benutzen als RS232.
Ohne ein Oszilloskop und/oder einen laufenden Bus den du erst mal nur 
liest, wirst du nicht auf einen grünen Zweig kommen.

Wie aus deines Listings zu ersehen ist, hast du absolut keine Erfahrung 
mit dem CAN-Bus.
Mein Rat: Erst mal etwas Grundlagen erlesen!!!

von Vladimir W. (Firma: Student) (vladimir)


Lesenswert?

Ich kann nochmals hier aufführen was ich weiß und was zu Verfügung 
steht.
Den Device kann ich bereits öffnen.

//Deviceliste erstellen
Device[] devices = Service.listDevices();
//Das erste gefundene Device verwenden
Device device = devices[0];
//Device oeffnen
device.open();
//Den BitBangModus könnte ich auch setzen
device.setBitBangMode(Integer.SIZE, 
BitBangMode.FAST_OPTO_ISOLATED_SERIAL);

//Danach wird der Port ausgelesen.
Port port= device.getPort();
//ich setze die Portbaudrate.
port.setBaudRate(500);
//Ich könnte die DataCaracteristic setzen
port.setDataCharacteristics(DataBits.DATA_BITS_8, StopBits.STOP_BITS_1, 
Parity.NONE);
//oder den FlowControl
port.setFlowControl(FlowControl.NONE);

Das funktioniert auch, allerdings weiß ich nicht wie ich damit ein Frame 
aufbaue und damit den CAN in Bewegung setze. Vielleicht habe ich auch 
den falschen Ansatz gewählt.
Ich werde mich mit dem CAN beschäftigen. Vielleicht kriege ich noch ein 
paar Tipps von Euch wo ich die Infos bekomme. Danach werde ich hier ein 
laufendes Beispiel rein stellen.

von Stefan K. (syliosha)


Lesenswert?

Soweit ich das bis jetzt sehe verwechselst du da momentan einiges.
Wenn du dir die Beschreibung genauer anguckst läuft das so ab das der 
FTDI-Chip als USB-Serial-Converter dient indem er einen neuen COM-Port 
aufmacht. Danach brauchst du die zweite Bibliothek für die serielle 
Kommunikation, die dann die Befehlssätze beinhalten um den 
CAN-Controller zu etwas zu bringen.

mfg
Stefan

von Vladimir W. (Firma: Student) (vladimir)


Lesenswert?

Ja, Stefan Du hast recht. Ich bin auf dem falschen Pferd geritten und 
dazu noch in eine falsche Richtung. Ich muss den Chip nur die Ausgaben 
übergeben. Dieser setzt sie in CAN Befehle um. Hier ein Beispielcode in 
Java. Dieser funktioniert aber immer noch nicht, der Ansatz ist jetzt 
aber Richtig:
1
package nativeifc;
2
3
import com.ftdichip.ftd2xx.*;
4
import java.io.*;
5
/**
6
 *
7
 * @author Petrenko Vladimir
8
 */
9
public class Main
10
{
11
    public static void main(String args[])
12
    {
13
        try
14
        {
15
16
             //Devicelist
17
              Device[] devices = Service.listDevices();
18
             //Use Device 0
19
             Device device = devices[0];
20
             if (devices.length == 0) {
21
                System.out.println("Devices Not Found");
22
                System.exit(1);
23
             }
24
25
             for (int i = 0; i < devices.length ; i++)
26
             {
27
              System.out.println("Got Device: " + devices[i]);
28
             }
29
30
             //Device open
31
             device.open();
32
             //Set Timeout
33
             device.setTimeout(3000);
34
35
             DeviceDescriptor desc = device.getDeviceDescriptor();
36
37
             System.out.println("Manufacturer: "+desc.getManufacturer());
38
             System.out.println("Serialnumber: "+desc.getSerialNumber());
39
             System.out.println("Description: "+desc.getProductDescription());
40
41
             //Make OutputStreamer to write out
42
             //BufferedOutputStream out= new BufferedOutputStream(device.getOutputStream());
43
             OutputStream out= new BufferedOutputStream(device.getOutputStream());
44
45
             //Baudraterate for CAN 500Kbit
46
             String commandBR = "S6[CR]";
47
             byte [] command = commandBR.getBytes();
48
             String str= new String(command);
49
             System.out.println(str);
50
             //device.write(command);
51
             out.write(command,0,6);
52
             out.flush();
53
54
             //CAN Channel open
55
             String commandOpen = "O[CR]";
56
             byte [] commandO = commandOpen.getBytes();
57
             String str1= new String(commandO);
58
             System.out.println(str1);
59
             //device.write(commandO);
60
61
             out.write(commandO,0,5);
62
             out.flush();
63
64
             //Write x500 same data
65
             int i=0;
66
             while(i<5000)
67
             {
68
                 System.out.print(i+" ");
69
             //Transmit 11bit CAN Frame
70
             //Identifier ID=21
71
             //2 bytes
72
             //Value Ox11 and 0x33
73
             String commandFrame = "T00000014400010000";
74
             byte [] commandF = commandFrame.getBytes();
75
             String str2= new String(commandF);
76
             System.out.println(str2);
77
             //device.write(commandF);
78
79
             out.write(commandF,0,16);
80
             out.flush();
81
             i++;
82
             }
83
84
             byte [] readBuffer = new byte[50];
85
             device.read(readBuffer);
86
             System.out.println("Read Data : " +new String(readBuffer));
87
88
             //CAN Channel close
89
             String commandClose = "C[CR]";
90
             byte [] commandC = commandClose.getBytes();
91
             String str3= new String(commandC);
92
             System.out.println(str3);
93
             //device.write(commandC);
94
95
             out.write(commandC,0,5);
96
             out.flush();
97
98
             device.close();
99
        }
100
        catch(Exception e)
101
        {
102
            System.err.println("!!!ERROR!!! :"+e);
103
        }
104
    }
105
}

von Rolf Magnus (Gast)


Lesenswert?

> String commandBR = "S6[CR]"

Meine Vermutung ist, daß du alle "[CR]" besser durch "\r" ersetzen 
solltest.

von Vladimir W. (Firma: Student) (vladimir)


Lesenswert?

Hi Leute, wollte mich nur nochmal bei euch allen bedanken. Rolf du hast 
auch recht, nach dem ersetzen sprang der Bus an ([CR] durch \r)!
Ich werde in kürze, eine Schritt für Schritt Anweisung hier rein stellen 
und zeigen wie die Treiberanbindung mit Java funktioniert.

von Alex (Gast)


Lesenswert?

Hallo, ich stehe nun vor einem vergleichbaren Problem, nur dass ich die 
CAN Module nur über einen CAN to Ethernet Adapter ansprechen können 
soll. Hierbei geht die Kommunikation über das Internet und dann weiter 
über eine Java Anwendung zu einer Webausgabe um diverse Änderungen von 
Zuständen zu visualisieren.

Gibt's deine Beschreibung schon irgendwo bzw hat jemand eine Idee welche 
Hardware hier verwendbar ist. Bevorzugt mit einem Buffer, damit man 
keine Probleme bei der Datenübertragung bekommt.

Lg

Alex

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
Noch kein Account? Hier anmelden.