Quantcast
Channel: CodeGuru Forums - Visual C++ Programming
Viewing all articles
Browse latest Browse all 3029

Trouble with timer

$
0
0
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.

Viewing all articles
Browse latest Browse all 3029

Latest Images

Trending Articles



Latest Images