Hallo, ich bin auf der Suche nach einer Library für den FT232.
Ein Zeichen senden kann ich (funktioniert auch), aber für mehr reichen
meine Kenntnisse nicht. Deshalb suche ich einen Codeausschnitt bzw. eine
Library die einen String senden und empfangen kann. Ich programmieren in
Codeblocks unter Win7 x64 / mit C++.
Vielen Dank für etwaige Hilfe
> Ein Zeichen senden kann ich (funktioniert auch), aber für mehr reichen
meine Kenntnisse nicht.
Du kannst 1 Zeichen senden, hast aber Probleme mit Strings?
Das ergibt keinen Sinn. Einen String sendet man, indem man 1 Zeichen
nach dem anderen sendet. Das kannst du aber offenbar. Wo liegt daher das
Problem?
1
voidsendString(constchar*string)
2
{
3
while(*string)
4
sendCharacter(*string++);
5
}
wenn du nicht mit ollen C-style Strings rummachen willst (was ich
verstehen kann), musst du dir halt was Gleichwertiges mit deiner
favorisierten String-Klasse einfallen lassen.
Genauer gesagt sind es mehrere Probleme. Der Null Teminierte String muss
dieser funktion übergeben werden.Daher muss er konvertiert werden jedoch
weiß ich leider nicht wie?
FT_STATUS FT_Write (FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD
dwBytesToWrite,LPDWORD lpdwBytesWritten)
Parameters:
ftHandle Handle of the device.
lpBuffer Pointer to the buffer that contains the data to be written to
the device.
dwBytesToWrite Number of bytes to write to the device.
lpdwBytesWritten Pointer to a variable of type DWORD
Das lesen ist für mich noch weit komplizierter.Zuerst muss die folgende
Funktion richtig parametriert werde.
FT_STATUS FT_SetEventNotification (FT_HANDLE ftHandle, DWORD
dwEventMask, PVOID pvArg)
Parameters
ftHandle Handle of the device.
dwEventMask Conditions that cause the event to be set.
pvArg Interpreted as the handle of an event.
Remarks
An application can use this function to setup conditions which allow a
thread to block until one of the conditions is met. Typically, an
application will create an event, call this function, then block on the
event. When the conditions are met, the event is set, and the
application thread unblocked.
dwEventMask is a bit-map that describes the events the application is
interested in. pvArg is interpreted as the handle of an event which has
been created by the application. If one of the event conditions is met,
the event is set.
If FT_EVENT_RXCHAR is set in dwEventMask, the event will be set when a
character has been received by the device.
If FT_EVENT_MODEM_STATUS is set in dwEventMask, the event will be set
when a change in the modem signals has been detected by the device.
If FT_EVENT_LINE_STATUS is set in dwEventMask, the event will be set
when a change in the line status has been detected by the device.
Danach ein nullterminierter String aus folgender funktion ausgelesen
werden.
FT_STATUS FT_Read (FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD
dwBytesToRead,
LPDWORD lpdwBytesReturned)
Parameters
ftHandle Handle of the device.
lpBuffer Pointer to the buffer that receives the data from the device.
dwBytesToRead Number of bytes to be read from the device.
lpdwBytesReturned Pointer to a variable of type DWORD which receives the
number of bytes read from the device.
wie gesagt ich verstehe es leider nicht ganz.
> void sendString( const char* string )> {> while( *string )> sendCharacter( *string++ );> }>> wenn du nicht mit ollen C-style Strings rummachen willst (was ich> verstehen kann), musst du dir halt was Gleichwertiges mit deiner> favorisierten String-Klasse einfallen lassen.
ja so leicht ist es leider nicht, ich habe Probleme mit den Pointern
bzw. der Datentyp konvertierung. Aber schon mal Danke
Mark L. schrieb:> Genauer gesagt sind es mehrere Probleme. Der Null Teminierte String muss> dieser funktion übergeben werden.Daher muss er konvertiert werden jedoch> weiß ich leider nicht wie?>> FT_STATUS FT_Write (FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD> dwBytesToWrite,LPDWORD lpdwBytesWritten)>> Parameters:>> ftHandle Handle of the device.> lpBuffer Pointer to the buffer that contains the data to be written to> the device.> dwBytesToWrite Number of bytes to write to the device.> lpdwBytesWritten Pointer to a variable of type DWORD
Ich versteh dein Problem immer noch nicht.
Dein STring hat eine gewisse Länge und damit eine gewisse Byteanzahl.
Ich ignoriere jetzt mal Unicode sondern gehe von guten alten ASCII
Strings aus. Wenn dem nicht so ist, dann musst du also entweder
feststellen wie man von einem Unicode-String die Anzahl der Bytes
ermittelt, oder wie man einen Unicode String auf ASCII transferiert.
Beides hat aber erst mal nichts mit FT232 zu tun.
Hast du dann die Anzahl der Bytes, dann ab damit in diese Funktion. Die
Längenangabe richtig angegebn und fertig, Wo liegt da jetzt schon wieder
das Problem? Das ist banales C++ / Windows Wissen. So wie ich das sehe,
hat diese API Funktion auch durchaus eine unter Windows gebräuchliche
Signatur.
Mark L. schrieb:>> void sendString( const char* string )>> {>> while( *string )>> sendCharacter( *string++ );>> }>>>> wenn du nicht mit ollen C-style Strings rummachen willst (was ich>> verstehen kann), musst du dir halt was Gleichwertiges mit deiner>> favorisierten String-Klasse einfallen lassen.>> ja so leicht ist es leider nicht, ich habe Probleme mit den Pointern> bzw. der Datentyp konvertierung.
Welche Probleme?
Die Sache wäre wesentlich einfacher, wenn du Code zeigen würdest.
Und PS: konzentrier dich erst mal nur auf eine Sache. Senden geht
einfacher als Empfangen. Also fang erst mal mit Senden an.
Mark L. schrieb:> unsigned char cmd[]= {'T','E','S','T','\n'};
ich glaube du braucht ein Buch über C und nicht über die FT232 lib.
unsigned char cmd[]= {'T','E','S','T','\n', 0 };
oder VIEL besser
char cmd[]= "TEST\n";
Peter II schrieb:> char cmd[]= "TEST\n";
ergibt aber übertragunsfehler:
Ausgabe ist dann <NUL>xTEST<LF>
x ist ein unbekanntes Zeichen. Aber danke der hilfe.
Mark L. schrieb:> ergibt aber übertragunsfehler:> Ausgabe ist dann <NUL>xTEST<LF>> x ist ein unbekanntes Zeichen. Aber danke der hilfe.
dann hast du wo anders noch einen Fehler oder eventuell Probleme mit
unicode.
Zeig doch mal den den quelltext mit den dieser Fehler entstanden ist.
> FT_Write( ftHandle, (void*)String, len, &bytesSent );>> if( bytesSent != len )> cout << "Nicht alle Bytes konnten gesendet werden\n";>> Wie gesagt: die Problematik UNICODE ignoriere ich jetzt erst mal, weil> ich nicht weiß ob das ein konkretes Problem für dich darstellt.
Vielen dank das hilft schon mal weiter, ich wusste nicht das es soo
möglich ist den string zu senden (void*)String.
Mark L. schrieb:> Peter II schrieb:>> char cmd[]= "TEST\n";>> ergibt aber übertragunsfehler:>> Ausgabe ist dann <NUL>xTEST<LF>>> x ist ein unbekanntes Zeichen.
Wie hast du das festgestellt?
Bei allen 'Messmethoden' muss man immer auch berücksichtigen, dass das
'Messgerät' Unsinn anzeigt, weil es sich zb erst mal auf eine
Übertragung einklinken muss. Nach dem ersten Zeichen sollte das
allerdings dann nicht mehr sein.
1
Angedachtist:
2
3
Stringstr0="Test\n";
4
5
6
write(str0);
7
8
9
intwrite(stringstr)
10
{
11
12
"String senden"
13
14
}
Ja. Wie gehts jetzt weiter?
Stringlänge feststellen (Hinweis: dein sizeof da oben ist schon mal
nicht dafür geeignet), entsprechenden Pointer auf die Bytes in FT_wruite
reinstecken, die ermittelte Stringlänge reinstecken und ... fertig.
Ich seh immer noch kein Problem.
Mark L. schrieb:>> FT_Write( ftHandle, (void*)String, len, &bytesSent );>>>> if( bytesSent != len )>> cout << "Nicht alle Bytes konnten gesendet werden\n";>>>> Wie gesagt: die Problematik UNICODE ignoriere ich jetzt erst mal, weil>> ich nicht weiß ob das ein konkretes Problem für dich darstellt.>> Vielen dank das hilft schon mal weiter, ich wusste nicht das es soo> möglich ist den string zu senden (void*)String.
Das hat mit versenden nichts zu tun.
Der Cast auf void ist notwendig, weil es nun mal in C++ keinen Datentyp
gibt der für 'Pointer auf irgendwas' steht und in den alle anderen
Pointertypen implizit konvertiert werden können.
void* realisiert einen 'Pointer auf irgendwas', aber in C++ kann kein
Pointer vom Compiler implizt darauf hingecastet werden, sondern der
Programmierer muss das erlauben bzw. einfordern. Die Funktion will einen
void Pointer, also caste ich den Datenpointer entsprechend um. Das
normalste von der Welt.
Mir scheint Peter II hat da oben schon recht. Du brauchst in erster
Linie mal ein vernünftiges Buch.
Mark L. schrieb:> Ausgabe: <NUL>xTEST<LF>
Die Art wie du dein Array baust, hat damit nichts zu tun. Deine erste
Version ist nur die umständliche Schreibweise der 2.ten Version. Das
Array wird aber in beiden Fällen identisch angelegt.
Ich denke eher, dass das 'x' das du siehst, das 0-Byte vom ersten (bzw.
vorhergehenden) Versuch ist. Wozu sollte man ein 0-byte übertragen, wenn
es nicht korrekt angezeigt werden kann. Normalerweise macht man das
nicht (ausser der Empfänger benötigt das 0byte um das Ende des Strings
erkennen zu können, was ein normales Terminalprogramm nicht kann. Das
malt dann eben ein Zeichen für 'kenn ich nicht' hin.)
Karl Heinz Buchegger schrieb:> Die Art wie du dein Array baust, hat damit nichts zu tun. Deine erste> Version ist nur die umständliche Schreibweise der 2.ten Version. Das> Array wird aber in beiden Fällen identisch angelegt.
nein, einmal hat es am ende eine 0 einmal nicht. Aber der Anfang sollte
gleich sein.
@Mark L.
Für soetwas hilft doch der debugger, schau dir doch einfach mal die
Variaben an.
Peter II schrieb:> Karl Heinz Buchegger schrieb:>> Die Art wie du dein Array baust, hat damit nichts zu tun. Deine erste>> Version ist nur die umständliche Schreibweise der 2.ten Version. Das>> Array wird aber in beiden Fällen identisch angelegt.> nein, einmal hat es am ende eine 0 einmal nicht. Aber der Anfang sollte> gleich sein.
Ah. ok. Daran hab ich jetzt nicht gedacht.
Ist ja auch Schwachsinn einen String mittels Einzelbuchstaben anzulegen.
Das macht die Stringverarbeitung so schon <Sarkasmus ein> unkompliziert
</Sarkasmus aus>
sorry hat einen moment gedauert, der fehler war die \0 am ende aber
jetzt funktioniert das senden wie es soll.
Ich benutze das http://www.cplusplus.com/ als Hilfe
Vielen dank schonmal für die Hilfestellung.
Mark L. schrieb:> char TEXT[strlen(str)];>> DWORD Written=0;> for(int i = 0; i < strlen(str); i++)> {> TEXT[i] = str[i];> }
und was soll das? Du kopierst 1:1 alles was in str steht in TEXT rein -
wozu?
Dann kannst du auch gleich str verwenden und braucht TEXT überhaupt
nicht.
hast du ein glück das es seit neusten soetwas gibt:
char TEXT[strlen(str)];
vor ein paar jahren hätte jeder Compiler hier aufgehört.
Mark L. schrieb:> weil es zur laufzeit passiert? wenn ich das richtig verstehe?
ja, weil der Compiler es noch nicht wissen kann wie gross die Variabel
wird.
Warum hat deine Write funktion ein int als Rückgabe, wenn du eh immer 0
zurückgibst - man muss nichts zurückgeben.
ISO C++ forbids declaration of 'write' with no type, war sonst der
Fehler.
Zur Read Funktion ich habe das Beispiel geteste. Jedoch ohne Erfolg,
deshalb auch die Frage ob jemand etwas in einer funktionsfähigen Form
hat.
if((ftStatus == FT_OK) && (RxBytes >= OneSector))
das sieht aber merkwürdig aus, du willst wo extra den Speicher
überschreiben weil du hier wartest bis so viele Daten da sind das sie
nicht mehr in RxBuffer reinpassen.
Mark L. schrieb:> Wie gesagt war das Beispiel das ich fand verstanden habe ich es nicht.
dann versteh es bitte zu erst, Trial and Error ist bei programmieren in
C das schlechteste was man machen kann.
> if(BytesReceived == RxBytes)
und was ist wenn man weniger zu empfangen ist?
Lies dir die Doku von FTDI durch und Programmiere es selber. Vom Copy
and Paste lernt man nichts.
Ja wenn ich alles verstanden hätte wäre ich nicht hier, mir wäre es auch
lieber alles zu können.
Oder eine Fertige lib zu nutzen die alles kann was ich brauche. Kann es
aber eben nur so, ich dachte die Beispiele sind für den schnell
Einstieg?Es geht leider nicht alles zu 100% zu lernen (wer hat den dazu
Zeit?) somit ist das mein Weg. Ich bitte das zu verstehen. Jedoch, Danke
für die Hilfe.
Mark L. schrieb:> Oder eine Fertige lib zu nutzen die alles kann was ich brauche.
die FTDI lib ist doch schon fertig. Und macht eigentlich alles was man
braucht.
> Es geht leider nicht alles zu 100% zu lernen (wer hat den dazu Zeit?)
doch geht es, wenn man einmal die Grundlagen verstanden hat, dann spart
man am ende sogar Zeit. Du hast doch noch mal mal verstanden wie
"Strings" in C funktionieren - dann sollte man noch nicht Anfangen
irgendwelche Libs einzubinden.
was soll das hier:
> int(BytesReceived)
weist du überhaupt warum du das dort hingeschrieben hast?
Mark L. schrieb:> einen typecast zur laufzeit.
nein ein typcast wird so geschrieben
(int)BytesReceived
aber warum willst du über casten? For-Schleifen müssen nicht mit int
gemacht werden.
for(DWORD i = 0 ; i < BytesReceived; i++)
Mark L. schrieb:> es ist ein typecast von unsigned in signed, geht doch so, warum nicht?
das Problem dabei ist das es ein cast ist, wenn du aus irgend einem
grund mal die Variable BytesReceived einen komplett anderen Datentyp
gibst dann wirkt der Cast immernoch. und es gibt keine warnung vom
Compiler. Also versucht man ohne cast auszukommenm. Und hier gibt es
überhaupt keinen Grund mit einem Cast zu arbeiten.