Gerne. Kann ich auch verstehen - wer stellt schon "einfach nur so" mal eben alles um. :-)Zitat:
Zitat von izaseba
Druckbare Version
Gerne. Kann ich auch verstehen - wer stellt schon "einfach nur so" mal eben alles um. :-)Zitat:
Zitat von izaseba
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" )
[/code]Code://------------------------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+ReadTotalTimeoutConstant 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();
}
//---------------------------------------------------------------------------
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
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