Program character interpretation USB ports

Hi all,

I am working on a program that takes a character input from the user and sends information through USB ports to motor controllers of a robot. The purpose of this is to move the robot in any direction specified by the user. Basically the pseudo layout looks like this:

Q W E

A S D F G

Z X C

Each of these buttons has a meaning:

Q= northwest
W= forward
E= northeast
A= left
S= stop
D= right
Z= southwest
X= reverse
C= southeast
F= rotate ccw
G= rotate cw

I have started out with some basic code, but I am a little stuck as to where to go from here. I need to somehow communicate to the two USB ports (COMM4 and COMM5) on my laptop, and to write commands to those ports.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <conio.h>

void main ()
{
	char key;

	printf("Use Q W E A S D Z X C F G to control: \n");
	while (getchar()) 
	{
		std::cin >> key;
		if (_kbhit()) 
		{
			switch(key)		//need to communicate with the two USB ports
			{
				case 'q':
					{ /*move northwest*/ };

				case 'w':
					{ /*move forward*/ };

				case 'e':
					{ /*move northeast*/ };

				case 'a':
					{ /*move left*/ };

				case 's':
					{ /*stop*/ };

				case 'd':
					{ /*move right*/ };

				case 'z':
					{ /*move southwest*/ };

				case 'x':
					{ /*move reverse*/ };
				
				default: {};	//do nothing
			}
		}
	}
	return;
}


If someone could steer me in the right direction it would be strongly appreciated. Thanks.

Ian
Does anybody have an idea how to do this? Or is it even possible in C++ language?
Of course it's possible. You just need the right libraries (something to detect key presses and key releases and something to communicate via your USB ports). I think the Windows API permits you to do both, but I discourage the use of system APIs.

-Albatross
Here is my code so far. Hoping I am on the right track..
I ran into some errors, such as _hCom was undefined in multiple areas. Not sure what type of value it should be. The other error is this: ''CreateFileW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR'".



header file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef _COMPORT_H
#define _COMPORT_H

#include <windows.h>
#include <string.h>

bool  openComPort  (const char* port, const char* baudrate);

void  closeComPort (void);

DWORD sendData     (const char* data, DWORD size);

DWORD receiveData  (char* data, DWORD size);

#endif /* _COMPORT_H */ 



cpp file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "comport.h"

static HANDLE _hcom;

#include <iostream>
#include <stdio.h>
#include <conio.h>

bool openComPort (const char* port, const char* baudrate)
{
	char buildStr[50];
	DCB dcb;       
	COMMTIMEOUTS timeouts = {0};
             
            
	_hCom = CreateFile(port,
					  GENERIC_READ | GENERIC_WRITE,
                      0,
                      0,
                      OPEN_EXISTING,
                      0,
                      0);

	if(_hCom == INVALID_HANDLE_VALUE)   
	{
		_hCom = NULL;
		return FALSE;
	}

	/* set timeouts */
	timeouts.ReadTotalTimeoutConstant    = 100;
	timeouts.ReadTotalTimeoutMultiplier  = 0;
	timeouts.WriteTotalTimeoutMultiplier = 0;
	timeouts.WriteTotalTimeoutConstant   = 0;

	if(SetCommTimeouts(_hCom, &timeouts) == FALSE)
		{return FALSE;}

	dcb.DCBlength = sizeof(DCB);
	
	if(GetCommState(_hCom, &dcb) == FALSE)
		{return FALSE;}

	/* Simplified way of setting up the COM port using strings: */
	buildStr[0] = '\0';
	strcat(buildStr, "baud=");
	strcat(buildStr, baudrate);
	strcat(buildStr," parity=N data=8 stop=1");

	/* (A more effective way is to setup the members of the DCB struct manually, 
		then you don't need BuildCommDCB) */

	BuildCommDCB(buildStr, &dcb);
	return SetCommState(_hCom, &dcb);
}  


void closeComPort(void)
{
	CloseHandle(_hCom);
}


DWORD sendData (const char* data, DWORD size)
{
	DWORD numberOfBytesWritten;
  
	WriteFile(_hCom,
		       data,
			   size,
			   &numberOfBytesWritten,
			   0);

	return numberOfBytesWritten;
}


DWORD receiveData (char* data, DWORD size)
{
	DWORD numberOfBytesRead;
  
	ReadFile(_hCom,
              data,
              size,
              &numberOfBytesRead,
              0);

	return numberOfBytesRead;
}

int main ()
{
	unsigned key1, key2;
	const char* baudrate = "9600";
	const char* port1 = "com4";
	const char* port2 = "com5";
	openComPort(port1, baudrate);
	openComPort(port2, baudrate);

	printf("Use Q W E A S D Z X C F G to control: \n");
	
	do
	{
		key1 = _getche();	//outer test
		_putch('\x8');		//input backspace
		
		if (key1 == 0)
		{
			key2 = _getche();	//inner test
			_putch('\x8');
			
			while (_kbhit()=='q')
			{printf("NW");};		//move northwest

			while (_kbhit()=='w')
			{printf("FWD");};		//move forward

			while (_kbhit()=='e')
			{printf("NE");};		//move northeast

			while (_kbhit()=='a')
			{printf("L");};			//move left

			if (_kbhit()=='s')
			{printf("STOP");
			break;};				//stop operation

			while (_kbhit()=='d')
			{printf("R");};			//move right

			while (_kbhit()=='z')
			{printf("SW");};		//move southwest

			while (_kbhit()=='x')
			{printf("REV");};		//back up
					
			while (_kbhit()=='c')
			{printf("SE");};		//move southeast

			while (_kbhit()=='f')
			{printf("CCW");};		//rotate counter-clockwise

			while (_kbhit()=='g')
			{printf("CW");};		//rotate clockwise
		}		
	}

	while (key1 != 27);	//escape key

	return 0;
}

Does anybody know what these errors mean, and how I can correct them?
the _hCom one is straight forward.
line 3 (of the cpp) says static HANDLE _hcom; - notice the spelling.

with regard to this:
''CreateFileW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR'".
It is because you are setup to do a UNICODE (wide string) build - so the CreateFile call is being mapped to
the CreateFileW - CreateFileWide _ function - and this function takes pointers to wide char strings - LPCWSTR.

There are at least 3 ways to correct this error:
The first and easiest two are:

1. Undefine the UNICODE and the _UNICODE macros - like this:
1
2
3
4
5
6
7
8
9
#ifndef _COMPORT_H
#define _COMPORT_H

#undef _UNICODE
#undef UNICODE

#include <windows.h>
#include <string.h>


2. Specifically the non-unicode version of the CreateFile function -which is called CreateFileA -like this
1
2
3
4
5
6
7
8
9
	
_hCom = CreateFileA(port,		
     GENERIC_READ | GENERIC_WRITE,
     0,
     0,
     OPEN_EXISTING,
     0,
     0);
Last edited on
Awesome thanks! That fixed the problems :) now i just need to somehow send commands via the com ports (specifically 4 and 5). You will notice that I have the pseudo code pretty much written for the controls. Of course, I am commanding some motor drivers, so kinematics will play a role. I need the motors to operate so the output speed will be 1 m/s in every direction (3-axis system). Has anybody ever done this?
Topic archived. No new replies allowed.