-
January 17th, 2013, 07:29 AM
#1
Trouble with timer
Hi everybody !
The purpose is to manage serial communication between a pedal and the computer.
I begin to search for the serial port on which the pedal is connected :
- I request the sotware version of the pedal
- I set up a timer of 20 ms to escape if no reply
- I set up the mode
- I set up again the timer of 20 ms
- If OK I set up a new timer of 200 ms to request the pedal state
This runs fine.
Here is the main :
Code:
int _tmain(int argc, _TCHAR* argv[])
{
pedal My_Pedal;
My_Pedal.enumerate_pedal();
if (My_Pedal.search_pedal_port())
My_Pedal.activate_pedal();
std::cin >> key;
My_Pedal.deactivate_pedal();
return 0;
}
At the present time the method enumerate_pedal() sets up a new timer of 2s just to display a warning message.
Here is the header of the pedal class :
Code:
#pragma once
#include <string>
#include "toolbox.h"
#include "template_timer.h"
#include "const_pedal.h"
#include "tserial_event.h"
#include "enumser.h"
class pedal
{
public:
void enumerate_pedal(void);
void activate_pedal(void);
bool search_pedal_port(void);
void deactivate_pedal(void);
static char* reply_iss_version;
static char* reply_serial_number;
static char* reply_configuration;
static char* reply_io_state;
// state comes with UP or DOWN
static bool pedal_state;
private:
void wait_for_reply(void);
void OnTimedEvent_PedalReply(void);
void OnTimedEvent_PedalRequest(void);
void OnTimedEvent_PedalEnumeration(void);
// the callback function has to be a static one if any class member !
static void SerialEventManager(uint32 object, uint32 event);
static void OnDataArrival(int size, char *buffer);
static void todo_on_pedalchange(void);
void request_iss_version(void);
void request_pedal_state(void);
void request_serial_number(void);
void configure_io_mode(void);
TTimer<pedal> timer_pedal_enumeration;
TTimer<pedal> timer_pedal_request;
TTimer<pedal> timer_pedal_reply;
static char* serial_number;
static std::string firmware_revision_number;
// status comes with OK or not
static bool pedal_status;
static bool iss_version_received;
static bool io_mode_received;
static bool pedal_state_received;
static bool pedal_state_mem;
static bool first_pedalrequest;
bool pedalreply_timeelapsed;
};
And the cpp of the class pedal :
Code:
#include "stdafx.h"
#include "pedal.h"
#include <sstream>
tserial_event* com;
int error;
CSimpleArray<UINT> ports;
CSimpleArray<CString> friendlyNames;
CSimpleArray<CString> sPorts;
int port_number;
char* pedalport = PEDALPORT_UNKNOWN;
// **********************************************************
// * todo_on_pedalchange *
// * *
// * put here the stuff you have to do when a state change *
// * occurs *
// **********************************************************
void pedal::todo_on_pedalchange(void)
{
if (pedal_state)
printf("Pedal ACTIVATED \n");
else
printf("Pedal UNACTIVATED \n");
}
// **********************************************************
// * OnDataArrival *
// **********************************************************
void pedal::OnDataArrival(int size, char *buffer)
{
std::ostringstream oss;
std::string sbuffer;
int i_num;
if ((size>0) && (buffer!=0))
{
buffer[size] = 0;
sbuffer = buffer;
#ifdef DISPLAY_ONDATA_ARRIVAL
printf("OnDataArrival: %s ",buffer);
printf("\n");
#endif
switch (size)
{
case 1 : reply_io_state = buffer;
// pedal is linked to the first IO input
i_num = int(buffer[0]) & 1;
pedal_state = (i_num == 0);
if (first_pedalrequest)
{
pedal_state_mem = pedal_state;
first_pedalrequest = false;
}
else
{
if (pedal_state != pedal_state_mem)
{
pedal_state_mem = pedal_state;
todo_on_pedalchange();
}
}
pedal_state_received = true;
break;
case 2 : reply_configuration = buffer;
// converting to ascii
i_num = int(buffer[0]);
if (i_num < 0)
i_num = i_num + 256;
pedal_status = (i_num == 0xff);
io_mode_received = true;
break;
case 3 : reply_iss_version = buffer;
i_num = buffer[1];
oss << i_num;
firmware_revision_number = oss.str();
iss_version_received = true;
break;
case 8 : reply_serial_number = buffer;
serial_number = reply_serial_number;
break;
}
}
}
// **********************************************************
// * SerialEventManager *
// **********************************************************
void pedal::SerialEventManager(uint32 object, uint32 event)
{
char *buffer;
int size;
tserial_event *com;
com = (tserial_event *) object;
if (com!=0)
{
switch(event)
{
case SERIAL_CONNECTED :
#ifdef DISPLAY_CONNECTED
printf("Connected ! \n");
#endif
break;
case SERIAL_DISCONNECTED :
#ifdef DISPLAY_DISCONNECTED
printf("Disonnected ! \n");
#endif
break;
case SERIAL_DATA_SENT :
#ifdef DISPLAY_DATA_SENT
printf("Data sent ! \n");
#endif
break;
case SERIAL_RING :
#ifdef DISPLAY_DRING
printf("DRING ! \n");
#endif
break;
case SERIAL_CD_ON :
#ifdef DISPLAY_CARRIER_DETECTED
printf("Carrier Detected ! \n");
#endif
break;
case SERIAL_CD_OFF :
#ifdef DISPLAY_NO_MORE_CARRIER
printf("No more carrier ! \n");
#endif
break;
case SERIAL_DATA_ARRIVAL :
size = com->getDataInSize();
buffer = com->getDataInBuffer();
OnDataArrival(size, buffer);
com->dataHasBeenRead();
break;
}
}
}
// **********************************************************
// * enumerate_serial_ports *
// **********************************************************
bool enumerate_serial_ports(void)
{
//Initialize COM (Required by CEnumerateSerial::UsingWMI)
CoInitialize(NULL);
//Initialize COM security (Required by CEnumerateSerial::UsingWMI)
HRESULT hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
if (FAILED(hr))
{
printf("Failed to initialize COM security, Error:%x\n", hr);
CoUninitialize();
return false;
}
#if defined CENUMERATESERIAL_USE_STL
std::vector<UINT> ports;
#if defined _UNICODE
std::vector<std::wstring> friendlyNames;
std::vector<std::wstring> sPorts;
#else
std::vector<std::string> friendlyNames;
std::vector<std::string> sPorts;
#endif
size_t i;
#elif defined _AFX
CUIntArray ports;
CStringArray friendlyNames;
CStringArray sPorts;
INT_PTR i;
#else
/*
CSimpleArray<UINT> ports;
CSimpleArray<CString> friendlyNames;
CSimpleArray<CString> sPorts;
int i;
*/
#endif
///////////////////////// Serial Ports Enumeration Methods ////////////////////////////////////////////
// CREATEFILE_SERIAL_ENUMERATION_METHOD
#ifdef CREATEFILE_SERIAL_ENUMERATION_METHOD
printf(CREATEFILE);
if (CEnumerateSerial::UsingCreateFile(ports))
goto Co_Uninitialize;
else
{
printf(CREATEFILE_FAILURE, GetLastError());
return false;
}
#endif
// QUERY_DOSDEVICE_SERIAL_ENUMERATION_METHOD
#ifdef QUERY_DOSDEVICE_SERIAL_ENUMERATION_METHOD
printf(QUERY_DOSDEVICE);
if (CEnumerateSerial::UsingQueryDosDevice(ports))
goto Co_Uninitialize;
else
{
printf(QUERY_DOSDEVICE_FAILURE, GetLastError());
return false;
}
#endif
// GET_DEDAULT_COMMCONFIG_SERIAL_ENUYMERATION_METHOD
#ifdef GET_DEDAULT_COMMCONFIG_SERIAL_ENUYMERATION_METHOD
printf(GET_DEFAULT_COMMCONFIG);
if (CEnumerateSerial::UsingGetDefaultCommConfig(ports))
goto Co_Uninitialize;
else
{
printf(GET_DEFAULT_COMMCONFIG_FAILURE, GetLastError());
return false;
}
#endif
// GUID_DEVINTERFACE_SERIAL_ENUMERATION_METHOD
// buggy on Windows 7 Professional
#ifdef GUID_DEVINTERFACE_SERIAL_ENUMERATION_METHOD
// Issue while testing on Windows 7 Professional
printf(GUID_DEVINTERFACE);
if (CEnumerateSerial::UsingSetupAPI1(ports, friendlyNames))
goto Co_Uninitialize;
else
{
printf(GUID_DEVINTERFACE_FAILURE, GetLastError());
return false;
}
#endif
// PORTS_DEVICE_INFORMATION_SERIAL_ENUMERATION_METHOD
#ifdef PORTS_DEVICE_INFORMATION_SERIAL_ENUMERATION_METHOD
printf(PORT_DEVICE_INFORMATION);
if (CEnumerateSerial::UsingSetupAPI2(ports, friendlyNames))
goto Co_Uninitialize;
else
{
printf(PORT_DEVICE_INFORMATION_FAILURE, GetLastError());
return false;
}
#endif
// ENUMPORTS_SERIAL_ENUMERATION_METHOD
// buggy on Windows 7 Professional
#ifdef ENUMPORTS_SERIAL_ENUMERATION_METHOD
printf(ENUMPORTS);
if (CEnumerateSerial::UsingEnumPorts(ports))
goto Co_Uninitialize;
else
{
printf(ENUMPORTS_FAILURE, GetLastError());
return false;
}
#endif
// WMI_SERIAL_ENUMERATION_METHOD
#ifdef WMI_SERIAL_ENUMERATION_METHOD
printf(WMI);
if (CEnumerateSerial::UsingWMI(ports, friendlyNames))
goto Co_Uninitialize;
else
{
printf(WMI_FAILURE, GetLastError());
return false;
}
#endif
// COM08_SERIAL_ENUMERATION_METHOD
// buggy on Windows 7 Professional
#ifdef COM08_SERIAL_ENUMERATION_METHOD
printf(COM08);
if (CEnumerateSerial::UsingComDB(ports))
goto Co_Uninitialize;
else
{
printf(COM08_FAILURE), GetLastError();
return false;
}
#endif
// REGISTRY_SERIAL_ENUMERATION_METHOD
#ifdef REGISTRY_SERIAL_ENUMERATION_METHOD
printf(REGISTRY);
if (CEnumerateSerial::UsingRegistry(sPorts))
goto Co_Uninitialize;
else
{
printf(REGISTRY_FAILURE, GetLastError());
return false;
}
#endif
Co_Uninitialize:
//close down COM
CoUninitialize();
return true;
}
// **********************************************************
// * OnTimedEvent_PedalEnumeration *
// **********************************************************
void pedal::OnTimedEvent_PedalEnumeration(void)
{
printf("Attempting pedal enumeration ...\n");
}
// **********************************************************
// * OnTimedEvent_PedalRequest *
// **********************************************************
void pedal::OnTimedEvent_PedalRequest(void)
{
#ifdef DISPLAY_READING_PEDAL_STATE
printf("Reading pedal state ...\n");
#endif
this->request_pedal_state();
}
// **********************************************************
// * OnTimedEvent_PedalReply *
// **********************************************************
void pedal::OnTimedEvent_PedalReply(void)
{
printf("Waiting for pedal reply ... \n");
pedalreply_timeelapsed = true;
}
// **********************************************************
// * enumerate_pedal *
// **********************************************************
void pedal::enumerate_pedal(void)
{
timer_pedal_enumeration.SetTimedEvent(this,&pedal::OnTimedEvent_PedalEnumeration);
timer_pedal_enumeration.Start(PEDAL_ENUMERATION_PERIOD);
}
// **********************************************************
// * activate_pedal *
// **********************************************************
void pedal::activate_pedal(void)
{
timer_pedal_request.SetTimedEvent(this,&pedal::OnTimedEvent_PedalRequest);
timer_pedal_request.Start(PEDAL_REQUEST_PERIOD);
}
// **********************************************************
// * wait_for_reply *
// **********************************************************
void pedal::wait_for_reply(void)
{
this->pedalreply_timeelapsed = false;
timer_pedal_reply.SetTimedEvent(this,&pedal::OnTimedEvent_PedalReply);
timer_pedal_reply.Start(PEDAL_REPLY_PERIOD,NOT_IMMEDIATELY,ONCE);
}
// **********************************************************
// * request_iss_version *
// **********************************************************
void pedal::request_iss_version(void)
{
iss_version_received = false;
com->sendData(ISS_VERSION_REQUEST,2);
com->setRxSize(3); // waiting for 3 bytes
}
// **********************************************************
// * request_serial_number *
// **********************************************************
void pedal::request_serial_number(void)
{
com->sendData(SERIAL_NUMBER_REQUEST,2);
com->setRxSize(8); // waiting for 8 bytes
}
// **********************************************************
// * request_pedal_state *
// **********************************************************
void pedal::request_pedal_state(void)
{
pedal_state_received = false;
com->sendData(PEDAL_STATE_REQUEST,1);
com->setRxSize(1); // waiting for 1 byte
}
// **********************************************************
// * configure_io_mode *
// **********************************************************
void pedal::configure_io_mode(void)
{
pedal_status = PEDAL_NOK;
com->sendData(CONFIGURE_IO_MODE,3);
com->setRxSize(2); // waiting for 2 bytes
}
// **********************************************************
// * search_pedal_port *
// * *
// * enumerate the serial ports on the tablet *
// * search for the one connected to the pedal *
// **********************************************************
bool pedal::search_pedal_port(void)
{
std::string sport_number;
std::string sport_name;
char* cport_name;
int port_number_max;
if (enumerate_serial_ports())
{
#ifdef CENUMERATESERIAL_USE_STL
port_number_max = ports.size();
#else
port_number_max = ports.GetSize();
#endif
port_number = 0;
while ((pedalport == PEDALPORT_UNKNOWN)&&(port_number != port_number_max))
{
sport_number = to_string(ports[port_number]);
sport_name = "COM" + sport_number;
cport_name = const_cast<char*>(sport_name.c_str());
com = new tserial_event();
if (com!=0)
{
com->setManager(this->SerialEventManager);
error = com->connect(cport_name, PEDAL_PORT_SPEED, SERIAL_PARITY_NONE, PEDAL_PORT_BITS, PEDAL_PORT_MODEM_EVENT);
if (!error)
{
this->request_iss_version();
this->wait_for_reply();
while ((!iss_version_received)&&(!this->pedalreply_timeelapsed));
if (iss_version_received)
{
pedalport = cport_name;
this->configure_io_mode();
this->wait_for_reply();
while ((!io_mode_received)&&(!this->pedalreply_timeelapsed));
if (io_mode_received)
{
this->request_pedal_state();
this->wait_for_reply();
while ((!pedal_state_received)&&(!this->pedalreply_timeelapsed));
return (pedal_state_received);
}
}
else
{
com->disconnect();
port_number++;
}
}
}
}
return PEDAL_UNDETECTED;
}
}
// **********************************************************
// * deactivate_pedal *
// **********************************************************
void pedal::deactivate_pedal(void)
{
timer_pedal_request.Stop();
timer_pedal_reply.Stop();
if (com != 0)
com->disconnect();
}
The purpose now is to make it running after the pedal being disconnected and connected again.
I thought to move :
Code:
if (My_Pedal.search_pedal_port())
My_Pedal.activate_pedal();
into the method enumerate_pedal. When done the timer set by wait_for_reply() doesn't seem to run again and I never go out of the first while loop of the method search_pedal_port().
Note : on my PC the pedal is connected onto the second serial port, not the first one.
So I don't understand the trouble.
Many thanks.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|