Hi Juergen,
Thank you very much for your detailed response. It really helped me to get going.
I tried to implement the code that you presented and even though I am sure that my code has a lot of errors, visual studio is not reporting them to me so I managed to build the exe file.
Unfortunately I still don't understand several details.
Since we will not have amplifier ready until the end of the semester, I will not be able to check if my code is working, so I will try to attach output of signal generator (sine wave) to serial port of my computer and see if I am getting any response in BCI2000.
But now I am trying to at least get the software to go through the Preflight phase and it is not working because I don't know what exactly is "example command GETVERSION" from the code that you gave me:
outStream << "GETVERSION\n" << flush;
(by the way, is senddata from the line: mPort << "SENDDATA\n" << flush; also example command or I can leave it like that?)
this is what I have done so far, and it gives me the error:
Code: Select all
#include "PCHIncludes.h"
#pragma hdrstop
#include<iostream>
#include "PolyBuffADC.h"
#include "BCIError.h"
#include "SerialStream.h"
#include "ThreadUtils.h" // for SleepFor()
using namespace std;
RegisterFilter( PolyBuffADC, 1 );
PolyBuffADC::PolyBuffADC():
mSourceCh(0),
mSampleBlockSize(0),
mSamplingRate(0)
{
BEGIN_PARAMETER_DEFINITIONS
"Source:Signal%20Properties int SourceCh= 1 "
"// number of digitized and stored channels",
"Source:Signal%20Properties int SampleBlockSize= 32 "
"// number of samples transmitted at a time",
"Source:Signal%20Properties float SamplingRate= 512Hz "
"// sample rate",
"Source string COMport= COM3"
"// COMport for PolyAmp",
END_PARAMETER_DEFINITIONS
BEGIN_STATE_DEFINITIONS
"Running 1 0 0 0"
END_STATE_DEFINITIONS
}
PolyBuffADC::~PolyBuffADC()
{
OnHalt();
}
void
PolyBuffADC::OnHalt()
{
}
void
PolyBuffADC::OnPreflight( SignalProperties& Output ) const
{
// The user has pressed "Set Config" and we need to sanity-check everything.
// For example, check that all necessary parameters and states are accessible:
/*Local Variables: */
int sourceCh = Parameter( "SourceCh" ),
sampleBlockSize = Parameter( "SampleBlockSize" ),
samplingRate = static_cast<int>( Parameter( "SamplingRate" ).InHertz() ); //not sure bout this one
// Check that the user is asking for one channel
//after, we are going to change it to 8 channels.
if( sourceCh != 1 )
bcierr << "PolyBuff only has one electrode for now. Set SourceCh=1." << endl;
if( samplingRate != 512 )
bcierr << "PolyBuff has a sampling rate of 512Hz. Set SamplingRate to 512." << endl;
if( Parameter( "SampleBlockSize" ) >64 )
bcierr << "Sample Block Size shouldnt be bigger than 64" << endl;
string COMportParam = Parameter( "COMport" );
if( COMportParam.empty() )
{
bcierr << "No COM port specified for device" << endl;
return;
}
serialstream port;
if( !ConnectToAD( port ) )
bcierr << "Cannot connect to AD on port " << Parameter( "COMport" ) << endl;
int numberOfChannels = Parameter( "SourceCh" ); //same as sourceCh from above
int samplesPerBlock = Parameter( "SampleBlockSize" ); //same as sampleBlockSize from above
SignalType sigType = SignalType::float32; // could also parameterize this
Output = SignalProperties( numberOfChannels, samplesPerBlock, sigType );
}
bool PolyBuffADC::ConnectToAD(serialstream& outStream) const{
outStream.clear();
outStream.close();
string comport = Parameter( "COMport" );
COMMCONFIG config = { sizeof( COMMCONFIG ), 1 };
config.dwProviderSubType = PST_RS232;
::BuildCommDCB( "baud=1200 parity=N data=8 stop=1", &config.dcb );
bool success = ::SetDefaultCommConfig( comport.c_str(), &config, sizeof( config ) );
if( success )
{
bcierr << "if 1" << endl; //added if for debuging
outStream.open( comport.c_str() );
success = outStream.is_open();
}
string response;
if( success )
{
bcierr << "if 2" << endl; //added if for debuging
outStream << "GETVERSION\n" << flush;
success = getline( outStream, response, '\n' );
}
if( success )
bcierr << "if 3" << endl; //added if for debuging, never enters here
bcidbg << "Connected to AD, version is " << response << endl;
return success;
}
void
PolyBuffADC::OnInitialize( const SignalProperties& Output )
{
mSourceCh = Parameter( "SourceCh" );
mSampleBlockSize = Parameter( "SampleBlockSize" );
mSamplingRate = Parameter( "SamplingRate" );
serialstream mPort;
ConnectToAD( mPort );
mLastTime = PrecisionTime::Now();
}
void
PolyBuffADC::OnStartAcquisition()
{
mPort << "SENDDATA\n" << flush;
}
void
PolyBuffADC::DoAcquire( GenericSignal& Output )
{
double value;
for( int ch = 0; ch < Output.Channels(); ++ch )
for( int sample = 0; sample < Output.Elements(); ++sample )
{
mPort >> ws >> value;
Output( ch, sample ) = value;
}
/*given by default: */
// For now, we output flat lines:
for( int ch = 0; ch < Output.Channels(); ch++ )
for( int el = 0; el < Output.Elements(); el++ )
Output( ch, el ) = 0.0f;
// Here is a wait loop to ensure that we do not deliver the signal faster than real-time
// (In your final implementation, you should remove this: the hardware will play this role then.)
while( PrecisionTime::UnsignedDiff( PrecisionTime::Now(), mLastTime ) < mMsecPerBlock ) ThreadUtils::SleepFor(1);
mLastTime = PrecisionTime::Now();
}
void
PolyBuffADC::StartRun()
{
// The user has just pressed "Start" (or "Resume")
bciout << "Hello World!" << endl;
mLastTime = PrecisionTime::Now();
}
void
PolyBuffADC::StopRun()
{
// The Running state has been set to 0, either because the user has pressed "Suspend",
// because the run has reached its natural end.
bciout << "Goodbye World." << endl;
}
void
PolyBuffADC::OnStopAcquisition()
{
// This method will always be called before OnHalt is called.
}
and this is what I get in the operator log:
2012-10-04T01:59:33 - BCI2000 Started
2012-10-04T01:59:35 - Waiting for configuration ...
2012-10-04T01:59:41 - Waiting for configuration ...
2012-10-04T01:59:43 - Waiting for configuration ...
2012-10-04T02:00:37 - Operator set configuration
2012-10-04T02:00:37 - DataIOFilter::Preflight: PolyBuffADC::Preflight: if 1.
2012-10-04T02:00:41 - DataIOFilter::Preflight: PolyBuffADC::Preflight: if 2.
2012-10-04T02:00:42 - DataIOFilter::Preflight: PolyBuffADC::Preflight: Cannot connect to AD on port COM3.
if 1 and if 2 are lines which I added to ConnectToAD(serialstream& outStream) so that I could localize the error(the line
outStream << "GETVERSION\n" << flush; causes the error since I dont understand what it does.)
So, Could you help me and tell me or maybe give me a hint about what I need to change so that I could read the data from my one channel signal generator connected to COM port?
Sorry for the long and maybe a bit messy post.
Thank you very much once more!
Best,
Andrej