[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Serial Port Programming with Visual C

Posted on 2004-03-22
21
Medium Priority
?
1,009 Views
Last Modified: 2012-05-04
I was wondering how to open, read and write to a serial port in Visual C 6? I have read the technical article in MSDN and do not really understand it. I was wondering if there is an easier way to read and write to the serial ports with minimal amounts of code?
0
Comment
Question by:changw414
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 7
  • 2
  • +1
21 Comments
 

Author Comment

by:changw414
ID: 10651802
Oh by the way im on a Win XP machine.
0
 
LVL 17

Assisted Solution

by:mokule
mokule earned 400 total points
ID: 10653318
Hi

m_hPort = ::CreateFile(m_sPort,      GENERIC_READ | GENERIC_WRITE,0, NULL,
                                     OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
if( GetCommState(m_hPort, &dcbPort) )
      {
                  dcbPort.BaudRate = atoi(m_sBody);
                  dcbPort.ByteSize = 8;
                  dcbPort.Parity = NOPARITY;
                  dcbPort.StopBits = ONESTOPBIT;
                        if(SetCommState(m_hPort, &dcbPort))
                        {
                                                                }
                 }


WriteFile(m_hPort, buf, ile, &nWyslane, NULL);
ReadFile(m_hPort, buf, ile, &nOdebrane, NULL);
0
 
LVL 6

Accepted Solution

by:
joghurt earned 100 total points
ID: 10653654
Well, the above example is basically OK. However, if there's not enough characters waiting in the input queue, your program will wait until the data arrives (or wait forever, if it won't). You can use the SetCommTimeouts function to set these time-out values.

And what's missing from the above code:
HANDLE m_hPort;
char m_sPort[] = "COM1:";
DCB dcbPort;
etc.

If you want to use more than 8 serial ports, use the syntax of "\\.\COM10" instead.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:changw414
ID: 10654210
thx, u were a great help!!!
0
 
LVL 17

Expert Comment

by:mokule
ID: 10655820
Hi changw414
If we were any help to u
You have five choices when it comes to closing your open questions....
http://www.experts-exchange.com/help.jsp#hs5
 
0
 
LVL 17

Expert Comment

by:mokule
ID: 10659284
Hi changw414
r u sure that u accepted good answer
0
 
LVL 6

Expert Comment

by:joghurt
ID: 10661266
mokule, neither do I think so. Sorry.
0
 
LVL 17

Expert Comment

by:mokule
ID: 10661411
thank you joghurt.
0
 

Author Comment

by:changw414
ID: 10662107
Yes his answer was very helpful. I figured out what I needed to do, Thanks...
0
 
LVL 17

Expert Comment

by:mokule
ID: 10662700
changw414
Just for curiosity. Could You explain me what information from whose answer was very helpful. I'll be happy to know that You choose what You want to.
0
 

Author Comment

by:changw414
ID: 10663178
both joghurt and moukle
0
 
LVL 17

Expert Comment

by:mokule
ID: 10663234
so why didn't u split points?
0
 

Author Comment

by:changw414
ID: 10663246
i didnt know how? Im new to this site.
0
 
LVL 17

Expert Comment

by:mokule
ID: 10663364
I'm also rather new. May be for that reason I'm so unhappy ;-) that u gave all points to joghurt and nothing to me. Generally I'm  curious whether it is possible to change ur mind afteri accepting some answer?

for splitting points or other informations read this
http://www.experts-exchange.com/Programming/Programming_Languages/C/help.jsp#hi19
0
 
LVL 17

Expert Comment

by:mokule
ID: 10663427
0
 

Author Comment

by:changw414
ID: 10663763
can i still split the points still?
0
 
LVL 17

Expert Comment

by:mokule
ID: 10663797
Not just simply split now, I think.
You should follow the link in my previous message.
0
 

Author Comment

by:changw414
ID: 10668986
yes please i wanna split it half and half, cause both tips were very helpful, I read your FAQ but I still dont see where to split the points.
0
 

Expert Comment

by:Mamata_gd
ID: 10855926
#include "stdio.h"
#include <windows.h>
#include <process.h>
#include <time.h>
#include <string.h>


int GetChksm(char *, int );
unsigned _stdcall WorkerThread(void);
void SetCommParameters(HANDLE);
bool openCommandFile();
bool writetoLogFile(CHAR *);
bool InitializeController();

#define MAX_MESSAGE            256
#define STX                        0x02
#define ETX                        0x03
#define MAX_IOC_MSG_LEN 240

int i;
HANDLE hComm, hMutex,hEvent;
CHAR CommandQ[35][MAX_MESSAGE];
volatile CHAR bridgebuffer[MAX_MESSAGE];
UCHAR seqNum = 'a';

main()
{
      HANDLE hThread = 0;
      CHAR buffer[MAX_MESSAGE];
      DWORD threadID,dwSomeData = 42;
      CHAR *pCommand,*pResponse;
      const char *portName = "COM3";
      UCHAR length;
      int j = 0;
                  
      if ( !openCommandFile() )
      {
            printf("Can not Create and open the file\n");
            return 0;
      }

      // Create the communication port
      hComm = CreateFile( portName,                                // Specify port device: default "COM1"
                                    GENERIC_READ | GENERIC_WRITE, // Specify mode that open device.
                                    0,                            // the devide isn't shared.
                                    NULL,                         // the object gets a default security.
                                    OPEN_EXISTING,                // Specify which action to take on file.
                                    0,                            // default.
                                    NULL);                        // default.

      if ( INVALID_HANDLE_VALUE == hComm )
      {
            printf("Communication handle could not create properly\n");
            return 0;
      }

      SetCommParameters(hComm);

    // Create the Synchronizaton object, called hMutex
      hMutex = CreateMutex(0,    // Security attrubutes
                                    FALSE, // Do not own the Mutex
                                    0);    // Nameless mutex

      if ( 0 == hMutex )
      {
            CloseHandle(hComm);
            return 0;
      }

      hEvent = CreateEvent(NULL,      // No security
                                    TRUE,      // Manual Reset
                                    FALSE,  // Initial state in not signaled
                                    NULL);  // No name to event

      if ( NULL == hEvent )
      {
            CloseHandle(hComm);
            CloseHandle(hMutex);
            return 0;
      }


      if ( !InitializeController() )
      {
            CloseHandle(hComm);
            CloseHandle(hMutex);
            CloseHandle(hEvent);
            return 0;
      }
      
      // Create and start the thread
      hThread = CreateThread( NULL, // Can not be inherited
                                          0,        // Default stack size
                                          (LPTHREAD_START_ROUTINE) WorkerThread, // Thread start function name
                                          NULL,                                                // No parameter passed
                                          0,                        
                                          &threadID);

      if ( hThread == 0 )
      {
            printf("Thread can not be created\n");
            CloseHandle(hComm);
            CloseHandle(hMutex);
            CloseHandle(hEvent);
            return 0;
      }

      // Go in loop till end of file.
      while (1)
      {
            printf("Enter the command: ");
            
            if ( fgets(&buffer[3],(MAX_MESSAGE-6),stdin) != NULL )
            {
                  if ((pCommand = strchr(&buffer[3], '\n')) != NULL)
                        *pCommand = '\0';
            }
            if ( !strcmp("quit",&buffer[3]) )
                  break;
   
            // Attach header
            pCommand = &buffer[0];
            *pCommand = STX;
            *(pCommand+1) = '0';
            *(pCommand+2) = seqNum;
            if ( seqNum == 't' )
                  seqNum = 'a';
            else
                  seqNum++;

            pResponse = strchr(pCommand,'\0');
            length = pResponse-pCommand;

            
            // Calculate checksum and attach trailer
            sprintf(&buffer[length],"%02x",GetChksm(buffer,length));
            buffer[length+2] = ETX;
            buffer[length+3] = '\0';


            // Aquire the Mutex
            WaitForSingleObject(hMutex,INFINITE);
            // Copy the command string into the Sendbuffer
            strncpy((char *)&bridgebuffer[0],buffer,strlen(buffer));
            //printf("String is %s and length %d \n",(char*)bridgebuffer,strlen((char *)bridgebuffer));
            // Relase the Mutex
            ReleaseMutex(hMutex);

            SetEvent(hEvent);

            Sleep(2000);
      }
      // Terminate thread

      // Close all the handles
      CloseHandle(hComm);

      CloseHandle(hThread);

      CloseHandle(hMutex);
      
      return 0;
}
      

int GetChksm(char *buf, int len)
{
      unsigned int total = 0, i;
      
      if (len < 4 || len >= MAX_IOC_MSG_LEN)
            return 0;
      
      for (i = total = 0; i < len; i++)
            total += *buf++;

      return ((~total) & 0xff);
}

#define EIGHT_SECONDS 2000

unsigned _stdcall WorkerThread()
{
      bool bResult;
      CHAR Sendbuffer[MAX_MESSAGE];
      CHAR Recvbuffer[MAX_MESSAGE];
      ULONG nbytes;
//      time_t   start, finish;
      UCHAR length;
      char *p;
      DWORD dwRes;

      // Start the time
      //time(&start);
      while (1)
      {
            // Loop till buffer gets some date to 8 seconds expires
            dwRes = WaitForSingleObject(hEvent,EIGHT_SECONDS);

            switch ( dwRes )
            {
                  case WAIT_OBJECT_0:
                        //Aquire the n=mutex
                        WaitForSingleObject(hMutex,INFINITE);
                        // Copy to senbuffer
                        strncpy(Sendbuffer,(char *)&bridgebuffer[0],strlen((char *)bridgebuffer));
                        // Fill the memory with NULL
                        strnset( (char *)&bridgebuffer[0], 0, MAX_MESSAGE );
                        // Release the Mutex
                        ReleaseMutex(hMutex);
                        // Get the length of command string
                        if ( ( p = strchr((char *)&Sendbuffer[0],ETX) ) != NULL )
                              length = p - ( (char *)&Sendbuffer[0] );

                        break;

                  case WAIT_TIMEOUT :
                        Sendbuffer[0] = STX;
                        Sendbuffer[1] = '0';
                        Sendbuffer[2] = 't';
                        Sendbuffer[3] = 'Z';
                        sprintf(&Sendbuffer[4],"%02x",GetChksm(Sendbuffer,4));
                        Sendbuffer[6] = ETX;

                        length = 7;
                        // And send the 'Z' command
                        break;
                  default :
                        printf("Error in WaitForSingleObject\n");
                        ExitThread(0);
            }

            ResetEvent(hEvent);
            
            // Start the counter again
            //time(&start);
            
            if ( writetoLogFile(Sendbuffer) )
            {
                  bResult  = WriteFile(hComm,                  // handle to file to write to
                                Sendbuffer,                        // pointer to data to write to file
                                length,             // number of bytes to write
                                &nbytes,NULL);   // pointer to number of bytes written
                  if ( FALSE == bResult)
                  {
                        printf("Writing of serial communication has problem.");
                        return FALSE;
                  }


                  // Wait for response in loop
                  nbytes = 0;
                  strnset(&Sendbuffer[0],0,MAX_MESSAGE);
                  strnset(&Recvbuffer[0],0,MAX_MESSAGE);
                  //Sleep(1000);
                  while (1)
                  {
                        Sleep(1000);
                        bResult = ReadFile(hComm,            // handle of file to read
                                            Recvbuffer,           // handle of file to read
                                            MAX_MESSAGE,      // number of bytes to read
                                            &nbytes,          // pointer to number of bytes read
                                            NULL);              // pointer to structure for data
                        if ( NULL == bResult )
                        {
                              printf("Reading of serial communication has problem.");
                              return FALSE;
                        }
                        if ( nbytes )
                        {
                              //printf("String = %s and length = %d\n",Recvbuffer,nbytes);
                              break;
                        }
                  }

                  bResult = writetoLogFile(Recvbuffer);
                  if ( 0 == bResult )
                  {
                        printf("Could not write the data to log file\n");
                        return 0;
                  }
            }
      }
      return 0;
}

void SetCommParameters(HANDLE hComm)
{
      DCB dcb = {0};
      DCB config;
//      DWORD dwCommEvent=0;
      COMMTIMEOUTS timeouts;

      if ( !GetCommTimeouts(hComm,&timeouts) )
            printf("Error getting Communication timeout\n");

//      timeouts.ReadIntervalTimeout = MAXDWORD;
      timeouts.ReadIntervalTimeout = 20;
      timeouts.ReadTotalTimeoutMultiplier = 3;
      timeouts.ReadTotalTimeoutConstant = 2;
      timeouts.WriteTotalTimeoutMultiplier = 3;
      timeouts.WriteTotalTimeoutConstant = 2;

      printf("ReadTimeIntervaltimeOut = %d\n",timeouts.ReadIntervalTimeout);
      printf("ReadTotalTimeoutMultiplier = %d\n",timeouts.ReadTotalTimeoutMultiplier);
      printf("ReadTotalTimeoutConstant = %d\n",timeouts.ReadTotalTimeoutConstant);
      printf("WriteTotalTimeoutMultiplier = %d\n",timeouts.WriteTotalTimeoutMultiplier);
      printf("WriteTotalTimeoutConstant = %d\n",timeouts.WriteTotalTimeoutConstant);


      if ( !SetCommTimeouts(hComm,&timeouts) )
            printf("Error Setting Communication Timeouts\n");
                                                                  
      if (!GetCommState(hComm, &dcb))
       // Error getting current DCB setting
         printf("Error getting current status\n");
    else
       // DCB is ready for use.
    {
          printf("BaudRate = %d StopBits = %d Parity %d and ByteSize = %d\n",
                                                 dcb.BaudRate,    // Specify buad rate of communicaiton.
                                                 dcb.StopBits,    // Specify stopbit of communication.
                                                dcb.Parity,      // Specify parity of communication.
                                                dcb.ByteSize);   // Specify  byte of size of communication.
          config = dcb;

          config.BaudRate = CBR_38400;
          config.StopBits = ONESTOPBIT;
          config.Parity = NOPARITY;
          config.ByteSize = 8;

          if ( SetCommState(hComm, &config))
            {
                if (GetCommState(hComm, &dcb) )
                        printf("BaudRate = %d StopBits = %d Parity %d and ByteSize = %d\n",
                                                            dcb.BaudRate,    // Specify buad rate of communicaiton.
                                                            dcb.StopBits,    // Specify stopbit of communication.
                                                            dcb.Parity,      // Specify parity of communication.
                                                            dcb.ByteSize);   // Specify  byte of size of communication.
            }
      }

}

bool openCommandFile()
{
      HANDLE hCommandFile=0;
      ULONG numberofbytes;//,nbytes;
      //bool bResult;
      CHAR buffer[MAX_MESSAGE];
      CHAR *pCommand;

      // Open the file where command strings are stored
      hCommandFile = CreateFile("c:\\ggg\\sioccmd\\command.txt",
                              GENERIC_READ|GENERIC_WRITE,
                              FILE_SHARE_READ,
                              NULL,                        // secuity
                              OPEN_EXISTING,            // existing always
                              0,0);

      // If CreateFile is unsuccessful
      if ( INVALID_HANDLE_VALUE == hCommandFile )
      {
            printf("Can not open the file and error = %d\n",GetLastError());
            return 0;
      }
      else
      {
            printf("File has been created successfully\n");
            printf("Handle = %p\n",hCommandFile);
      }

      int i = 0;
      int j = 0;
      int iFilePointer = 0;
      // read the file
      while ( (ReadFile(hCommandFile,&buffer[0],MAX_MESSAGE,&numberofbytes,NULL)) && numberofbytes )
      {
            while ( numberofbytes )
            {
                  // Find the line feed and replace with null character
                  if ( (pCommand = strchr( &buffer[i],'\n')) != NULL )
                  {
                        *(pCommand-1) = '\0';
                        strncpy( (char*)(CommandQ+j),&buffer[i],strlen(&buffer[i]));
                  }
                  else
                  {
                        iFilePointer += i;
                        if ( 0xFFFFFFFF == SetFilePointer(hCommandFile,iFilePointer,NULL,FILE_BEGIN) )
                        {
                              printf("Can not set the pointer\n");
                              return 0;
                        }
                        i = 0;
                        break;
                  }
                  pCommand++;
                  numberofbytes = numberofbytes-(pCommand - (&buffer[i]) );
                  i += (pCommand - (&buffer[i]) );
                  j++;      
            }
      }

      return 1;
}
                  
bool writetoLogFile(CHAR *buf)
{
      SYSTEMTIME st;
      char logData[280];
      FILE *fp;
//      char *p;
      
      GetLocalTime(&st);

      GetDateFormat( 0, 0, &st, "ddd',' MMM dd,yy",logData, sizeof(logData) );
      GetTimeFormat( 0, 0, &st, "  hh':'mm':'ss tt", logData+14, sizeof(logData) );

      strcat(logData," cmd/rsp: \0");

      for (;;)
      {
            if ( *buf >= 33 )
                  strncat(logData,buf,1);
            else if ( *buf >= 0 && *buf <= 32 )
            {
                  char aa[4];
                  sprintf(aa,"<%02d>",*buf);
                  strncat(logData,aa,4);
                  if ( * buf == ETX )
                        break;
            }
            buf++;
      }
            
      fp = fopen("c:\\ccc\\sioccmd\\log.txt","a+");
      fprintf(fp,"%s\n",logData);
      fclose(fp);

      return 1;
}


bool InitializeController()
{
      bool bResult;
      CHAR Sendbuffer[MAX_MESSAGE];
      CHAR Recvbuffer[MAX_MESSAGE];
      char *pCommand,*pResponse;
      ULONG nbytes;
      int stringlength,j = 0;

      while (1)
      {
            stringlength = strlen((char*)(CommandQ+j));
            strncpy(&Sendbuffer[3], (char*)(CommandQ+j),stringlength+1);
            
            
            if ( !(strcmp("quit",(char*)(CommandQ+j) ) ) )
                  break;

            j++;


            // Attach header
            pCommand = &Sendbuffer[0];
            *pCommand = STX;
            *(pCommand+1) = '0';
            *(pCommand+2) = seqNum;
            if ( seqNum == 't' )
                  seqNum = 'a';
            else
                  seqNum++;
            pResponse = strchr(pCommand,'\0');
            stringlength = pResponse-pCommand;

            
            // Calculate checksum and attach trailer
            sprintf(&Sendbuffer[stringlength],"%02x",GetChksm(Sendbuffer,stringlength));
            Sendbuffer[stringlength+2] = ETX;
            Sendbuffer[stringlength+3] = '\0';

            if ( writetoLogFile(Sendbuffer) )
            {
                  bResult  = WriteFile(hComm,                  // handle to file to write to
                                Sendbuffer,                        // pointer to data to write to file
                                stringlength+3,           // number of bytes to write
                                &nbytes,NULL);                  // pointer to number of bytes written
                  if ( FALSE == bResult)
                  {
                        printf("Writing of serial communication has problem.");
                        return FALSE;
                  }


                  // Wait for response in loop
                  nbytes = 0;
                  strnset(&Sendbuffer[0],0,MAX_MESSAGE);
                  strnset(&Recvbuffer[0],0,MAX_MESSAGE);
                  
                  while (1)
                  {
                        Sleep(1000);
                        bResult = ReadFile(hComm,            // handle of file to read
                                            Recvbuffer,           // handle of file to read
                                            MAX_MESSAGE,      // number of bytes to read
                                            &nbytes,          // pointer to number of bytes read
                                            NULL);              // pointer to structure for data
                        if ( FALSE == bResult )
                        {
                              printf("Reading of serial communication has problem.");
                              return FALSE;
                        }
                        if ( nbytes )
                        {
                              //printf("String = %s and length = %d\n",Recvbuffer,nbytes);
                              break;
                        }
                  }

                  bResult = writetoLogFile(Recvbuffer);
                  if ( 0 == bResult )
                  {
                        printf("Could not write the data to log file\n");
                        return 0;
                  }
            }
      }
      return TRUE;
}
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
Suggested Courses

656 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