none
serial port to poll on request

    Question

  • I currently have two programs("reading" and "writing") and each program run on one PC to do textfile transferring/logging. The program is run in widows and is a DOS application written in c++. The PCs is connected via a null modem cable. The programs work but it is working in a way that i have to run the "reading" program first to let it poll before i can run the "writing" program to send the content of the text file.

    How do i make it in a way that the "reading" program will only start polling upon request from the "writing" program? Meaning, when i clicked the "writing" program to send the data, it will communicate with the "reading" program to start and get ready to receive.


    This is my codes for the "reading" side (Upon receiving the content from the "writing" side, it will log it into a text file called "new.txt")

    #include "windows.h"
    
    #include <stdio.h>
    
    #include <ctype.h>
    
    #include <io.h>
    
    #include <conio.h>
    
    #include <stdlib.h>
    
    #define maxBytes 111
    
    int main()
    
    {
    
     HANDLE hSerial;
    
     DCB dcbSerialParams = {0};
    
     COMMTIMEOUTS timeouts = {0};
    
     DWORD dwBytesRead = 0;
    
     char szBuff[maxBytes] = {0};
    
     int firstdigit = 0;
    
     FILE *fp;
    
     int i;
    
     //opening the serial port
    
     hSerial = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    
     if(hSerial==INVALID_HANDLE_VALUE)
    
     {
    
      if(GetLastError()==ERROR_FILE_NOT_FOUND)
    
      {
    
       printf("Serial port does not exist\n");
    
      }
    
      printf("Other errors\n");
    
     }
    
     //setting parameters
    
     dcbSerialParams.DCBlength = sizeof (dcbSerialParams);
    
     //GetCommState is to retrieves the current control settings for a specific communications device.
    
     if (!GetCommState(hSerial, &dcbSerialParams))
    
     {
    
      printf("Not GetCommState, not able to retrieves the current control\n");
    
     }
    
     dcbSerialParams.BaudRate = CBR_115200;
    
     dcbSerialParams.ByteSize = 8;
    
     dcbSerialParams.StopBits = ONESTOPBIT;
    
     dcbSerialParams.Parity = NOPARITY;
    
     //SetCommState configures a communications device according to the specifications
    
     //in DCB. The function reinitializes all hardware control settings but it does not
    
     //empty output or input queues
    
     if (!SetCommState(hSerial, &dcbSerialParams))
    
     {
    
      printf("Not SetCommState, cannot configures serial port according to DCB specifications set\n");
    
     }
    
     //setting timeouts
    
     timeouts.ReadIntervalTimeout = 40;
    
     timeouts.ReadTotalTimeoutConstant = 40;
    
     timeouts.ReadTotalTimeoutMultiplier = 40;
    
     timeouts.WriteTotalTimeoutConstant = 40;
    
     timeouts.WriteTotalTimeoutMultiplier = 40;
    
     //SetCommTimeouts set the time out parameters for all read and write operation
    
     if (!SetCommTimeouts(hSerial, &timeouts))
    
     {
    
      printf("Not SetCommTimeouts, cannot set the timeout parameters to serial port\n");
    
     }
    
     //reading data
    
     //ReadFile reads data from the specified file or i/o devices.
    
     printf("The content inside the file: \n\n");
    
     if(!ReadFile(hSerial, szBuff, maxBytes, &dwBytesRead, NULL))
    
     {
    
       printf("error\n");
    
     }
    
     else
    
     {
    
      fp = fopen("c:\\new.txt", "w");
    
      while (ReadFile(hSerial, szBuff, maxBytes, &dwBytesRead, NULL))
    
      {
    
       
    
       for (i = 0; i < dwBytesRead; i++)
    
       {
    
        if (szBuff[i] == 10 || szBuff[i] == 13)
    
        {
    
         fprintf(fp, "\n");
    
         printf("\n");
    
         break;
    
        }
    
        else
    
        {
    
        fprintf(fp, "%c", szBuff[i]);
    
        printf("%c", szBuff[i]); 
    
        }
    
       }
    
           
    
      }
    
      fclose(fp);
    
     CloseHandle(hSerial);
    
     }
    
    }
    
    


    This is my codes for thw "writing" side (The program will read the content inside a textfile called "helloworld.txt" and write it line by line to the serial port)

    #include "windows.h"
    
    #include <stdio.h>
    
    #include <io.h>
    
    #include <conio.h>
    
    #include <stdlib.h>
    
    #define maxBytes 111
    
    #define MAX 256
    
    int main()
    
    {
    
     HANDLE hSerial;
    
     DCB dcbSerialParams = {0};
    
     COMMTIMEOUTS timeouts = {0};
    
     DWORD dwBytesWrite = 0;
    
     int i;
    
     char szBuff[maxBytes];
    
     char stemp[MAX];
    
     FILE *fp;
    
    
    
     //opening the serial port
    
     hSerial = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    
     if(hSerial==INVALID_HANDLE_VALUE)
    
     {
    
      if(GetLastError()==ERROR_FILE_NOT_FOUND)
    
      {
    
       printf("Serial port does not exist\n");
    
      }
    
      printf("Other errors\n");
    
     }
    
     //setting parameters
    
     dcbSerialParams.DCBlength = sizeof (dcbSerialParams);
    
     //GetCommState is to retrieves the current control settings for a specific communications device.
    
     if (!GetCommState(hSerial, &dcbSerialParams))
    
     {
    
      printf("Not GetCommState, not able to retrieves the current control.\n");
    
     }
    
     dcbSerialParams.BaudRate = CBR_115200;
    
     dcbSerialParams.ByteSize = 8;
    
     dcbSerialParams.StopBits = ONESTOPBIT;
    
     dcbSerialParams.Parity = NOPARITY;
    
     //SetCommState configures a communications device according to the specifications
    
     //in DCB. The function reinitializes all hardware control settings but it does not
    
     //empty output or input queues
    
     if (!SetCommState(hSerial, &dcbSerialParams))
    
     {
    
      printf("Not SetCommState, cannot configures serial port according to DCB specifications set.\n");
    
     }
    
     //setting timeouts
    
     timeouts.ReadIntervalTimeout = 40;
    
     timeouts.ReadTotalTimeoutConstant = 40;
    
     timeouts.ReadTotalTimeoutMultiplier = 40;
    
     timeouts.WriteTotalTimeoutConstant = 40;
    
     timeouts.WriteTotalTimeoutMultiplier = 40;
    
     //SetCommTimeouts set the time out parameters for all reand and write operation
    
     if (!SetCommTimeouts(hSerial, &timeouts))
    
     {
    
      printf("Not SetCommTimeouts, cannot set the timeout parameters to serial port.\n");
    
     }
    
     //Writting data
    
     //WriteFile write data from the specified file or i/o devices.
    
     printf("The content inside the file: \n\n");
    
     fp = fopen("c:\\helloworld.txt", "r");
    
     while ((fgets(stemp, MAX, fp)) != NULL)
    
     {
    
      i = sprintf(szBuff, "%s", stemp);
    
      if (!WriteFile(hSerial, szBuff, maxBytes, &dwBytesWrite, NULL))
    
      {
    
       printf("Serial port cannot write file.\n");
    
      }
    
      else
    
      {
    
        printf("%s", szBuff);
    
      }
    
     }
    
     fclose(fp);
    
     CloseHandle(hSerial);
    
    }

    I know that this is just a small program but how do i make the "reading" program poll only when the "writing" program is trying to send data?

    Someone please help, new in serial port.

    Thursday, June 11, 2009 4:58 AM

Answers

  • The serial communication standard (RS-232) has signals available for "flow control."  The sender raises RTS (Request to Send) signal and waits for the receiver to raise CTS (Clear to Send) signal before it sends.  So the sender will not send until the receiver is ready.  You can enable this behavior for Windows ports with the SetCommState API. 

    The null modem cable must have the appropriate wiring.  This link is a short tutorial about the signals:
    http://www.zytrax.com/tech/layer_1/cables/heavy.htm
    Thursday, June 11, 2009 3:59 PM
  • Yup, hardware handshake.  Set DCB.fOutxDsrFlow to 1.  Return the favor with DCB.fDtrControl.  DSR/DTR are a "device is ready" handshake.  CTS/RTS is a "program is ready" handshake.  But it usually works either way in Windows.  Unless the device draws power from the PC.

    Hans Passant.
    • Marked as answer by Nancy Shao Wednesday, June 17, 2009 3:24 AM
    Friday, June 12, 2009 1:03 AM
    Moderator

All replies

  • see this function call:
    BOOL WaitCommEvent(
      HANDLE
    hFile,                // handle to communications device
      LPDWORD lpEvtMask,           // pointer to variable to receive event
      LPOVERLAPPED lpOverlapped,   // pointer to overlapped structure
    );
    Thursday, June 11, 2009 11:29 AM
  • The serial communication standard (RS-232) has signals available for "flow control."  The sender raises RTS (Request to Send) signal and waits for the receiver to raise CTS (Clear to Send) signal before it sends.  So the sender will not send until the receiver is ready.  You can enable this behavior for Windows ports with the SetCommState API. 

    The null modem cable must have the appropriate wiring.  This link is a short tutorial about the signals:
    http://www.zytrax.com/tech/layer_1/cables/heavy.htm
    Thursday, June 11, 2009 3:59 PM
  • Yup, hardware handshake.  Set DCB.fOutxDsrFlow to 1.  Return the favor with DCB.fDtrControl.  DSR/DTR are a "device is ready" handshake.  CTS/RTS is a "program is ready" handshake.  But it usually works either way in Windows.  Unless the device draws power from the PC.

    Hans Passant.
    • Marked as answer by Nancy Shao Wednesday, June 17, 2009 3:24 AM
    Friday, June 12, 2009 1:03 AM
    Moderator