Click here to Skip to main content
15,893,487 members

Win API serial port reading "C"

Member 12278335 asked:

Open original thread
I have written a Win API application. To read the Serial port Data. It was Work Fine in Console application without any trouble. When i try it on win32 gui application its dosent work fine some time it reads few chars only some time its read complete buffer...
Why its happens...

Those data i am sending from arduino by using "Serial.println("NM0");"
my code is written for the like below fromat:-
To read: 4(this is bytes to be read) -> NM0(This is data)

my out put shows like below

To read: 4 -> NM0

To read: 1 ->


To read: 4 -> NM1

To read: 1 ->


To read: 4 -> NM1

To read: 1 ->


To read: 2 -> NM

To read: 3 -> 0


To read: 4 -> NM0

To read: 1 ->


To read: 1 -> N

To read: 4 -> M0


To read: 1 -> N

To read: 4 -> M1


To read: 1 -> N

To read: 4 -> M1


To read: 4 -> NM0

To read: 1 ->


To read: 4 -> NM1

To read: 1 ->

What I have tried:

//----------------------Reading Port file..----------------------------

#pragma once

#include "stdafx.h"
#include <istream>
#include<ios>
#include <Windows.h>
#include <string>
#include <vector>
#include "myMonitor.h"
#include <sstream>

HANDLE hComm; // handel for the serial port
bool quit = false;
BOOL ConfigureSerialPort()
{
	// Setup Com Time Outs
	COMMTIMEOUTS TimeOuts = { 0 };
	TimeOuts.ReadIntervalTimeout = 1000; // Set Read Timeouts
	TimeOuts.ReadTotalTimeoutMultiplier = 500;
	TimeOuts.ReadTotalTimeoutConstant = 5000;
	TimeOuts.ReadIntervalTimeout = 1000;
	TimeOuts.WriteTotalTimeoutConstant = 2000; // Set Write Time Outs
	TimeOuts.WriteTotalTimeoutMultiplier = 500;

	if (!SetCommTimeouts(hComm, &TimeOuts))// Set Time Outs
	{
		myMonitor::sendTxt("\nERROR: Set Com time out faild.");
	};
	DCB dcb;

	if (!GetCommState(hComm, &dcb))
	{
		myMonitor::sendTxt("\nERROR: Get Comm state faild");
	}
	dcb.BaudRate = 9600; // Baud Rates
	dcb.ByteSize = 8;	// 8 bit per byte
	dcb.Parity = NOPARITY; // No Parity Bits
	dcb.StopBits = TWOSTOPBITS; //Two Stop Bits

	if (!SetCommState(hComm, &dcb))
	{
		myMonitor::sendTxt("\nERROR: Set Com State faild.");
		return true;
	}
	else
	{
		return false;
	}

	if (!PurgeComm(hComm, PURGE_TXCLEAR | PURGE_RXCLEAR))
	{
		myMonitor::sendTxt("\nERROR:  Comm Purge Faild.");
	}



}

BOOL OpenSerialPort(int portNo, int baud)
{
	hComm = CreateFile("\\\\.\\COM9", // COM Port
		GENERIC_READ | GENERIC_WRITE, // Configure for read and write
		0,
		NULL,
		OPEN_EXISTING, // Open existing without creating new 
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //Synchrnous Mode.
		NULL);
	if (hComm == (HANDLE)-1)
	{
		myMonitor::sendTxt("\nPort opend");
		return 0;
	}
	else
	{
		ConfigureSerialPort();
		return 1;
	}

}

BOOL  ReadSerialPort()
{
	char lpBuffer[256];
	DWORD dwBytesRead = 256; // read bytes
	COMSTAT ComStat;
	DWORD dwErrorFlag;
	OVERLAPPED m_osRead;
	stringstream ss;

	stringstream st;
	memset(&m_osRead, 0, sizeof(OVERLAPPED));
	m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	ClearCommError(hComm, &dwErrorFlag, &ComStat);
	dwBytesRead = min(dwBytesRead, (DWORD)ComStat.cbInQue);

	if (!dwBytesRead)return FALSE;

	BOOL bReadStatus;

	bReadStatus = ReadFile(hComm, lpBuffer, dwBytesRead, &dwBytesRead, &m_osRead);

	ss <<"To read: "<< (size_t)ComStat.cbInQue<<" -> ";

	for (size_t i = 0; i < (size_t)ComStat.cbInQue; i++)
	{
		if (i < sizeof(lpBuffer)) 
		{
			//printf("/n%c", lpBuffer[i]);
			ss << lpBuffer[i];
		}
	}
	
	myMonitor::sendTxt(ss.str());

	if (!bReadStatus) // if the Read File returns False
	{
		if (GetLastError() == ERROR_IO_PENDING)
		{
			WaitForSingleObject(m_osRead.hEvent, 2000);
			PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
			return dwBytesRead;
		}
		return 0;
	}
	PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

	memset(lpBuffer, 0, sizeof(lpBuffer));
	return dwBytesRead;
}


void readPort()
{
	while (!quit)
	{
		ReadSerialPort();
	}
}


///--------------------------------------------------------------------------------------
//----------------------Serial GUI app ------------------------------------------
// SerialHUB.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "SerialHUB.h"
#include <Windows.h>
#include "Init.h"
#include "myMonitor.h"
#include "Port.h"

#define MAX_LOADSTRING 100
#define IDC_BUTTION_OPEN_COMM 20003
#define IDC_BUTTION_CLOSE_COMM 20004
#define IDC_BUTTION_REFRESH 20005
#define IDC_CMBOX_PORT 20006
#define IDC_TXTBOX 20007
#define IDC_LBL_STATUS 20008

#define WNDOW_WIDTH 1000
#define WNDOW_HEIGHT 600
#define BTN_GAP (WNDOW_WIDTH-500)


HWND buttion_ConnectFSX;
HWND buttion_DisConnectFSX;
HWND buttion_OpenComm;
HWND buttion_CloseComm;
HWND buttion_Refresh;
HWND cbBox_Com;
HWND txtbox_Monitor;
HWND staticLable;

//Serial port Handle

HANDLE RxThread;
DWORD ThreadID;

// Global Variables:
HINSTANCE hInst;                                // current instance
WCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: Place code here.

    // Initialize global strings
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_SERIALHUB, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SERIALHUB));

    MSG msg;

    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SERIALHUB));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_SERIALHUB);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable
   //hWnd = CreateWindowW(szWindowClass, (LPCWSTR)"CockpitX-MCP", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
	   //CW_USEDEFAULT, CW_USEDEFAULT, 435, 350, nullptr, nullptr, hInstance, nullptr);


   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, CW_USEDEFAULT, WNDOW_WIDTH, WNDOW_HEIGHT, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
   myMonitor monitor(&txtbox_Monitor);
   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND  - process the application menu
//  WM_PAINT    - Paint the main window
//  WM_DESTROY  - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
	case WM_CREATE:
	{
		//Buttion
		buttion_OpenComm = CreateWindow("BUTTON", "Open COM", WS_CHILD | WS_VISIBLE | WS_BORDER | BS_PUSHBUTTON, BTN_GAP+283, 139, 121, 23, hWnd, (HMENU)IDC_BUTTION_OPEN_COMM, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);
		buttion_CloseComm = CreateWindow("BUTTON", "Close COM", WS_CHILD | WS_VISIBLE | WS_BORDER | BS_PUSHBUTTON, BTN_GAP+283, 168, 121, 23, hWnd, (HMENU)IDC_BUTTION_CLOSE_COMM, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);
		buttion_Refresh = CreateWindow("BUTTON", "Refresh", WS_CHILD | WS_VISIBLE | WS_BORDER | BS_PUSHBUTTON, BTN_GAP+283, 233, 121, 23, hWnd, (HMENU)IDC_BUTTION_REFRESH, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);
		
		//Combo Box;
		cbBox_Com = CreateWindow("COMBOBOX", NULL, WS_CHILD | ES_READONLY | WS_VISIBLE | WS_BORDER | WS_TABSTOP | CBS_DROPDOWN, BTN_GAP+284, 80, 125, 225, hWnd, (HMENU)IDC_CMBOX_PORT, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);
		initComboBox(&cbBox_Com);

		//Text Box;
		txtbox_Monitor = CreateWindow("EDIT", "Welcome\n", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE | WS_BORDER | ES_READONLY | ES_AUTOVSCROLL | ES_AUTOHSCROLL, 12, 12, BTN_GAP + 265, WNDOW_HEIGHT-100, hWnd, NULL, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);

		// Set the buttion endbled condtion 
		EnableWindow(GetDlgItem(hWnd, IDC_BUTTION_OPEN_COMM), TRUE);
		EnableWindow(GetDlgItem(hWnd, IDC_BUTTION_CLOSE_COMM), FALSE);
		EnableWindow(GetDlgItem(hWnd, IDC_CMBOX_PORT), TRUE);
	}
	break;
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // Parse the menu selections:
            switch (wmId)
            {
			case IDC_BUTTION_OPEN_COMM :
			{
				//Greeting to Command execution
				myMonitor::sendTxt("\n Init Open");

				//Get the selected port from the combobox
				unsigned int index = 0;
				char strText[255] = { 0 };
				//Get Selected index form the combobox.
				index = SendMessage(cbBox_Com, CB_GETCURSEL, 0, 0);
				SendMessage(cbBox_Com, CB_GETLBTEXT, index, (LPARAM)strText);
				string str = strText;
				myMonitor::sendTxt("\n Selected Port is " + str);

				//ConfigureSerialPort();
				OpenSerialPort(9, 9600);

				RxThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)readPort, NULL, NULL, &ThreadID);


			}break;
			case IDC_BUTTION_CLOSE_COMM:
			{
				//Closing of the port.
				quit = true;
				WaitForSingleObject(RxThread, INFINITE);
				
				CloseHandle(RxThread);


			}break;

            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code that uses hdc here...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}
Tags: C, Windows, Microcontroller, GUI, API, Serial port, Read/write

Plain Text
ASM
ASP
ASP.NET
BASIC
BAT
C#
C++
COBOL
CoffeeScript
CSS
Dart
dbase
F#
FORTRAN
HTML
Java
Javascript
Kotlin
Lua
MIDL
MSIL
ObjectiveC
Pascal
PERL
PHP
PowerShell
Python
Razor
Ruby
Scala
Shell
SLN
SQL
Swift
T4
Terminal
TypeScript
VB
VBScript
XML
YAML

Preview



When answering a question please:
  1. Read the question carefully.
  2. Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  3. If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
  4. Don't tell someone to read the manual. Chances are they have and don't get it. Provide an answer or move on to the next question.
Let's work to help developers, not make them feel stupid.
Please note that all posts will be submitted under the http://www.codeproject.com/info/cpol10.aspx.



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900