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

  • Автор темы pavlentiy
  • Дата начала
P

pavlentiy

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

grigsoft

Well-known member
15.11.2005
735
0
#2
Приемников сигнала со сканера сколько? Если нельзя аппаратно развести сканеры на разные порты,то сомневаюсь что можно что-то здесь сделать. Путается, я так понимаю, именно приемник, а не программа.
 
P

pavlentiy

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

zubr

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

pavlentiy

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

zubr

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

pavlentiy

#7
вот как у меня реализовано чтение из порта:
[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]

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

grigsoft

Well-known member
15.11.2005
735
0
#8
Цель твоей функции - получить пакет от сканера и переправить его окну. Соответственно:
1. Если в результате работы нескольких сканеров окну приходят целостные отдельные пакеты с правильными данными, то здесь все в порядке, и логикой в программе ты в состоянии управлять сканерами.
2. Если окно получает мусор, то в шлюзе пакеты от сканеров смешиваются, и надо изучать голые логи с ком порта чтобы понять причину.

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

pavlentiy

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

pavlentiy

#11
1. Если в результате работы нескольких сканеров окну приходят целостные отдельные пакеты с правильными данными, то здесь все в порядке, и логикой в программе ты в состоянии управлять сканерами.
больше склоняюсь к этой...

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

pavlentiy

#12
подскажите пожалуйста, вот таким способом я создал 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]

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

pavlentiy

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