P300 Output --> Serial Com Port
-
jjbaker
- Posts: 9
- Joined: 07 May 2008, 11:58
P300 Output --> Serial Com Port
I need to output the letters selected by the user in the P300 speller to a serial communications port.
Has anybody already done this?
If not, is it something as simple as modifying a few lines in a module? Where should I start?
Thanks in advance!
John
Has anybody already done this?
If not, is it something as simple as modifying a few lines in a module? Where should I start?
Thanks in advance!
John
-
gschalk
- Posts: 615
- Joined: 28 Jan 2003, 12:37
P3Speller ...
John,
The best way to do this may be to use the UDP-based protocol that is built into the P3Speller. Using this protocol, which can be enabled using the parameter DestinationAddress that is described on
http://www.bci2000.org/wiki/index.php/U ... pellerTask
you can write a little external program in any programming language that reads the characters from UDP and sends them to a serial port.
Of course, you may also modify the existing P3Speller code, but this would mean it would not directly take advantage of potential future improvements to the P3Speller that comes with BCI2000.
Gerwin
The best way to do this may be to use the UDP-based protocol that is built into the P3Speller. Using this protocol, which can be enabled using the parameter DestinationAddress that is described on
http://www.bci2000.org/wiki/index.php/U ... pellerTask
you can write a little external program in any programming language that reads the characters from UDP and sends them to a serial port.
Of course, you may also modify the existing P3Speller code, but this would mean it would not directly take advantage of potential future improvements to the P3Speller that comes with BCI2000.
Gerwin
-
mellinger
- Posts: 1341
- Joined: 12 Feb 2003, 11:06
John,
a program that redirects UDP input into serial output would be quite short, something along the following lines:
Regards,
Jürgen
a program that redirects UDP input into serial output would be quite short, something along the following lines:
Code: Select all
#include "SockStream.h"
#include "SerialStream.h"
using namespace std;
int
main( int, char** )
{
receiving_udpsocket s( "localhost:5000" );
sockstream input( s );
serialstream output( "COM1" );
string line;
while( getline( input, line ) )
output << line << endl;
return 0;
}
Jürgen
Last edited by mellinger on 14 May 2008, 14:03, edited 3 times in total.
-
jjbaker
- Posts: 9
- Joined: 07 May 2008, 11:58
Hi, thanks that worked perfectly. I had to do the following to get it to compile. I'm using the Dev-C++ IDE (http://www.bloodshed.net/dev/devcpp.html) which is freeware, open source and I think follows C++ standards pretty closely.
Will output just the character in question to your serial com port. I'd also suggest adding unix styled command line options for changing the host:port and com-port if you use Jürgen's code.
Thanks again!
John[/size]
- 1. Find SockStream.h/cpp and SerialStream.h/cpp, and add them to the project.
- BCI2000 SVN Source Code\src\shared\utils
- Project > Project Options > Parameters Tab > Add Library or Object
C:/Dev-Cpp/lib/libws2_32.a
3. Tell the compiler where to find the string type:Code: Select all
std::string line;
Code: Select all
output << line[17] << std::endl;Thanks again!
John[/size]
-
mellinger
- Posts: 1341
- Joined: 12 Feb 2003, 11:06
John,
thanks for your helpful feedback.
I added a line to the example program above in order to fix the compilation problem.
Regards,
Juergen
thanks for your helpful feedback.
I added a line
Code: Select all
using namespace std;Regards,
Juergen
-
mellinger
- Posts: 1341
- Joined: 12 Feb 2003, 11:06
John,
using the extractor (>>) rather than the inserter (<<), or getline(), should work for you:
For more details about C++ iostreams, see http://www.parashift.com/c++-faq-lite/input-output.html, or a C++ textbook.
Regards,
Juergen
using the extractor (>>) rather than the inserter (<<), or getline(), should work for you:
Code: Select all
serialstream input( "COM1" );
// Read a name and a number separated by white space:
int number = 0;
string name;
input >> name >> number;
// Read to the next newline:
string line;
getline( input, line );Regards,
Juergen
Last edited by mellinger on 22 May 2008, 12:24, edited 1 time in total.
-
jjbaker
- Posts: 9
- Joined: 07 May 2008, 11:58
I ended up using a different h/cpp for the serial communications. For some reason, whenever I tried to read the serial buffer with SerialStream.h/cpp, I'd get the first set of information but nothing after that. The getch()/break setup works in other similar programs but isn't working here for some reason but other than that, the program performs perfectly.
If you have any suggestions on the coding to make it shorter, more elegant, or more inline with professional programming style, I'm all ears as most C/C++ I've done in the past was personal or academic. I have comments in the official version but removed them here for conciseness.
Thanks again for all the help!
The comport.h/cpp was posted here by Daniel Lundin from Stockholm, Sweden.
If you have any suggestions on the coding to make it shorter, more elegant, or more inline with professional programming style, I'm all ears as most C/C++ I've done in the past was personal or academic. I have comments in the official version but removed them here for conciseness.
Thanks again for all the help!
Code: Select all
u2s.cpp
/* UDP to Serial (u2s.cpp)
This program takes the UDP packets outputed by a host at specified port,
parses them and redirects them to specified serial com port, it then reads
the same com port for any returning information.*/
#include <conio.h>
#include "comport.h"
#include "SockStream.h"
using namespace std;
int main(int argc, char *argv[])
{
//////////////////////////// Intialize Variables ///////////////////////////
int buffIn=8;
int buffOut=0;
char serIn[8]={'\0'};
char userInput='\0';
char baud[]="9600";
string line("");
string parsed("");
string hostIP("localhost");
string hostPort("5000");
string host("");
string port="COM5";
int swNum=1;
/////////////////////////// Command Line Parsing ///////////////////////////
while ((swNum < argc) && (argv[swNum][0]=='-')) {
string sw = argv[swNum];
if (sw=="-h"){
cout << "Usage: u2s -i <host> -p <port> -c <com port>\n";
cout << "Example: u2s -i localhost -p 5000 -c 5\n";
cout << "Omissions will use defaults: localhost:5000, COM5\n";
system("PAUSE");
return 1;
}
else if (sw=="-i") {
swNum++;
hostIP = argv[swNum];
}
else if (sw=="-p") {
swNum++;
hostPort = argv[swNum];
}
else if (sw=="-c") {
swNum++;
port = argv[swNum];
port = "COM"+port;
}
else
cout << "Unknown switch: " << argv[swNum] << endl;
swNum++;
}
host=hostIP+":"+hostPort;
///////////////////////////// Data Redirection /////////////////////////////
if(!openComPort(port.c_str(),baud)){
cout << "Could not open " << port << '\n';
system("PAUSE");
return 1;
}
receiving_udpsocket s( host.c_str() );
sockstream udpIn( s );
cout << "Redirecting traffic from "<< host << " to " << port << ".\n\n";
while(1){
if(getline(udpIn,line)){
parsed=line[17];
buffOut=parsed.length();
sendData(parsed.c_str(),buffOut);
cout << "U2S: " << parsed << endl;
}
for(int i=0; i<buffIn; i++){
serIn[i]='\0';
}
if(readData(serIn,buffIn))
cout << "S2U: " << serIn << endl;
if (kbhit()){
userInput = getch();
if (userInput == 27)
break;
}
}
closeComPort();
return 0;
}
Code: Select all
comport.h
#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 */Code: Select all
comport.c
#include "comport.h"
static HANDLE _hCom;
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;
}
-
Gesanan
- Posts: 5
- Joined: 20 Jan 2009, 11:13
Hi.
When I try to compile this piece of code I got these Compilation Errors:
E2209: Unable to open include file 'SockStream.h"
E2209: Unable to open include file 'SockStream.h"
I've looked for and I don't have these files on my PC.
What can I do?
Thank you very much.
Gesanan
When I try to compile this piece of code I got these Compilation Errors:
E2209: Unable to open include file 'SockStream.h"
E2209: Unable to open include file 'SockStream.h"
I've looked for and I don't have these files on my PC.
What can I do?
Thank you very much.
Gesanan
mellinger wrote:John,
a program that redirects UDP input into serial output would be quite short, something along the following lines:
Regards,Code: Select all
#include "SockStream.h" #include "SerialStream.h" using namespace std; int main( int, char** ) { receiving_udpsocket s( "localhost:5000" ); sockstream input( s ); serialstream output( "COM1" ); string line; while( getline( input, line ) ) output << line << endl; return 0; }
Jürgen
-
jjbaker
- Posts: 9
- Joined: 07 May 2008, 11:58
It's available as part of the BCI2000 source code release:
BCI2000 SVN Source Code\src\shared\utils
BCI2000 SVN Source Code\src\shared\utils
Gesanan wrote:Hi.
When I try to compile this piece of code I got these Compilation Errors:
E2209: Unable to open include file 'SockStream.h"
E2209: Unable to open include file 'SockStream.h"
I've looked for and I don't have these files on my PC.
What can I do?
Thank you very much.
Gesanan
mellinger wrote:John,
a program that redirects UDP input into serial output would be quite short, something along the following lines:
Regards,Code: Select all
#include "SockStream.h" #include "SerialStream.h" using namespace std; int main( int, char** ) { receiving_udpsocket s( "localhost:5000" ); sockstream input( s ); serialstream output( "COM1" ); string line; while( getline( input, line ) ) output << line << endl; return 0; }
Jürgen
-
Gesanan
- Posts: 5
- Joined: 20 Jan 2009, 11:13
Thank you very much. I've found SerialStream at:
root/tags/BCI2000.v1.4/src/shared
However I can't find SockStream.
Could somebody tell me where I could find it?
Thanks a lot.
Gemma
root/tags/BCI2000.v1.4/src/shared
However I can't find SockStream.
Could somebody tell me where I could find it?
Thanks a lot.
Gemma
jjbaker wrote:It's available as part of the BCI2000 source code release:
BCI2000 SVN Source Code\src\shared\utils
Gesanan wrote:Hi.
When I try to compile this piece of code I got these Compilation Errors:
E2209: Unable to open include file 'SockStream.h"
E2209: Unable to open include file 'SockStream.h"
I've looked for and I don't have these files on my PC.
What can I do?
Thank you very much.
Gesanan
mellinger wrote:John,
a program that redirects UDP input into serial output would be quite short, something along the following lines:
Regards,Code: Select all
#include "SockStream.h" #include "SerialStream.h" using namespace std; int main( int, char** ) { receiving_udpsocket s( "localhost:5000" ); sockstream input( s ); serialstream output( "COM1" ); string line; while( getline( input, line ) ) output << line << endl; return 0; }
Jürgen
-
Gesanan
- Posts: 5
- Joined: 20 Jan 2009, 11:13
Hi all.
Before sending and receiving data to and from the serial port I need to configurate it with the next setings: no parity, no flowcontrol, 8 data bits, 9600 bps.
I've read at "SerialStream.h" that "Configuration of the serial interface is independent of stream communication, and not provided here. Configuration must take place before opening the interface from the serialstream class.".
Could somebody guide me about how to do it?
Thanks a lot.
Gemma
Before sending and receiving data to and from the serial port I need to configurate it with the next setings: no parity, no flowcontrol, 8 data bits, 9600 bps.
I've read at "SerialStream.h" that "Configuration of the serial interface is independent of stream communication, and not provided here. Configuration must take place before opening the interface from the serialstream class.".
Could somebody guide me about how to do it?
Thanks a lot.
Gemma
-
mellinger
- Posts: 1341
- Joined: 12 Feb 2003, 11:06
Hi,
you will need to create a handle to the serial port by opening it, and then use the SetCommState/GetCommState functions from the Win32 API.
There is an example provided at:
http://msdn.microsoft.com/en-us/library ... S.85).aspx
HTH,
Juergen
you will need to create a handle to the serial port by opening it, and then use the SetCommState/GetCommState functions from the Win32 API.
There is an example provided at:
http://msdn.microsoft.com/en-us/library ... S.85).aspx
HTH,
Juergen
-
Gesanan
- Posts: 5
- Joined: 20 Jan 2009, 11:13
Hello everybody.mellinger wrote:John,
a program that redirects UDP input into serial output would be quite short, something along the following lines:
Regards,Code: Select all
#include "SockStream.h" #include "SerialStream.h" using namespace std; int main( int, char** ) { receiving_udpsocket s( "localhost:5000" ); sockstream input( s ); serialstream output( "COM1" ); string line; while( getline( input, line ) ) output << line << endl; return 0; }
Jürgen
If I want to read an integer form the socket the code would be like this??
Code: Select all
int i;
receiving_udpsocket s( host.c_str() );
sockstream udpIn( s );
udpIn >> i;
cout << "\nReceived int: " << i;
Gesanan
Who is online
Users browsing this forum: No registered users and 0 guests
