Solved

Problems with ComPort Class

Posted on 2001-08-30
19
977 Views
Last Modified: 2007-11-27
Hi Experts

i've written a class (TComPort) for write and read to/from the ComPort.
Now, i want to Open two (com1 & com2) but i can only send on one com port....
what do u think is the failure?


this is my class:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "TCom.h"
//---------------------------------------------------------------------------
__fastcall TComPort::TComPort(void)
{
/*
    Das isch de sogenannte konschtruktor. Do ine werded samtlichi variable
    und Klassainstanza initialisiert.
    Da Konschtruktr wird nume bim uufruaf vo "new" d.h. z.B. bi
    "TComPort *ComPort = new TComPort();" uusgfuurt nocher numa.
*/
    hComm = NULL;                  // Handle fur RS232 Kommunikation

    ReadTotalTimeoutConstant = 100;
    ReadTotalTimeoutMultiplier = 0;
    WriteTotalTimeoutMultiplier = 0;
    WriteTotalTimeoutConstant = 0;


    ComPort = "COM1";              // Default-Comport festlegen
    DeviceControl = "9600,N,8,1";
}
//---------------------------------------------------------------------------
__fastcall TComPort::~TComPort(void)
{
/*
    De Destruktor. Do chasch allfalligi sache no abschlusse falls z.B. so en
    tubel vergasse hett de Com Port z'schlussa oder so.
    Au da wird nume eimol uusgfuhrt namlich bim uufruaf vo "delete"
*/
//    CloseComm();
}
//---------------------------------------------------------------------------
int __fastcall TComPort::OpenComm (void)
{
  DCB dcbCommPort;

  hComm = CreateFile(ComPort.UpperCase().c_str(),
                      GENERIC_READ | GENERIC_WRITE,
                      0,
                      0,
                      OPEN_EXISTING,
                      0,
                      0);

  // wann fahler, usefigge

  if(hComm == INVALID_HANDLE_VALUE)
    {
    Application->MessageBox("Fehler beim Offnen der Seriellen Kommunkation",
                            "Fehler", 16);
    hComm = NULL;
    return -1;
    }

  // set d comm teimauts

  GetCommTimeouts(hComm,&ComTimeoutOld_CTO);
  ComTimeoutNew_CTO.ReadTotalTimeoutConstant = 100;
  ComTimeoutNew_CTO.ReadTotalTimeoutMultiplier = 0;
  ComTimeoutNew_CTO.WriteTotalTimeoutMultiplier = 0;
  ComTimeoutNew_CTO.WriteTotalTimeoutConstant = 0;
  SetCommTimeouts(hComm, &ComTimeoutNew_CTO);

  // SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.

  dcbCommPort.DCBlength = sizeof(DCB);
  GetCommState(hComm, &dcbCommPort);
  BuildCommDCB(DeviceControl.c_str(), &dcbCommPort);
  SetCommState(hComm, &dcbCommPort);
  return 0;
}
//---------------------------------------------------------------------------
bool __fastcall TComPort::CloseComm (void)
{
    if (hComm != NULL)
    {
        PurgeComm(hComm, PURGE_RXABORT);
        SetCommTimeouts(hComm, &ComTimeoutOld_CTO);
        return CloseHandle(hComm);
    }
    else
        return true;
}
//---------------------------------------------------------------------------
bool  __fastcall TComPort::SendChar(char pfuedi)
{
  return TransmitCommChar(hComm, pfuedi);
}
//---------------------------------------------------------------------------
char*  __fastcall TComPort::ReceiveChar(int Value)
{
  char InBuff[100];
  DWORD dwBytesRead;

  ReadFile(hComm, InBuff, Value, &dwBytesRead, NULL);
  if(dwBytesRead)
    {
    InBuff[dwBytesRead] = 0; // NULL Terminate the String
    return InBuff;
    }
}
//---------------------------------------------------------------------------
#pragma package(smart_init)
0
Comment
Question by:reggler
  • 9
  • 7
  • 2
  • +1
19 Comments
 
LVL 2

Expert Comment

by:bkdc
ID: 6439959
Love that german stuff, couldn't understand a thing. Anyway, the problem is quite clear to me.
>> ComPort = "COM1";
 You should provide a way to set the comm port,maybe in OpenComm(void) method
 
OpenComm(int commNo) would be lovely
{
  if (commNo==1)
  {
     ComPort="COM1";
  }
  else
  {
    ComPort="COM2";
  }
 //quite stupid but I'm in a hurry
 //you should convert the commNo into a string and do smth like ComPort="COM"+strCom;

......your stuff follows
}

0
 

Author Comment

by:reggler
ID: 6440064
those are just default values...
after i defined the class in my code
TComPort *Com1_CP = new TComPort();
for example, i can change the Port by calling ComDSK_CP->ComPort = "COM1";
so i don't tink that this is the problem...

btw: if u need translation from the comment u can tell my
btwbtw: it's swiss german and not german ;o)

0
 
LVL 2

Expert Comment

by:bkdc
ID: 6440164
pardon me sir, i didn't know :)
 No,really, it's no problem with the comments.
 >>TComPort *Com1_CP = new TComPort();
for example, i can change the Port by calling ComDSK_CP->ComPort = "COM1";

 If the object is Com1_CP shouldn't you call Com1_CP->ComPort="COM1"; ?

 Anyway, you should have 2 objs.
 TComPort *Com1=new TComPort;
 TComPort *Com2=new TComPort;
 Com1->ComPort="COM1";
 Com2->ComPort="COM2";
 Com1->OpenComm();
 Com2->OpenComm();
....
 Com1->SendChar(..);
 Com2->SendChar(..);

....
Oh, i hope hComm is a member of TComPort and not a global var.
0
 

Author Comment

by:reggler
ID: 6440217
>>pardon me sir, i didn't know :)
>>No,really, it's no problem with the comments.
>>>>TComPort *Com1_CP = new TComPort();
>>for example, i can change the Port by calling ComDSK_CP->ComPort = "COM1";
>>
>>If the object is Com1_CP shouldn't you call Com1_CP->ComPort="COM1"; ?

Oh yes, you're right...sorry....was copy/paste failure :o)


i exactly have what u wrote...
and hComm is only in TComPort included...
0
 

Author Comment

by:reggler
ID: 6440509
if i call GetLastError after TransmitCommChar i receive error number 995 wich means:

//
// MessageId: ERROR_OPERATION_ABORTED
//
// MessageText:
//
//  The I/O operation has been aborted because of either a thread exit
//  or an application request.
//
#define ERROR_OPERATION_ABORTED          995L


what means that?
i don't know what error this is
0
 
LVL 2

Expert Comment

by:bkdc
ID: 6440905
Coffe break, so...

 Your approach should work fine... anyway it's not the best.
 I suppose you use TransmitCommChar by accident, however WriteFile/WriteFileEx is better.
 If you really,really need TransmitCommChar then do smth like this
  PurgeComm(..);
  TransmitCommChar(..);
  FlushFileBuffers(..);

check for errors after each of them and see what happens

READ THIS

Straight from the Bible:
"
The TransmitCommChar function is useful for sending an interrupt character (such as a CTRL+C) to a host system.

If the device is not transmitting, TransmitCommChar cannot be called repeatedly. Once TransmitCommChar places a character in the output buffer, the character must be transmitted before the function can be called again. If the previous character has not yet been sent, TransmitCommChar returns an error.
"
!!!Flood
Read and Write Operations
The Win32 API supports both synchronous and asynchronous (overlapped) file I/O operations on serial communications resources. Overlapped operations enable the calling thread to perform other tasks while the operation executes in the background. A thread uses the ReadFile or ReadFileEx function to read from a communications resource, and the WriteFile or WriteFileEx function to write to a communications resource. ReadFile and WriteFile can be performed synchronously or asynchronously. ReadFileEx and WriteFileEx can only be performed asynchronously.

The behavior of these read and write functions is affected by whether the function is executed as an overlapped operation, whether the time-out parameters are associated with the handle, and whether flow control parameters are associated with the handle.

A thread can also write to a communications resource by using the TransmitCommChar function, which transmits a specified character ahead of any pending data in the output buffer. This function is useful for transmitting a high priority signal character to the receiving system. Transmission of the high priority character is still subject to flow control and write time-outs, and the operation is performed synchronously.

A thread can use the PurgeComm function to discard all characters in a device's output or input buffer. PurgeComm can also terminate pending read or write operations, even if the operations have not been completed. If a thread uses PurgeComm to flush an output buffer, the deleted characters are not transmitted. To empty the output buffer while ensuring that the contents are transmitted, a thread can call the FlushFileBuffers function (a synchronous operation). Note, however, that FlushFileBuffers is subject to flow control but not to write time-outs, and it will not return until all pending write operations have been transmitted.

"
0
 

Author Comment

by:reggler
ID: 6443937
hi bkdc

okay, i did it now with WriteFile...

unsigned long *lpNumberOfBytesWritten;
  return WriteFile(
                   hComm,      // handle to file to write to
                   pfuedi,     // pointer to data to write to file
                   strlen(pfuedi),     // number of bytes to write
                   lpNumberOfBytesWritten,     // pointer to number of bytes written
                   NULL      // pointer to structure needed for overlapped I/O
                  );

(with enlish comment :o) )
it's the same error...
0
 
LVL 2

Expert Comment

by:bkdc
ID: 6444073
hmmm....
 Tell me some things.
1. computer type
2. what mouse (and/or other pointing device) do you have; of course, I'd like to know on what ports
3. do you have an internal modem
4. is COM2 enabled from bios
5. is COM2 sharing it's IRQ with anyone
6. is your app working fine when using just one COM (which one, or both are working properly)

That's all I can think of right now.
PS. just for curiosity, please post the TCom.h source too.
0
 

Author Comment

by:reggler
ID: 6444094
1. DELL OptiPlex GX110 633MHz, 128MB RAM
2. PS/2
3. no
4. yes
5. can't see, i'm not admin, sorry...
6. both COM-Ports works fine in another application. i saw that also both at one time work in another application, so the problem is my app.... but i don't know where the problem is...
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:reggler
ID: 6444096
//---------------------------------------------------------------------------
#ifndef HTTP_Handling_UH
#define HTTP_Handling_UH

//---------------------------------------------------------------------------
class TComPort
{
protected:  //Verborgene Methoden
    //Weiss num so gnau was de witz vo Protected isch

private:
    //Alles was doo stoot, isch noch usse "unsichtbar" und chan nume
    //klassa intern verwandet werde
    HANDLE hComm;                   // Handle fur RS232 Kommunikation
    COMMTIMEOUTS ComTimeoutOld_CTO; // Var fur alte RS232 Timeouts
    COMMTIMEOUTS ComTimeoutNew_CTO; // Var fur neue RS232 Timeouts

public:          // Benutzerdeklarationen
    AnsiString ComPort;               // Comportvariable
    AnsiString DeviceControl;         // DeviceControl String

    DWORD ReadTotalTimeoutConstant;
    DWORD ReadTotalTimeoutMultiplier;
    DWORD WriteTotalTimeoutConstant;
    DWORD WriteTotalTimeoutMultiplier;

    __fastcall TComPort(void);
    __fastcall ~TComPort(void);

    int __fastcall OpenComm(void);  // ComPort offnen.
    bool __fastcall CloseComm (void); //ComPort Schliessen.
    bool __fastcall SendChar(char pfuedi); //Buchstaben senden
    char* __fastcall ReceiveChar(int Value); //Buchstabe empfangen
};
//---------------------------------------------------------------------------
#endif
0
 
LVL 2

Expert Comment

by:bkdc
ID: 6444220
about the 6th question, Doesn't matter if the COM works in other apps, what I want to know is if it works with your app.

>>i've written a class (TComPort) for write and read
>>to/from the ComPort.
>>Now, i want to Open two (com1 & com2) but i can only
>>send on one com port....
>>what do u think is the failure?

 As far as I understand, your application (TComPort) works fine when using just one comm. Problems appear when you try to send data on the second comm too. Is that true ?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6449251
I don't see the code that you use to create and use the TComPort objects.  Perhaps one or both of the objects is falling out of scope and getting destructed.

-- Dan
0
 

Author Comment

by:reggler
ID: 6450578
hey, i found when the software works and when it doesn't

it woks when i boot up the pc and start my app.

it don't works if i opend HYPER TERMINAL before (after closing connection!)

what's the reason for that?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6451834
Hyperterminal will invoke TAPI which decides that it needs to own the com port.  

When that is the case, you should be getting an error return when you attempt to open the port or perhaps when you forst try to write to it.

-- Dan
0
 
LVL 2

Expert Comment

by:bkdc
ID: 6452903
I suppose you close the connection but Hyperterm is still opened. Close it ! Comm sharing is not implemented in RS232 chipset, so if you want to use it be careful not to let any other app access it
0
 

Author Comment

by:reggler
ID: 6455798
DanRollins
i received the error when sendig the data

bkdc
i closed the connection as well as the hyperterminal softw.....i know that there is no sharing implemented! if i take annother terminal software (older one) everything works fine

0
 
LVL 2

Expert Comment

by:bkdc
ID: 6456287
Then what's the problem. Why do you need HyperTerminal ?
0
 

Author Comment

by:reggler
ID: 6456292
i don't need it anymore...
think i'll delete this question...
0
 
LVL 1

Accepted Solution

by:
Computer101 earned 0 total points
ID: 6468443
Points reduced to 0 and placed in PAQ.  The questioner asked to delete this question, but alot of good info here, so I will PAQ.

Thank you
Computer101
Community Support Moderator
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now