как можно реализовать параллельные потоки через Com-порт

Тема в разделе "MS Visual C++", создана пользователем pavlentiy, 2 апр 2008.

  1. pavlentiy

    pavlentiy Гость

    Суть проблемы состоит в том, что у меня есть программа, на нее приходят данные через ком порт с радио сканера. Считываются сканером подряд два штрих-кода, при считывании первого приходит сообщение на сканер что считан такойто штрихкод, потом считывается второй штрих-код и на сканер приходит сообщение что считан второй штрих-код, и в программе регестрируется продукт, как прошедший регистрацию, всего в работе используется 4-ре сканера, но ими можно работать только по отдельности.... Суть проблемы такова что мне надо сделать чтобы можно было работать одновременно хотябы 2-мя сразу... Сейчас когда начинаешь считывать одновременно двумя сканерами, то происходит путаница, когда я считываю первым сканером первый штрих-код, а вторым тоже первый штрих-код, то на втором пишется что неверный штрих-код, а если первым сканером считать первый штрих-код, а вторым второй то регистрируется продукция, а такого нельзя чтобы происходило...
    Подскажите пожалуйста как сделать пераллельные потоки или как реализовать чтобы велась выборка по номерам сканеров, т.е чтобы каждый сканер считывал одновременно по два штрих-кода и они не путались между собой...
     
  2. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Приемников сигнала со сканера сколько? Если нельзя аппаратно развести сканеры на разные порты,то сомневаюсь что можно что-то здесь сделать. Путается, я так понимаю, именно приемник, а не программа.
     
  3. pavlentiy

    pavlentiy Гость

    База накоторую приходят сообщения одна, но обработка ведется в самой программе...
     
  4. zubr

    zubr Гость

    Надо свой протокол обмена между программой и сканерами организовать, чтобы в заголовке пакетов был номер или какой другой индентификатор сканера.
     
  5. pavlentiy

    pavlentiy Гость

    У меня получается пакет идет 000-000000-N000000000000000000000
    первые три цифры идут номер сканера, потом шесть цифр время со сканера, и последние номер штрихкода...
     
  6. zubr

    zubr Гость

    Так в чем проблема? Номер сканера известен. В принятом пакете определяешь от кого он пришел и разветвляешь данные в программе.
     
  7. pavlentiy

    pavlentiy Гость

    вот как у меня реализовано чтение из порта:
    [codebox]UINT ThreadReadFromPort(LPVOID tfParam)
    {
    CWThrd232* pWnd = (CWThrd232*) tfParam;
    BYTE RxBuffer[NUM_BYTE_RX];
    BYTE OldRxBuffer[NUM_BYTE_RX];
    memset(OldRxBuffer,0,NUM_BYTE_RX);
    bool messageChanged = false;
    bool UndefMess=false;

    BYTE zeroBuffer[NUM_BYTE_RX];
    memset(zeroBuffer,0,NUM_BYTE_RX);


    while (pWnd->m_requestExit == false)
    {
    if (bConnect)
    {
    messageChanged = false;
    UndefMess=false;

    memset(RxBuffer,0,NUM_BYTE_RX);


    ReadBufferTimed(pWnd->m_pSerialPort, (char*) RxBuffer, NUM_BYTE_RX,500);

    if (memcmp(&RxBuffer, &zeroBuffer, NUM_BYTE_RX) !=0)
    {
    if (memcmp(&RxBuffer[0],&OldRxBuffer[0],15)!=0)
    {
    if ((RxBuffer[3]=='-')&&(RxBuffer[10]=='-')&&(RxBuffer[11]=='N'))
    {
    if((RxBuffer[22]==0x0d)&&(RxBuffer[23]==0x0a))
    {
    messageChanged = TRUE;
    pWnd->PostThreadMessage(ID_ZAVNOM_FROM_SKANER,(UINT)RxBuffer, 0);

    pWnd->m_thrdHdl->SuspendThread();
    }
    else if((RxBuffer[34]==0x0d)&&(RxBuffer[35]==0x0a))
    {
    messageChanged = TRUE;
    pWnd->PostThreadMessage(ID_TEHNOM_FROM_SKANER,(UINT)RxBuffer, 0);

    pWnd->m_thrdHdl->SuspendThread();
    }
    else
    UndefMess=true;


    }
    else if ((RxBuffer[ 3]=='-')&&(RxBuffer[10]=='-')&&(RxBuffer[11]=='A'))
    {
    if((RxBuffer[13]==0x0d)&&(RxBuffer[14]==0x0a))
    {
    if ((RxBuffer[12]==0x3c)||
    (RxBuffer[12]==0x3d)||
    (RxBuffer[12]==0x3e)
    )
    {
    messageChanged = TRUE;
    pWnd->PostThreadMessage(ID_BUTTON_FROM_SKANER ,(UINT)RxBuffer,0);
    pWnd->m_thrdHdl->SuspendThread();
    }
    }
    else
    UndefMess=true;

    }
    else
    UndefMess=true;

    if (true == UndefMess)
    {
    messageChanged = TRUE;
    pWnd->PostThreadMessage(ID_UNDEF_FROM_SKANER ,(UINT)RxBuffer,0);
    pWnd->m_thrdHdl->SuspendThread();
    }

    if(messageChanged)
    memcpy(OldRxBuffer,RxBuffer, NUM_BYTE_RX);
    }
    else
    {
    pWnd->PostThreadMessage(ID_REPEAT_FROM_SKANER ,(UINT)RxBuffer,0);
    pWnd->m_thrdHdl->SuspendThread();
    }

    }
    }
    Sleep(WAIT_BEFORE_SUSPEND);
    }


    TRACE(" Поток чтения порта завершен\n");

    pWnd->m_requestExitOk = true;
    return (0);
    }[/codebox]

    так данные я так понемаю разветвлять не в этом коде надо...
     
  8. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Цель твоей функции - получить пакет от сканера и переправить его окну. Соответственно:
    1. Если в результате работы нескольких сканеров окну приходят целостные отдельные пакеты с правильными данными, то здесь все в порядке, и логикой в программе ты в состоянии управлять сканерами.
    2. Если окно получает мусор, то в шлюзе пакеты от сканеров смешиваются, и надо изучать голые логи с ком порта чтобы понять причину.

    Твоя проблема из какой категории?
     
  9. pavlentiy

    pavlentiy Гость

    я вот создал пять одновременных потока, только проблемка есть, при завершении программы начали выскакивать ошибки, типа не могу закрыть окно, и почемуто приходят сообщения все на один сканер....
     
  10. pdp

    pdp Гость

    Я вижу решение Вашей проблемы следующим образом:
    1-если сканеры подключаются на СОМ, то каждый сканер необходимо подключать
    на один СОМ-порт (обычно на материнке 2 СОМ порта) Для доступа ко второму
    (если он не выведен) необходимо установить на системный блок панельку с
    раземом и подсоединить разем к матаринке.
    Програмируется 2 потока Каждый обслуживает свой СОМ.
    2-есть расширители СОМ портов (4,8,16)
    Програмируются аналогично
    3- вслучаи подключения н-сканеров к одному порту необходим преобразователь
    RS-485 со стороны компа(такие имеются) и со стороны сканера(если у него нет
    своего выхода RS-485)
    При этом сканер не должен самопроизвольно "выбрасывать информацию",
    а отдавать только по запросу.
     
  11. pavlentiy

    pavlentiy Гость

    больше склоняюсь к этой...

    в том то и дело что к компу у меня подключены не сканера, а база, а сканера привязываются к базе, к базе провод подключается через RS232, а к компу провод подключается через КОМ-порт...
     
  12. pavlentiy

    pavlentiy Гость

    подскажите пожалуйста, вот таким способом я создал 5 потоков, когда компилишь прогу и запускаешь в ней создается пять потоков:
    [codebox]BOOL CThreadsManager::BeginThreads()
    {
    for(int i=0; i<THRD_NUM-1; i++)
    {
    m_configurationThread = AfxBeginThread(prtWinThrd232, THREAD_PRIORITY_NORMAL,
    0, NORMAL_PRIORITY_CLASS);
    if(!m_configurationThread)
    return FALSE;

    m_status = THRD_ONLINE;
    }

    m_configurationThread[THRD_232] = AfxBeginThread( prtWinThrd232, THREAD_PRIORITY_NORMAL,
    0, NORMAL_PRIORITY_CLASS);

    m_status[THRD_232] = THRD_ONLINE;

    if(!m_configurationThread[THRD_NUM])
    return FALSE;

    return TRUE;
    }[/codebox]

    но при этом у меня они при завершении программы не закрываются... вот два последовательных кода которые выполняются друг за другом:
    [codebox]afx_msg LRESULT CWThrd232::OnEndThread(WPARAM wparam, LPARAM lparam)
    {
    CWnd* pWin = (CWnd*) wparam;
    int repeat = 0;

    bConnect = false;

    delete (m_pZavManager);
    delete (m_pTehManager);

    m_requestExitOk = false;
    m_requestExit = true;
    if (m_requestExitOk == false)
    {
    while ((m_requestExitOk == false)&&(repeat < 20))
    {
    Sleep(100);
    repeat++;
    }
    }


    if(m_pSerialPort != NULL)
    PortClose(m_pSerialPort);



    m_pSerialPort = NULL;
    SystemMess = "ЗАВЕРШЕНИЕ РАБОТЫ. Порт закрыт.";
    tab2->SendMessage(ID_MESSAGE_LIST,SYS_MESS, SYS_MESS);


    pWin->PostMessage(ID_END_THREAD,lparam,0);
    ::postQuitMessage(0);
    return 0;
    }[/codebox]

    Код (Text):
    afx_msg LRESULT CThreadsManager::OnSetEndThread(WPARAM wparam, LPARAM lparam)
    {
    if(wparam < THRD_NUM)
    m_status[wparam] = THRD_SHUTDOWN;
    return TRUE;
    }
     
  13. pavlentiy

    pavlentiy Гость

    с последней из проблем я уже разобрался, теперь у меня открываются 5 параллельных потока, и нормально закрываются при этом никаких критических ошибок больше не выдается и программа корректно работает, осталось только разобраться чтобы сканера работали каждый под свой поток......
     
Загрузка...

Поделиться этой страницей