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;
bool quit = false;
BOOL ConfigureSerialPort()
{
COMMTIMEOUTS TimeOuts = { 0 };
TimeOuts.ReadIntervalTimeout = 1000;
TimeOuts.ReadTotalTimeoutMultiplier = 500;
TimeOuts.ReadTotalTimeoutConstant = 5000;
TimeOuts.ReadIntervalTimeout = 1000;
TimeOuts.WriteTotalTimeoutConstant = 2000;
TimeOuts.WriteTotalTimeoutMultiplier = 500;
if (!SetCommTimeouts(hComm, &TimeOuts))
{
myMonitor::sendTxt("\nERROR: Set Com time out faild.");
};
DCB dcb;
if (!GetCommState(hComm, &dcb))
{
myMonitor::sendTxt("\nERROR: Get Comm state faild");
}
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = TWOSTOPBITS;
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",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (hComm == (HANDLE)-1)
{
myMonitor::sendTxt("\nPort opend");
return 0;
}
else
{
ConfigureSerialPort();
return 1;
}
}
BOOL ReadSerialPort()
{
char lpBuffer[256];
DWORD dwBytesRead = 256;
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))
{
ss << lpBuffer[i];
}
}
myMonitor::sendTxt(ss.str());
if (!bReadStatus)
{
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 ------------------------------------------
#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;
HANDLE RxThread;
DWORD ThreadID;
HINSTANCE hInst;
WCHAR szTitle[MAX_LOADSTRING];
WCHAR szWindowClass[MAX_LOADSTRING];
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);
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_SERIALHUB, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SERIALHUB));
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
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);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance;
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;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
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);
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);
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);
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);
switch (wmId)
{
case IDC_BUTTION_OPEN_COMM :
{
myMonitor::sendTxt("\n Init Open");
unsigned int index = 0;
char strText[255] = { 0 };
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);
OpenSerialPort(9, 9600);
RxThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)readPort, NULL, NULL, &ThreadID);
}break;
case IDC_BUTTION_CLOSE_COMM:
{
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);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
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;
}