Archiv verlassen und diese Seite im Standarddesign anzeigen : serielle Schnittstelle vom PC unter C++
Hallo,
um meinen Bot zu kontrollieren und die Messergebnisse auf dem PC darstellen zu können, benötige ich eine funktionierende Kommunikationsgrundlage.
Auf der Bot-Seite ist alles klar. Die Daten vom Terminal-Programm werden alle richtig erkannt und richtig zerlegt (verwende nur Zeichenketten).
Nur will ich halt nicht ein fertiges Terminal-Programm verwenden, sondern mein Eigenes. Dazu habe ich mir mühsam eins unter Borland 6.0 gebastelt ( ich habe noch mit C zu tun, da will ich mich nicht noch Hals über Kopf in C++ reinsteigern).
Was ich jetzt nur bräuchte, wäre eine ganz simple Funktion zum Aufrufen der Schnittstellen-Parameter (Com-Port, Baudrate ,...) und eine SendData/ReadData Funktion. Diese ReadData Funktion müsste an ein Event gekoppelt sein (wenn ein Zeichen im Buffer des PC's vorliegt).
Nun habe ich wirklich nichts richtiges im Internet gefunden (auch nicht hier im Forum). Immer wenn ich solche Beispiele adaptieren will, haut nichts hin:
http://www.winapi.net/index.php?inhalt=t3
http://msdn2.microsoft.com/en-us/library/ms810467.aspx
http://www.codeproject.com/system/serial.asp
(um nur wenige aufzuzählen)
Auch 2 Bücher habe ich mir dazu ausgeliehen.
Was ich benötige ist wirklich nur eine Integration einer fertigen Komponente. Ich stell mit das wie beim Controller vor. Man hat zB. zig Dateien für den DS18S20 und per Hauptprogramm wird nur eine einzige Funktion (wie ein Makro) aufgerufen und fertig (also nur die Header-Datei einbinden).
Bin wirklich am ausrasten, nur wegen dem blöden *Piep* sucht man ewig im Netz, probiert und sucht weiter...
Um am Ende nichts ordentliches heraus zu bekommen. Na gut, etwas gutes war dabei: Timer unter C++ bekomme ich nun hin =P~ (aber keine Ahnung von Events - für Controller ist die Interrupt-Programmierung und die UART-Schnittstelle eigentlich so simpel zu programmieren :roll: ).
Euer deprimierter Reeper :(
Das hab ich mir aus einem alten Artikel gerettet, schau mal, vielleicht hilft es dir :-)
8-Bit,
ohne Parity,
ohne Flußkontrolle (3 Draht)
Ich verwende übrigens das MS VisualC++. Bei diesen Calls ist aber nix davon zu sehen, da es die üblichen Standard-Calls sind.
Keine Klassen, kein nix.
Windows-Interface
Open
Get Handle
char cName[]="\\\\.\\COM1";
HANDLE hFile;
hFile= CreateFile(cName,GENERIC_READ|GENERIC_WRITE,0,0,OP EN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hFile==INVALID_HANDLE_VALUE) // Das war nix, eventuell anderes "COM" versuchen
Das Handle "hFile" wird nun für alle Calls angegeben, wie halt bei Windows üblich.
Set State
Mit diesem Handle kann (muß) man die Eigenschaften festlegen. Ich sag's ehrlich, mit den Time-Out Argumenten hab' ich nicht weiter 'rumprobiert, mir war nur wichtig, daß es funktioniert. Das letzte Mal hab ich noch "*.SYS" Treiber für das Steinzeit-DOS geschrieben. Also eventuell bitte um Nachsicht.
COMMTIMEOUTS sTo;
DCB sDcb;
memset(&sDcb,0,sizeof(sDcb));
sDcb.DCBlength = sizeof(sDcb);
sDcb.BaudRate = Baud; // 9600 oder eine andere Baudrate
sDcb.fParity = FALSE;
sDcb.fBinary = TRUE;
sDcb.Parity = NOPARITY;
sDcb.StopBits = ONESTOPBIT;
sDcb.fOutxCtsFlow = FALSE;
sDcb.fOutxDsrFlow = FALSE;
sDcb.fDtrControl = DTR_CONTROL_ENABLE;
sDcb.fRtsControl = RTS_CONTROL_ENABLE;
sDcb.fDsrSensitivity = FALSE;
sDcb.fAbortOnError = FALSE;
sDcb.ByteSize = 8;
if(SetCommState(hFile,&sDcb))
{
sTo.ReadIntervalTimeout = MAXDWORD; // 0 ms Read-Timeout
sTo.ReadTotalTimeoutMultiplier = 0;
sTo.ReadTotalTimeoutConstant = 0;
sTo.WriteTotalTimeoutMultiplier = 1; // 1*2 ms Write Timeout
sTo.WriteTotalTimeoutConstant = 2;
if(SetCommTimeouts((HANDLE)hFile,&sTo))
return 1; // O.K. return
}
CloseHandle(hFile);
return 0; // Im Fehlerfall
}
Read
Fragen, ob Daten da sind
COMSTAT sComStat;
DWORD dwErrorFlags = 0;
ClearCommError(hFile, &dwErrorFlags, &sComStat);
sComStat.cbInQue; // Die Anzahl der Bytes im Buffer
Daten abholen
DWORD dwCount;
ReadFile(hFile, Buffer, Max, &dwCount, 0);
Buffer ein Bereich für die Daten
Max die Anzahl der gewünschten Bytes
dwCount die Anzahl der tatsächlich bekommenen Bytes
Write
WriteFile(hFile, Buffer, Count, &dwCount, 0);
Buffer die zu sendenden Daten
Max die Anzahl der Bytes
dwCount die Anzahl der tatsächlich gesendeten Bytes
Close
CloseHandle(hFile);
Geht leider nicht, aber danke Picknick :-)
Borland kennt viele Befehle nicht (Get, Set, ...).
Ich konnte vor einiger Zeit mit einem Beispiel aus einem Buch auch etwas senden, jedoch unzuverlässig und nach kurzer Zeit war die Verbindung unterbrochen (Controller war immernoch mit einem anderen Terminal-Programm "erreichbar" -> hat sich also nicht aufgehangen).
just4fun
08.10.2007, 20:37
Open Source, bitte sehr: http://sourceforge.net/projects/qextserialport bzw. http://qextserialport.sourceforge.net/
Funktioniert unter Windows und Linux! Ich nutze es selbst mit dem Qt-Framework. (http://trolltech.com/products/qt/features/index)
Kann allerdings sein, dass Qt Voraussetzung ist; da bin ich mir grad nicht mehr so sicher. Dann hast du mit dem Borland-Kram natürlich ein Problem.
Wäre vielleicht ne gute Gelegenheit auf Open Source (Qt für nicht kommerzielle Zwecke) umzusteigen... Möchte aber jetzt hier keine Diskusion lostreten. Nur als Anregung!! :-)
ich würde gerne helfen, aber mir ist nicht ganz klar, was du mit borland und events genau meinst. hast du eine windoof fensteranwendung, die man sich zusammenklickt, indem man zB die timerkomponente aufs formular klatscht und dann code in die timerfunktion einfügt? oder verwechsel ich das,..?
gruesse
Hallo just4fun,
Ich habe eine Frage,
wird bei dieser lib auch ein Event ausgelöst, wenn Daten über die Serielle Schnittstelle angekommen sind ?
Das war bis jetzt mein Problem, sowas umzusetzen.
Gelöst habe ich es so, daß
1. Der µC nichts sendet, wenn er nicht gefragt wird.
2. Ich schaue jede Sekunde nach, ob was im Puffer liegt.
Also keine "saubere" Lösung, ich arbeite auf Linux mit Gtk+ und selbstgestrickten Systemaufrufen und bin bis jetzt glücklich, wenn aber die von Dir genannte lib beim Empfang ein Event generiert, würde ich mir das überlegen, ob Qt doch nicht besser ist.
Gruß Sebastian
just4fun
08.10.2007, 21:20
Hallo just4fun,
Ich habe eine Frage,
wird bei dieser lib auch ein Event ausgelöst, wenn Daten über die Serielle Schnittstelle angekommen sind ?
Das war bis jetzt mein Problem, sowas umzusetzen.
Gelöst habe ich es so, daß
1. Der µC nichts sendet, wenn er nicht gefragt wird.
2. Ich schaue jede Sekunde nach, ob was im Puffer liegt.
Also keine "saubere" Lösung, ich arbeite auf Linux mit Gtk+ und selbstgestrickten Systemaufrufen und bin bis jetzt glücklich, wenn aber die von Dir genannte lib beim Empfang ein Event generiert, würde ich mir das überlegen, ob Qt doch nicht besser ist.
Gruß SebastianHi Sebastian,
nein von selbst nicht. Habe das auch so ähnlich wie du geregelt. Wobei Events und Threads etc. unter Qt extrem easy und sehr leicht und schnell umzusetzen sind: http://doc.trolltech.com/4.3/signalsandslots.html
Hallo just4fun,
danke für die Links, steht sehr viel drinnen. Werde es mal mir zu Gemüte führen. Das Blöde an der ganzen Sache ist ja, dass ich es nicht verstehen muss/unbedingt will. Denn es dient ausschließlich als Mittel zum Zweck und das Hauptaugenmerk liegt auf der Controller-Seite (C) und nicht auf dem PC (C++). Eine fertige Lösung wäre schon cool.
Hallo robocat,
Soweit mir bis jetzt bekannt, heißen Interrupts in C++ quasi Events (wenn man es vergleichen kann/will).
Ja, die Timerlösung ist wie du geschrieben hast. Einfach Icon suchen, drauf klatschen und Code einsetzen (letztes so wie beim Controller).
Hallo izaseba,
Timer ist zwar eine Lösung, jedoch wie du selber geschrieben hast: "keine saubere Lösung". Es kann ja zwischenzeitlich passieren, dass der Buffer überschrieben wird (wenn man unkontrolliert senden lässt).
Was auch auf der PC Seite komisch, bzw. für mein Vorhaben suboptimal ist, dass man den buffer jedesmal bestimmen muss (also immer zu erwartende Bytes dazu übermitteln).
Bei mir ist die Kommunikation so aufgebaut, dass am Ende der Zeichenkette ein '#' steht, somit ist dies das Ende und der String wird zerlegt und verglichen ...
Ich müsste demnach den buffer vorsichtshalber sehr groß machen. Jedoch wird meistens nur eine Zeichenkette mit 5-6 Zeichen übermittelt. Aber später soll ab und zu mal ein mehrdimensionales Array gesendet werden ...
Gruß Stefan
ich glaube, wirklich event-driven ist das alles nicht. zumindest habe ich noch nichts dergleichen gefunden. meistens wird ein thread verwendet, der ständig den port abfragt, also im grunde dein (2.)
http://www.tetraedre.com/advanced/serial2.php
gruesse
Hallo Just4fun,
danke für die Antwort, dann werde ich vorerst bei Gtk bleiben, Qt habe ich auch schon programmiert, es war aber noch die 3.* Version gewesen, irgendwas gefiel mir nicht mehr an 4.* (weiß selber nicht mehr, was es war ;-) ) und habe mich dann mit Gtk angefreundet...
Im Endeffekt, ist die vorgehensweise doch fast gleich.
@Reeper,
deswegen komuniziere ich mit den µC und nicht andersrum, wenn ich ihm sage, was ich haben will, weiß ich wohl dann am besten, mit welchen Daten ich zu rechnen habe.
Allerdings verschicke ich keine Strings sondern binäre Form (Es ging mir auf den Senkel von bin nach ascii zu wandeln, verschicken, String auswerten, Zahlen wieder in bin wandern usw. )
Gruß Sebastian
EDIT:
@robocat, dann bin ich beruhigt, daß die anderen auch nur mit Wasser kochen ;-)
Habe mir Dein Link angeguckt, ich glaube es ist das, was Reeper braucht
just4fun
08.10.2007, 21:47
Hallo Just4fun,
danke für die Antwort, dann werde ich vorerst bei Gtk bleiben, Qt habe ich auch schon programmiert, es war aber noch die 3.* Version gewesen, irgendwas gefiel mir nicht mehr an 4.* (weiß selber nicht mehr, was es war ;-) ) und habe mich dann mit Gtk angefreundet...
Im Endeffekt, ist die vorgehensweise doch fast gleich.Gerne. Kann ich auch verstehen - wer stellt schon "einfach nur so" mal eben alles um. :-)
Danke euch erstmal, werde morgen dein (robocat) Link mir zu Gemüte führen (downloaden, ausprobieren).
Hier mal der Stand vom Nachmittag:
(ganze RS232 Geschichte vom Buch: "Richard Kaiser C++ mit dem Borland C++Builder" )
//------------------------include---------------------------------------------------
//---------------------------------------------------------------------------
#include <vcl.h>
#include <vcl\vcl.h>
#pragma hdrstop
#pragma package(smart_init)
#pragma resource "*.dfm"
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "Unit2.h"
//#include "SerCommU.h"
//------------------------define---------------------------------------------------
//---------------------------------------------------------------------------
#define Baud 115200
//---------------------------------------------------------------------------
TForm2 *Form2;
//------------------------Variablen---------------------------------------------------
//---------------------------------------------------------------------------
char PWM_LEFT[10], PWM_RIGHT[10], buffer[10], receive[100];
int PWM_L=0, PWM_R=0, Strlaenge=0;
HANDLE hComSend,hComReceive;
//------------------------Programmteile---------------------------------------------------
//---------------------------------------------------------------------------
//------------------------RS 232---------------------------------------------------
//---------------------------------------------------------------------------
void ShowLastError(AnsiString where)
{ // In der VCL einfach mit SysErrorMessage:
MessageBox(NULL,SysErrorMessage(GetLastError()).c_ str(),where.c_str(),MB_OK|MB_ICONERROR);
/* Ohne SysErrorMessage:
LPTSTR lpMsgBuf; // char*
FormatMessage( // siehe Online-Hilfe zu Win32
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf, // Adresse des nullterminierten Meldungstextes
0,
NULL);
MessageBox( NULL, lpMsgBuf,where.c_str(),MB_OK|MB_ICONERROR);
LocalFree( lpMsgBuf ); // Free the buffer.
*/
}
//---------------------------------------------------------------------------
void ShowTextAndValue(TMemo* t,AnsiString s,int Value)
{
t->Lines->Add(s+IntToStr(Value));
}
void showDCB(TMemo* M,HANDLE hCom)
{
DCB dcb; // Device Control Block
BOOL fSuccess = GetCommState(hCom, &dcb); // DCB lesen
if (!fSuccess) ShowLastError("GetCommState");
// DWORD DCBlength; // sizeof(DCB)
// DWORD BaudRate; // current baud rate
ShowTextAndValue(M,"baud rate: ",dcb.BaudRate);
ShowTextAndValue(M,"parity: ",dcb.fParity);
ShowTextAndValue(M,"CTS output flow control: ",dcb.fOutxCtsFlow);
ShowTextAndValue(M,"DSR output flow control: ",dcb.fOutxDsrFlow);
ShowTextAndValue(M,"DTR flow control type: ",dcb.fDtrControl);
ShowTextAndValue(M,"DSR sensitivity: ",dcb.fDsrSensitivity);
ShowTextAndValue(M,"RTS flow control: ",dcb.fRtsControl);
}
HANDLE OpenComm(char* Port)
{ // Öffnet den Port und gibt sein Handle zurück
HANDLE hCom = CreateFile(Port,// z.B. "COM1",
GENERIC_READ | GENERIC_WRITE, // Zum Senden und Empfangen
0, // Für comm devices exclusive-access notwendig
0, // Keine security attributes
OPEN_EXISTING, // Für comm devices OPEN_EXISTING notwendig
0, // In den folgenden Beispielen kein overlapped I/O
0); // Für comm devices muß hTemplate NULL sein
if (hCom == INVALID_HANDLE_VALUE)
ShowLastError("CreateFile: "+AnsiString(Port));
return hCom;
}
//---------------------------------------------------------------------------
void SetDCB(HANDLE hCom)
{
DCB dcb; // Device Control Block
BOOL fSuccess = GetCommState(hCom, &dcb); // DCB lesen
if (!fSuccess) ShowLastError("GetCommState");
// Setze die Baudrate=9600, 8 Datenbits, keine Parity, 1 Stopbit:
dcb.BaudRate = Baud; // Baudrate
dcb.ByteSize = 8; // 8 Datenbits
dcb.Parity = NOPARITY; // keine Parity
dcb.StopBits = ONESTOPBIT; // 1 Stopbit
bool NoFlowControl=false,
HardwareFlowControl=false,
SoftwareFlowControl=true;
// Oft spricht man auch von Hardware- bzw. Software-Handshake
// Die folgenden Ausführungen nach dem MSDN-Artikel
if (NoFlowControl)
{
// kein Hardware Flowcontrol:
dcb.fOutxCtsFlow=false;
dcb.fOutxDsrFlow=false;
// kein Software Flowcontrol:
dcb.fInX=false; // für Empfänger
dcb.fOutX=false; // für Sender
dcb.fDsrSensitivity=false;
}
else
{
if (HardwareFlowControl)
{
dcb.fOutxCtsFlow=true;
dcb.fOutxDsrFlow=true;
}
// Hier kein else: Software- und HardwareFlowControl sind
// gleichzeitig möglich, auch wenn das nicht üblich ist
if (SoftwareFlowControl)
{
dcb.fInX=true; // für Empfänger
dcb.fOutX=true; // für Sender
// Die folgenden Elemente steuern SoftwareFlowControl,
// Sie müssen aber nicht gesetzt werden. Oft reichen die
// Voreinstellungen.
// dcb.fTXContinueOnXoff=false;
// dcb.XonLim = ...;
// dcb.XoffLim = ...;
// dcb.XoffChar = ...;
// dcb.XonChar = ...;
}
}
// SetCommState konfiguriert die serielle Schnittstelle
fSuccess = SetCommState(hCom, &dcb);
if (!fSuccess) ShowLastError("SetCommState");
showDCB(Form2->Memo1,hCom);
}
//---------------------------------------------------------------------------
void SetReadTimeouts(HANDLE hCom)
{ // Der Aufruf von SetCommTimeouts ist notwendig,
// da ohne diesen die Ergebnisse von Readfile undefiniert sind
COMMTIMEOUTS t;
// Alle Wert in Millisekunden
// Werte für ReadFile:
t.ReadIntervalTimeout=100; // Timeout zwischen zwei Zeichen
t.ReadTotalTimeoutMultiplier=10; // pro Zeichen
t.ReadTotalTimeoutConstant=1; //
// Wenn mit ReadFile n Zeichen gelesen werden sollen, tritt ein Timeout
// nach ReadTotalTimeoutMultiplier*n+ReadTotalTimeoutConst ant ms ein.
// Werte für WriteFile: wenn beide 0 sind,
// kein Timeout beim Schreiben
t.WriteTotalTimeoutMultiplier=0;
t.WriteTotalTimeoutConstant=0;
if (!SetCommTimeouts(hCom,&t))
ShowLastError("SetCommTimeouts");
}
//---------------------------------------------------------------------------
void showCommProp(TMemo* M, HANDLE hCom)
{
/*typedef struct _COMMPROP { // cmmp
WORD wPacketLength; // packet size, in bytes
WORD wPacketVersion; // packet version
DWORD dwServiceMask; // services implemented
DWORD dwReserved1; // reserved
DWORD dwMaxTxQueue; // max Tx bufsize, in bytes
DWORD dwMaxRxQueue; // max Rx bufsize, in bytes
DWORD dwMaxBaud; // max baud rate, in bps
DWORD dwProvSubType; // specific provider type
DWORD dwProvCapabilities; // capabilities supported
DWORD dwSettableParams; // changable parameters
DWORD dwSettableBaud; // allowable baud rates
WORD wSettableData; // allowable byte sizes
WORD wSettableStopParity; // stop bits/parity allowed
DWORD dwCurrentTxQueue; // Tx buffer size, in bytes
DWORD dwCurrentRxQueue; // Rx buffer size, in bytes
DWORD dwProvSpec1; // provider-specific data
DWORD dwProvSpec2; // provider-specific data
WCHAR wcProvChar[1]; // provider-specific data
} COMMPROP;
*/
_COMMPROP CP;
GetCommProperties(hCom,&CP);
ShowTextAndValue(M,"max Tx bufsize, in bytes: ",CP.dwMaxTxQueue);
ShowTextAndValue(M,"max Rx bufsize, in bytes: ",CP.dwMaxRxQueue);
ShowTextAndValue(M,"Tx buffer size, in bytes: ",CP.dwCurrentTxQueue);
ShowTextAndValue(M,"Rx buffer size, in bytes: ",CP.dwCurrentRxQueue);
}
int SendData(char Data[],int n)
{
DWORD NumberOfBytesWritten; // Anzahl der gesendeten Bytes
bool b=WriteFile(hComSend,
Data,
n, // Anzahl der zu sendenden Bytes
&NumberOfBytesWritten, // Adresse, an die der Wert geschrieben wird
0); // kein overlapped I/O
if (!b)
ShowLastError("SendData");
return NumberOfBytesWritten;
}
//---------------------------------------------------------------------------
DWORD ReceiveData(char* Data,int n)
{
DWORD NumberOfBytesRead; // Anzahl der gelesenen Bytes
bool b=ReadFile(hComReceive, // handle des Com-Ports
Data, // Adresse des Datenpuffers
n, // Anzahl der zu lesenden Bytes
&NumberOfBytesRead, // Adresse, an die der Wert geschrieben wird
0); // kein overlapped I/O
/*
if (!b)
ShowLastError("ReceiveData"); */
return NumberOfBytesRead;
}
//------------------------Funktionen---------------------------------------------------
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button5Click(TObject *Sender)
{
CloseHandle(hComSend);
CloseHandle(hComReceive);
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button6Click(TObject *Sender)
{
SendData("BM1#",4);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button7Click(TObject *Sender)
{
SendData("BM5#",4);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button8Click(TObject *Sender)
{
SendData("BM2#",4);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button9Click(TObject *Sender)
{
SendData("BM3#",4);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button10Click(TObject *Sender)
{
SendData("BM4#",4);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Close1Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm2::COM11Click(TObject *Sender)
{
hComSend=OpenComm("COM1");
hComReceive=OpenComm("COM1");
SetDCB(hComSend);
SetDCB(hComReceive);
SetReadTimeouts(hComReceive);
//showCommProp(Form2->Memo1,hComSend);
//showCommProp(Form2->Memo2,hComReceive);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::COM21Click(TObject *Sender)
{
hComSend=OpenComm("COM2");
hComReceive=OpenComm("COM2");
SetDCB(hComSend);
SetDCB(hComReceive);
SetReadTimeouts(hComReceive);
//showCommProp(Form2->Memo1,hComSend);
//showCommProp(Form2->Memo2,hComReceive);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::COM31Click(TObject *Sender)
{
hComSend=OpenComm("COM3");
hComReceive=OpenComm("COM3");
SetDCB(hComSend);
SetDCB(hComReceive);
SetReadTimeouts(hComReceive);
//showCommProp(Form2->Memo1,hComSend);
//showCommProp(Form2->Memo2,hComReceive);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::COM41Click(TObject *Sender)
{
hComSend=OpenComm("COM4");
hComReceive=OpenComm("COM4");
SetDCB(hComSend);
SetDCB(hComReceive);
SetReadTimeouts(hComReceive);
//showCommProp(Form2->Memo1,hComSend);
//showCommProp(Form2->Memo2,hComReceive);
}
//---------------------------------------------------------------------------
void __fastcall TForm2::COM51Click(TObject *Sender)
{
hComSend=OpenComm("COM5");
}
//---------------------------------------------------------------------------
void __fastcall TForm2::RadioButton6Click(TObject *Sender)
{
ScrollBar2->Visible=false;
Edit3->Visible=false;
Label5->Visible=false;
Label4->Visible=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::RadioButton7Click(TObject *Sender)
{
ScrollBar2->Visible=true;
Edit3->Visible=true;
Label5->Visible=true;
Label4->Visible=true;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::ScrollBar3Change(TObject *Sender)
{
if (ScrollBar3->Position == 0)PWM_L=0;
else PWM_L=(ScrollBar3->Position)*(-1);
itoa(PWM_L,buffer,10);
Edit2->Text=PWM_L;
if (RadioButton6->Checked==true)
{
strcpy(PWM_LEFT,"BPA");
strcat(PWM_LEFT,buffer);
strcat(PWM_LEFT,"#");
Memo2->Lines->Add(PWM_LEFT);
Strlaenge=strlen(PWM_LEFT);
SendData(PWM_LEFT,Strlaenge);
}
else
{
strcpy(PWM_LEFT,"BPL");
strcat(PWM_LEFT,buffer);
strcat(PWM_LEFT,"#");
Memo2->Lines->Add(PWM_LEFT);
Strlaenge=strlen(PWM_LEFT);
SendData(PWM_LEFT,Strlaenge);
}
strcpy(buffer,"");
}
//---------------------------------------------------------------------------
void __fastcall TForm2::ScrollBar2Change(TObject *Sender)
{
if (ScrollBar2->Position == 0) PWM_R=0;
else PWM_R=(ScrollBar2->Position)*(-1);
itoa(PWM_R,buffer,10);
Edit3->Text=PWM_R;
strcpy(PWM_RIGHT,"BPR");
strcat(PWM_RIGHT,buffer);
strcat(PWM_RIGHT,"#");
Memo2->Lines->Add(PWM_RIGHT);
Strlaenge=strlen(PWM_RIGHT);
SendData(PWM_LEFT,Strlaenge);
strcpy(buffer,"");
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
const int BufSize = 20;
char Buffer[BufSize]; // address of buffer that receives data
DWORD NumberOfBytesRead=ReceiveData(Buffer,BufSize);
if (NumberOfBytesRead > 0)
{
AnsiString s;
for (DWORD i=0;i<NumberOfBytesRead;i++)
s=s+Buffer[i];
Memo1->Lines->Add("Gelesen n="+IntToStr(NumberOfBytesRead)+" ch="+s);
}
else
{
Memo1->Lines->Add("Nichts empfangen");
}
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button2Click(TObject *Sender)
{
if (Timer1->Enabled)
{
Timer1->Enabled =false;
Button2->Caption="Read-Timer disabled";
Edit5->Clear();
ScrollBar5->Position=0;
ScrollBar6->Position=0;
}
else
{
Timer1->Enabled=true;
Button2->Caption="Read-Timer aktiv";
};
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Close2Click(TObject *Sender)
{
CloseHandle(hComSend);
CloseHandle(hComReceive);
Close();
}
//---------------------------------------------------------------------------
[/code]
Robocat -> Vielen Dank für den Link O:)
Konnte es erfolgreich adaptieren.
Der Empfang per Event (wenn Zeichen im Buffer) scheint auch prima zu klappen.
Bis jetzt zeigt er zwar nur jedes empfangene Zeichen einzeln an (wie als wenn dahinter "/n/r" stehen würde), doch das bekomme ich auch noch gebacken.
Also vielen Dank für eure Hilfe [-o<
Gruß
Stefan
ruppi985
23.10.2007, 08:40
Hallo,
wenn Du eine wirklich gute und einfache Komponente unter CBuilder suchst und nicht die API-Programmierung benutzen möchtets dann schau mal hier vorbei :
http://sourceforge.net/projects/tpapro/
Mit frdl. Gruß
Ruppi985
Danke dir auch, habe es jedoch schon mit der anderen Variante hinbekommen. Es funktioniert ganz gut. Habe jetzt leider immer weniger Zeit für den Roboter (Semesterbeginn), sodass mein Projekt wieder warten muss.
Danke und Gruß
Stefan
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.