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.