PDA

Просмотр полной версии : Опрос ТРМ138 из потока



stolzzz
16.05.2013, 10:42
Опрашиваю показания ТРМ138 (пишу на MS Visual C++ 2010, express) c использованием owen_io.DLL:



/*Открываем порт OpenPort();*/

for (int i=0; i<=6; ++i) {
res:=ReadIEEE32(16+i,0,'rEAd',val,tm,-1);
if(res>=0) {Ttek[i]:=val;}

}

Данные получаю корректные, но при опросе 8 каналов программа начинает подтормаживать.

Сделал опрос в таймере (интервал 2 секунда) отдельным потоком (System::Timers::Timer), открываю порт в том же потоке.

При опросе 8 каналов программа НЕподтормаживает. Данные также получаю корректные



OpenPort(); /*Открываем порт каждый такт*/
for (int i=0; i<=6; ++i) {
res:=ReadIEEE32(16+i,0,'rEAd',val,tm,-1);
if(res>=0) {Ttek[i]:=val;}

}
ClosePort();


Но если делаю интервал 1 секунда и открываю порт однократно...


static j=0;
if (j==0) {
OpenPort(); /*Открываем порт однократно*/
j=1;}

for (int i=0; i<=6; ++i) {
res:=ReadIEEE32(16+i,0,'rEAd',val,tm,-1);
ReadStoredDotS(i+16,0,"C.SP",ust,-1);
ReadStoredDotS(i+16,0,"HYSt",gis,-1);
if(res>=0) {Ttek[i]:=val;Tust=ust;Tgis=gis}

}

То через каждый такт таймера, появляется ошибка res=-2 то в 3 каналах, то в четырех


Т.е. запустили таймер
Однократно открыл порт
-> получили корректные данные
-> res=-2 (канал 4,5,6,7)
-> получили корректные данные
-> res=-2 (канал 1,2,3)

И так далее

Если интервал таймера установить 2 секунды, и каждый раз открывать закрывать порт, то данные корректно получаю.
Но у меня 6 приборов ТРМ138 по 7 каналов у каждого
Это получается что корректно считывание (без res=-2) будет только раз 12-15 секунд. Но это очень большой для меня интервал.
Или я что-то не так делаю?

Дмитрий Егоренков
16.05.2013, 15:25
Программа не успевает опросить все каналы за интервал таймера (1 секунду). В результате очередной обработчик таймера вызывается из другого потока, в котором порт, очевидно, никто не открывал.

Отключите таймер при входе в обработчик, и будет вам счастье.

stolzzz
16.05.2013, 19:30
Спасибо, Дмитрий за ответ. Но...


Программа не успевает опросить все каналы за интервал таймера (1 секунду). В результате очередной обработчик таймера вызывается из другого потока, в котором порт, очевидно, никто не открывал.

Да Вы окзались правы,прочитал про System.Timers::Timer в http://msdn.microsoft.com/, так вот там написано "Если обработка события Elapsed длится дольше, чем Interval, событие может возникнуть снова в другом потоке ThreadPool"


Отключите таймер при входе в обработчик, и будет вам счастье.

А как тогда без таймера ЦИКЛИЧЕСКИ опрашивать прибор? Ведь при в ходе в обработчик он отработается лишь ОДИН раз. А мне нужно постоянно осуществлять мониторинг параметров.

Дмитрий Егоренков
17.05.2013, 11:51
ну, включите его обратно при выходе из обработчика.



_timer.Enabled = false;

// опрашиваем приборы

_timer.Enabled = true;