Forum: PC-Programmierung UART-Daten eines FTDI-Chips in C# auslesen


von ben91 (Gast)


Lesenswert?

Hallo liebe Forenmitglieder!

Seit gut 3 Tagen bin ich für mein Praktikum damit beschäftigt,
ein Gerät, welches auf Basis eines FTDI-USB-Chips via UART 
ausgelesen/gesteuert werden kann, mit C# (und der entsprechenden 
C#-FTDI-Bibliothek) eine universal-Gerätesoftware zu schreiben.
Da ich jedoch in C# nur Grundkenntnisse besitze und mit der FTDI Serie 
auch noch nie gearbeitet habe, ist dies für mich eigentlich alles noch 
"Neuland".
Die Serienummer des Gerätes konnte ich mal schon auslesen und auch die 
Anzahl der angeschlossenen Geräte ermitteln.
Durch senden eines definierten ASCII-Strings via UART,
sollten anschließend die Daten aus dem Gerät ausgelesen werden.
Folgende Routine habe ich bisher programmiert,
und habe einen Bit-Stream erhalten,
bei welchen ich jedoch nicht weis,
wie ich diesen in C# als ASCII-Zeichen interpretieren lassen kann.
(Die Zeichen sollen übrigends zeilenweise eingelesen werden,
da das Gerät dies als Klartext an den PC sendet,
newline = <CR>+<LF>):
1
private void Open_FTDI_Device()
2
{
3
// Gerät mit aktueller Seriennummer öffnen
4
  ftStatus = myFtdiDevice.OpenBySerialNumber(GetSerialNumber()); 
5
// Baudrate mit 300 definieren 
6
  ftStatus = myFtdiDevice.SetBaudRate(300);
7
// Setzen von: 7 Datenbits, 1 Stopbit, "Even" als
8
// Parity                       
9
ftStatus = myFtdiDevice.SetDataCharacteristics(7, 1, FTDI.FT_PARITY.FT_PARITY_EVEN);    
10
}
11
12
private UInt32 read_from_device()        // lese-Routine für FTDI-Chip
13
{
14
    UInt32 recdata = 0;         // Variable für empfangene Daten definieren
15
    UInt32 numBytesWritten = 0;
16
    UInt32 numBytesToRead = 0;
17
    byte[] r = new byte[15];
18
19
    myFtdiDevice.GetRxBytesAvailable(ref numBytesToRead);
20
    byte[] received = new byte[numBytesToRead];
21
    myFtdiDevice.Read(received, numBytesToRead, ref numBytesWritten);
22
23
    recdata = Convert.ToUInt32(numBytesWritten);
24
25
    return recdata;             // empfangene Daten zurückgeben
26
}

Die serielle Schnittstelle besitzt folgende Parameter:
Baudrate:  300
Datenbits: 7
Stopbit:   1
Parity:    Even
new String:<CR>+<LF>

Hat jemand denn vielleicht eine Idee bzw. "Quellcode-Schnipsel",
wie ich dies realisieren kann?

Vielen dank bereits im Vorraus :-D

von Detlev T. (detlevt)


Lesenswert?

Und warum nimmst du nicht einfach ein entsprechendes Objekt 
(SerialPort?), das den (virtuellen) COM-Port benutzt?

von ben91 (Gast)


Lesenswert?

Hallo Detlevt!

Da ich wie gesagt noch ein C#-Anfänger bin, kann es sein,
dass folgende Frage vielleicht doof ist, aber:
Wie benutzt man einen virtuellen COM-Port in C#?
... meinst du also, den Chip einfach als USB-seriell-Wandler zu 
betrachten und anschließend mit einer "nicht FTDI-Bibliothek" 
auszulesen?
Wenn ja, kann man da dann auch die Baudrate umstellen?!

lg

von Peter II (Gast)


Lesenswert?

Wenn du schon soweit mit der FTDI Klasse bist, dann macht es keinen sinn 
es über den virtuellen-Com port zu machen, die umwandlung er Zahlen ist 
immer die gleiche.

Aber du sagst leider nicht was nicht geht? Steht denn in received etwas 
sinnvolles drin? Schau doch einfach mal im Debugger nach.

von ben91 (Gast)


Lesenswert?

Hallo PeterII!

Du meinst also, dass ich weiterhin mit der FTDI-Klasse arbeiten soll?
... das Problem ist eigentlich, dass ich nicht weiß, wie ich die binären 
Daten in C# in ein ASCII-Zeichen konvertiere :-(

lg

von Peter II (Gast)


Lesenswert?

ben91 schrieb:
> Du meinst also, dass ich weiterhin mit der FTDI-Klasse arbeiten soll?

ja, weil ja dort nicht dein Problem lieg.

> wie ich die binären Daten in C# in ein ASCII-Zeichen konvertiere :-(
http://dotnet-snippets.de/dns/string-in-byte-array-und-zurueck-wandeln-SID67.aspx

von noch son märklinist (Gast)


Lesenswert?

1
     UInt32 recdata = 0;         // Variable für empfangene Daten definieren
2
     UInt32 numBytesWritten = 0;
3
4
     recdata = Convert.ToUInt32(numBytesWritten);
5
6
     return recdata;             // empfangene Daten zurückgeben
ich kann zwar kein c#, aber das ergibt für mich einfach keinen Sinn.

ben91 schrieb:
> Da ich jedoch in C# nur Grundkenntnisse besitze und mit der FTDI Serie
> auch noch nie gearbeitet habe, ist dies für mich eigentlich alles noch
> "Neuland".
Mir haben in solchen Situationen immer Beispiele geholfen. Also such mal 
nach einem ordentlichen Beispiel und denke solange darüber nach bis du 
es Verstanden hast.

von ben91 (Gast)


Lesenswert?

Hallo PeterII!

Danke erstmal für deine Hilfe!

Ich habe jetzt mal versucht die Bits umzuwandeln.
Leider verstehe ich die FTDI-Empfangsroutine nicht mal,
und weiß deswegen auch nicht, wie ich das jetzt anstellen soll.
Bei der Konvertierung wird mir übrigends eine Fehlermeldubg angezeigt
(Fehler  1  Die beste Übereinstimmung für die überladene 
System.Text.Encoding.GetString(byte[])-Methode hat einige ungültige 
Argumente.

Fehler  2  1-Argument: Kann nicht von "uint" in "byte[]" konvertiert 
werden.)

hier der Quellcode dazu:
1
 private string read_from_device()            // lese-Routine für FTDI-Chip
2
 {
3
    string recdata;             // Variable für empfangene Daten definieren
4
    UInt32 numBytesWritten = 0; // Variable für empfangene Bits definieren
5
    UInt32 numBytesToRead = 0;  // Variable für verfügbare Bits definieren
6
    byte[] r = new byte[15];
7
8
//  Verfügbare Bitanzahl abfragen
9
    myFtdiDevice.GetRxBytesAvailable(ref numBytesToRead);   
10
//  neues Objekt als Datenbuffer erzeugen        
11
    byte[] received = 
12
new byte [numBytesToRead];       
13
// Bits seriell auslesen                         
14
myFtdiDevice.Read(received, numBytesToRead, ref numBytesWritten);
15
16
 // serielle Bits an Variable übergeben
17
// recdata = Convert.ToUInt32(numBytesWritten);                   
18
// Objekt für empfangene Bits defineren
19
   System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
20
// serielle Bits als string wandeln
21
   recdata = enc.GetString(numBytesWritten);      
22
                 
23
   return recdata;                // empfangene Daten zurückgeben
24
}

lg

von Peter II (Gast)


Lesenswert?

ben91 schrieb:
> recdata = enc.GetString(numBytesWritten);

denk doch mal bitte darüber nach was das hier soll? Was könnte 
"numBytesWritten" bedeuten? Eventuell "anzahl der Geschrieben bytes" 
Also wirst du damit wohl NIE an die Daten kommen.

Die Daten stehen in received!

von noch son märklinist (Gast)


Lesenswert?

Hier gibt es Super Beispiele:
http://www.ftdichip.com/Support/SoftwareExamples/CodeExamples/CSharp.htm

Lade dir das dritte Beispiel runter, lese es und verstehe es.
http://www.ftdichip.com/Support/SoftwareExamples/CodeExamples/CSharp/LoopBack.zip

ben91 schrieb:
> Ich habe jetzt mal versucht die Bits umzuwandeln.
Das brauchst du garnicht:
> // Note that the Read method is overloaded, so can read string or byte
> array data

von ben91 (Gast)


Lesenswert?

Hallo!

Erstmal danke für die ganzen Tips & Tricks!

Die Beispiele, wie auch das "Programmers Guide" von FTDI habe ich 
bereits heruntergeladen & versucht zu verstehen.

Da ich, wie gesagt, nicht nur bei der Verwendung der FTDI-Bibliothek, 
sondern auch in C# unerfahren bin,
ist dies für mich trotz super Beispiele eine Tortur,
etwas zu verstehen.

Verständnissfrage: was gibt die Funktion "myFtdiDevice.Read()" denn 
jetzt eigentlich für Daten zurück ... einzelne Bytes @ 7 Bit,
welche ich in ein ASCII-Zeichen umwandeln muss (8 Bit?!)
oder sämtliche Bits, welche gerade empfangen werden?

vielen Dank :-)

von Peter II (Gast)


Lesenswert?

ben91 schrieb:
> Verständnissfrage: was gibt die Funktion "myFtdiDevice.Read()" denn
> jetzt eigentlich für Daten zurück ... einzelne Bytes @ 7 Bit,
> welche ich in ein ASCII-Zeichen umwandeln muss (8 Bit?!)
> oder sämtliche Bits, welche gerade empfangen werden?

ich habe zwar keine Ahnung von FTDI aber das hier ist eigentlich 
selbsterklärend

myFtdiDevice.Read(received, numBytesToRead, ref numBytesWritten);

received - hier landen die Gelesen Daten
numBytesToRead - anzahl der bytes die man lesen will
numBytesWritten -  anzahl der gelesenen bytes

Und es sind immer 8bit - bytes. Auch wenn wenn du eine 7bit übertragung 
machst.

von Karl H. (kbuchegg)


Lesenswert?

ben91 schrieb:
> Hallo PeterII!
>
> Danke erstmal für deine Hilfe!
>
> Ich habe jetzt mal versucht die Bits umzuwandeln.
> Leider verstehe ich die FTDI-Empfangsroutine nicht mal,

Dein Problem ist, dass du dich nicht an den Wörtern orientierst. Ein gut 
geschriebenes Beispiel ist wie ein Prosatext, bei dem man die Füllwörter 
weglässt.

>     string recdata;             // Variable für empfangene Daten
> definieren

soweit so gut. Wir wissen aber noch mehr. Das sind nicht einfach nur 
Daten, sondern in dieser Variable sollen die Daten schon als String 
hinein. Also bereits in Textform!

>     UInt32 numBytesWritten = 0; // Variable für empfangene Bits
> definieren

Schau. Das ist Unsinn. Das können nicht die empfangenen Bits sein. Die 
Variable heißt
    num     offenbar eine Abkürzung. num ist meistens die Abkürzung
            für das englische number. Also Anzahl

    Bytes   da ist von Bytes die Rede. Und nicht von Bits

    Written ok, das ist ein wenig misverständlich. Denn hier geht
            es nicht um das Schreiben auf den FTDI, sondern um das
            Lesen.
            Aus dem weiteren Quelltext geht aber hervor, dass dir hier
            die eigentliche Lesefunktion angeben wird, wieviele Bytes
            sie beim Leseversuch tatsächlich in dein Array geschrieben
            hat.
            Du forderst eine bestimmte Anzahl Bytes an, und die
            Funktion sagt dir: soviele warens wirklich.
            Das ist wie wenn du einkaufen gehst. Du sagst zum
            Baumarkt-fachberater "Ich brauch 6 Rigips-Platten" und
            er sagt "Ich hab aber nur 4"

Alles in allem zusammengenommen, ist daher deine Beschreibung für diese 
Variable ziemlicher Mumpitz. Und das "definieren einer Variable" - spar 
dir solche Kommentare. Jeder Programmierer kann sehen, dass es hier um 
die Definition einer Variablen geht. Das brauchst du nicht komentieren. 
Das ist so, wie wenn du sagst: Dieses weiße Pferd ist ein Schimmel. No, 
na - was soll es sonst sein.

> //  Verfügbare Bitanzahl abfragen
>     myFtdiDevice.GetRxBytesAvailable(ref numBytesToRead);

Genau. Deswegen heißt die Funktion ...BytesAvailable. Weil sie Bitzahl
                                      *****
liefert.

> // Bits seriell auslesen
> myFtdiDevice.Read(received, numBytesToRead, ref numBytesWritten);

Was wird hier wohl passieren. Ohne dass man die Funktion selber kennt 
oder in der Doku nachschlägt. Was wird wohl logisch sein?

An das Objekt myFtdiDevice ergeht der Befehl "read". Was wird das Objekt 
wohl dazu brauchen
  es muss wissen, wieviele Bytes es eigentlich lesen soll

  und es wäre schön, wenn sie darüber Auskunft geben würde, wieviele
  Bytes sie tatsächlich gelesen hat. Diese Anzahl muss ja nicht
  notwendigerweise mit der angeforderten übereinstimmen.

  und es braucht natürlich eine Speicherfläche (die auch groß genug
  sein muss), in der sie die gelesenen Daten (die Bytes) ablegen
  kann

Welches der 3 Argumente wird wohl was sein? Die Namen der Argumente 
helfen dir das zu identifizieren.


Also: einfach mal ein wenig den Kopf benutzen und überlegen,
  was davon ist logisch
  wie helfen mir und was erzählen mir die Variablen- und Funktionsnamen

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.