www.mikrocontroller.net

Forum: PC-Programmierung CANopen mit ftd2xxj unter Linux


Autor: Vladimir Windkraft (Firma: Student) (vladimir)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Vladimir Windkraft (Firma: Student) (vladimir)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, die Zeile versteh ich nicht ganz:
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%93ar...

Autor: Vladimir Windkraft (Firma: Student) (vladimir)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Volker Zabe (vza)
Datum:

Bewertung
0 lesenswert
nicht 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!!!

Autor: Vladimir Windkraft (Firma: Student) (vladimir)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Kunz (syliosha)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Vladimir Windkraft (Firma: Student) (vladimir)
Datum:

Bewertung
0 lesenswert
nicht 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:

package nativeifc;

import com.ftdichip.ftd2xx.*;
import java.io.*;
/**
 *
 * @author Petrenko Vladimir
 */
public class Main
{
    public static void main(String args[])
    {
        try
        {

             //Devicelist
              Device[] devices = Service.listDevices();
             //Use Device 0
             Device device = devices[0];
             if (devices.length == 0) {
                System.out.println("Devices Not Found");
                System.exit(1);
             }

             for (int i = 0; i < devices.length ; i++)
             {
              System.out.println("Got Device: " + devices[i]);
             }

             //Device open
             device.open();
             //Set Timeout
             device.setTimeout(3000);

             DeviceDescriptor desc = device.getDeviceDescriptor();

             System.out.println("Manufacturer: "+desc.getManufacturer());
             System.out.println("Serialnumber: "+desc.getSerialNumber());
             System.out.println("Description: "+desc.getProductDescription());

             //Make OutputStreamer to write out
             //BufferedOutputStream out= new BufferedOutputStream(device.getOutputStream());
             OutputStream out= new BufferedOutputStream(device.getOutputStream());

             //Baudraterate for CAN 500Kbit
             String commandBR = "S6[CR]";
             byte [] command = commandBR.getBytes();
             String str= new String(command);
             System.out.println(str);
             //device.write(command);
             out.write(command,0,6);
             out.flush();

             //CAN Channel open
             String commandOpen = "O[CR]";
             byte [] commandO = commandOpen.getBytes();
             String str1= new String(commandO);
             System.out.println(str1);
             //device.write(commandO);

             out.write(commandO,0,5);
             out.flush();

             //Write x500 same data
             int i=0;
             while(i<5000)
             {
                 System.out.print(i+" ");
             //Transmit 11bit CAN Frame
             //Identifier ID=21
             //2 bytes
             //Value Ox11 and 0x33
             String commandFrame = "T00000014400010000";
             byte [] commandF = commandFrame.getBytes();
             String str2= new String(commandF);
             System.out.println(str2);
             //device.write(commandF);

             out.write(commandF,0,16);
             out.flush();
             i++;
             }

             byte [] readBuffer = new byte[50];
             device.read(readBuffer);
             System.out.println("Read Data : " +new String(readBuffer));

             //CAN Channel close
             String commandClose = "C[CR]";
             byte [] commandC = commandClose.getBytes();
             String str3= new String(commandC);
             System.out.println(str3);
             //device.write(commandC);

             out.write(commandC,0,5);
             out.flush();

             device.close();
        }
        catch(Exception e)
        {
            System.err.println("!!!ERROR!!! :"+e);
        }
    }
}


Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> String commandBR = "S6[CR]"

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

Autor: Vladimir Windkraft (Firma: Student) (vladimir)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.