I'm trying to configure my C++ application to communicate with a device using the COM port. I can currently do it using the HTerm software:
However, when I try to do my C++ implementation, I can't read any byte from the port. This is my program, based in this answer:
#include "stdafx.h"
#include <stdio.h>
#include <conio.h>
#include <string>
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
int main(int argc, char **argv) {
int ch;
char buffer[10] = {"\0"};
HANDLE file;
COMMTIMEOUTS timeouts;
DWORD read, written;
DCB port;
HANDLE keyboard = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode;
std::wstring port_name = s2ws("\\\\.\\COM4");
char init[] = "5000000555";
// open the comm port.
file = CreateFile(port_name.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (INVALID_HANDLE_VALUE == file) {
printf("opening file");
return 1;
}
// get the current DCB, and adjust a few bits to our liking.
memset(&port, 0, sizeof(port));
port.DCBlength = sizeof(port);
if (!GetCommState(file, &port))
printf("getting comm state");
if (!SetCommState(file, &port))
printf("adjusting port settings");
DCB dcbSerialParams = { 0 }; // Initializing DCB structure
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
dcbSerialParams.BaudRate = CBR_115200; // Setting BaudRate = 115200
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8
dcbSerialParams.StopBits = ONESTOPBIT; // Setting StopBits = 1
dcbSerialParams.Parity = NOPARITY;
if (!GetCommState(file, &dcbSerialParams))
printf("getting serial params");
if (!SetCommState(file, &dcbSerialParams))
printf("adjusting serial params");// Setting Parity = None
SetCommState(file, &dcbSerialParams); //Configuring the port according to settings in DCB
PurgeComm(file, PURGE_TXABORT | PURGE_RXABORT); // Clear up the queue
// set short timeouts on the comm port.
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 1;
if (!SetCommTimeouts(file, &timeouts))
printf("setting port time-outs.");
// basic terminal loop:
do {
if (!WriteFile(file, init, sizeof(init), &written, NULL)) {
printf("writing data to port");
}
else {
printf("written %lu bytes\n", written);
}
Sleep(1000);
if (written != sizeof(init))
printf("not all data written to port");
// check for data on port and display it on screen.
BOOL Status = ReadFile(file, buffer, sizeof(buffer), &read, NULL);
if (Status) {
printf("received %lu bytes\n", read);
}
// check for keypress, and write any out the port.
if (_kbhit()) {
ch = _getch();
WriteFile(file, &ch, 1, &written, NULL);
printf("closing...");
}
// until user hits ctrl-backspace.
} while (ch != 127);
// close up and go home.
CloseHandle(keyboard);
CloseHandle(file);
return 0;
}
This is the output in the console:
written 11 bytes
received 0 bytes
written 11 bytes
received 0 bytes
....
Any ideas about what's going on?
EDIT 1
As @rveerd suggests, I tried disabling the handshake with these lines, same result:
dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE;
dcbSerialParams.fDtrControl = DTR_CONTROL_DISABLE;
dcbSerialParams.fOutxCtsFlow = 0;
dcbSerialParams.fOutxDsrFlow = 0;
dcbSerialParams.fNull = 0;
dcbSerialParams.fOutX = 0;
dcbSerialParams.fInX = 0;
