|
MaxiMuz79
Участник
Сказали спасибо: +0/-0
Offline
Сообщений: 32
|
|
Отстает синхронизация в Timer
« : 24 Январь 2013, 16:18:33 »
|
|
Нужно с определенной частотой выводить график. Используя компонент Timer по табличным точкам строю график:
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
static int i;
static unsigned char dirCount=0;
NumWByte=1;
buf_out=tablsin[i];
//WriteFile(port,&buf_out,NumWByte,&WByteCount,&ovrlp);
VxADC=(unsigned int) tablsin[i];
MeasValue=(float)(MaxValue*VxADC)/MaxHC;
Series2->AddXY(Ti,MeasValue,"",clRed);
if (i==127)
{ dirCount=1;
}
else if (i==0)
{ dirCount=0;
}
if (dirCount==0) i++; else i--;
Ti++;
if (Ti>200)
{ Ti=0;
Series2->Clear();
}
}
Ставил различные периоды вызова , и только от 100 мсек частота вызовов совпадает с заданной. При меньшем периоде наблюдается сильное отставание.
Как организовать синхронный вызов событий ?
|
|
|
|
|
|
POV
Участник
Сказали спасибо: +107/-7
Offline
Сообщений: 640
|
|
Re: Отстает синхронизация в Timer
« Ответ #1 : 24 Январь 2013, 19:06:02 »
|
|
Имеется в виду - косяки при меньшем периоде?
|
|
|
|
|
|
Leex
Участник
Сказали спасибо: +132/-1
Offline
Сообщений: 577
|
|
Re: Отстает синхронизация в Timer
« Ответ #2 : 24 Январь 2013, 20:30:18 »
|
|
TTimer по своей природе очень не точен, но по опыту могу сказать что эта неточность сильно проявляется при интервалах меньше 50 мс. Здесь судя по всему сам обработчик таймера достаточно тяжело дается процессору. Обрати внимание как загружается процессор (ядро) если задать скажем 50 мс.
|
|
|
|
|
|
S0mbre
Глобальный модератор
Сказали спасибо: +1113/-22
Offline
Сообщений: 2132
S0mbre
|
|
Re: Отстает синхронизация в Timer
« Ответ #3 : 25 Январь 2013, 07:20:23 »
|
|
Для большинства задач, где требуется точность и хороший отклик, лучше использовать отдельные потоки. Например, метод Execute VCL потока может быть представлен в виде цикла с вызовом паузы в конце:
void __fastcall TMyThread::Execute(void) { while(!Terminated && !Suspended) { // делаем что-то (вывод графика и т.д.)... Sleep(100); // пауза } }
|
|
|
|
|
|
MaxiMuz79
Участник
Сказали спасибо: +0/-0
Offline
Сообщений: 32
|
|
Re: Отстает синхронизация в Timer
« Ответ #4 : 25 Январь 2013, 13:45:30 »
|
|
Обрати внимание как загружается процессор (ядро) если задать скажем 50 мс.
Проц. практически работает в холостую макс. 7%
|
|
|
|
|
|
MaxiMuz79
Участник
Сказали спасибо: +0/-0
Offline
Сообщений: 32
|
|
Re: Отстает синхронизация в Timer
« Ответ #5 : 25 Январь 2013, 13:48:06 »
|
|
Например, метод Execute VCL потока может быть представлен в виде цикла с вызовом паузы в конце:
я о этом методе незнал , где можно по подробнее почитать о нем ?
Вообще есть еще какие нибудь методы синхронного выполнения событий ?
|
|
|
|
|
|
POV
Участник
Сказали спасибо: +107/-7
Offline
Сообщений: 640
|
|
Re: Отстает синхронизация в Timer
« Ответ #6 : 25 Январь 2013, 13:51:10 »
|
|
Например, метод Execute VCL потока может быть представлен в виде цикла с вызовом паузы в конце:
я о этом методе незнал , где можно по подробнее почитать о нем ?
Вообще есть еще какие нибудь методы синхронного выполнения событий ?
Ты бы про задачу сказал подробнее. Потому как изучать начинающему глубинные возможности винды грустно. Почти всё можно решить силами билдера никуда не углубляясь. А самореализацией уж можно заняться потом, когда понимаешь что делаешь.
|
|
|
|
|
|
POV
Участник
Сказали спасибо: +107/-7
Offline
Сообщений: 640
|
|
Re: Отстает синхронизация в Timer
« Ответ #7 : 25 Январь 2013, 13:52:21 »
|
|
Если Execute интересует, то визард билдера создаст тебе юнит класса потока. Включаешь в проект, создаешь экземпляр этого класса и запускаешь поток. Он себе крутится и делает то, что ты в нем написал.
|
|
|
|
|
|
MaxiMuz79
Участник
Сказали спасибо: +0/-0
Offline
Сообщений: 32
|
|
Re: Отстает синхронизация в Timer
« Ответ #8 : 25 Январь 2013, 14:06:44 »
|
|
Например, метод Execute VCL потока может быть представлен в виде цикла с вызовом паузы в конце:
я о этом методе незнал , где можно по подробнее почитать о нем ?
Вообще есть еще какие нибудь методы синхронного выполнения событий ?
Ты бы про задачу сказал подробнее.
требуется с определенной периодичностью (1...100 мс) максимально точно во времяни выполнять какую либо операцию : выводить в порт команду и т.д. Использовал компонент Timer оказывается его interval ни фига не точен.
|
|
|
|
|
|
POV
Участник
Сказали спасибо: +107/-7
Offline
Сообщений: 640
|
|
Re: Отстает синхронизация в Timer
« Ответ #9 : 25 Январь 2013, 14:59:44 »
|
|
1...100 мс - малореально. Я находил исходники "высокоточных" таймеров.. но гложет меня сомнение. Как вариант могу предложить тот же поток, но в нем не Sleep(), а GetTikCount() - счетчик тактовых импульсов процессора.
что-то типа:
... Execute() { UINT last_tik = GetTikCount(); UINT current_tik; while(1) { currentk_tik = GetTikCount(); if (current_tik-last_tik > interval) { last_tik = current_tik; ... // тут вызываем обработчик события } else last_tik = current_tik; } }
interval - это твои миллисекунды, умноженные на какой-то коэффициент, зависящий от тактовой
|
|
| « Последнее редактирование: 25 Январь 2013, 18:09:21 от POV » |
Записан |
|
|
|
|
MaxiMuz79
Участник
Сказали спасибо: +0/-0
Offline
Сообщений: 32
|
|
Re: Отстает синхронизация в Timer
« Ответ #10 : 25 Январь 2013, 15:26:03 »
|
|
interval - это твои миллисекунды, умноженные на какой-то коэффициент, зависящий от тактовой
да, похоже это условные миллисекунды зависящие от конкретной машины
Тогда и для
GetTikCount()
нужно знать чему равен длительность одного такта
|
|
|
|
|
|
POV
Участник
Сказали спасибо: +107/-7
Offline
Сообщений: 640
|
|
Re: Отстает синхронизация в Timer
« Ответ #11 : 25 Январь 2013, 17:53:27 »
|
|
Конечно. Можно тактовую взять из винды или посчитать тактовую при запуске программы:
UINT t1 = GetTikCount(); Sleep(1000); UINT t2 = GetTikCount(); float k = (t2-t1)/1000;
Далее этот k умножай на нужный интервал в миллисекундах.
|
|
|
|
|
|
POV
Участник
Сказали спасибо: +107/-7
Offline
Сообщений: 640
|
|
Re: Отстает синхронизация в Timer
« Ответ #12 : 25 Январь 2013, 18:07:59 »
|
|
А если хочется вообще по максимуму переложить на VCL, то вместо GetTikCount использовать Now() и метод получения числа миллисекунд в переменной TDateTime (объявлена в DatUtils):
DateUtils.hpp> ... ::Execute() { TDateTime last_dt = Now(); TDateTime current_dt; while(1) { current_dt;= Now(); if (MilliSecondOf(current_dt-last_dt) > interval) { last_dt = current_dt; ... // тут вызываем обработчик события } else last_dt = current_dt; } }
|
|
|
|
|
|
Leex
Участник
Сказали спасибо: +132/-1
Offline
Сообщений: 577
|
|
Re: Отстает синхронизация в Timer
« Ответ #13 : 25 Январь 2013, 19:46:25 »
|
|
ребуется с определенной периодичностью (1...100 мс) максимально точно во времяни выполнять какую либо операцию
в венде впринципе невозможно добиться стабильного выполнения чего-либо с задержками меньше 15мс (цифра приблизительная по опыту, точные данные можно нагуглить), т.к это вам не ось реального времени.
Для большинства задач, где требуется точность и хороший отклик, лучше использовать отдельные потоки. Например, метод Execute VCL потока может быть представлен в виде цикла с вызовом паузы в конце:
На счет потоков согласен, но не для задач где нужно перерисовывать интерфейс, т.к потребуется синхронизация, а это ничем не быстрее TTimer, Sleep тоже не вариант, ибо тоже очень неточен в силу архитектуры ОС
Конечно. Можно тактовую взять из винды или посчитать тактовую при запуске программы:
Только не следует забывать, что современные процы умеют динамически изменять свою частоту
А разве оно надо выводить на экран с такой скоростью? Во-первых если у монитора частота обновления 60 Гц, то задержки меньше 16 мс не дадут ничего. Во-вторых на монитор смотрит человек, и он в силу физиологических особенностей ну ни как не сможет определить задержку вывода скажем на 20 мс.
Здесь нужно пересмотреть постановку задачи, с такими условиями она не решаема под виндой
|
|
|
|
|
|
Rius
Давний друг
Сказали спасибо: +116/-5
Offline
Сообщений: 753
|
|
Re: Отстает синхронизация в Timer
« Ответ #14 : 26 Январь 2013, 10:41:06 »
|
|
Тот самый таймер использует часы материнской платы, которые не могут дать интервалы точнее ~50мс. Потому таймер для таких мелких интервалов не пригоден. Не говоря уж о том, что винда - не rtos.
|
|
|
|
|
|
MaxiMuz79
Участник
Сказали спасибо: +0/-0
Offline
Сообщений: 32
|
|
Re: Отстает синхронизация в Timer
« Ответ #15 : 27 Январь 2013, 13:37:36 »
|
|
А разве оно надо выводить на экран с такой скоростью? ........
Здесь нужно пересмотреть постановку задачи, с такими условиями она не решаема под виндой
для того чтобы выводит просто инфу на экран, точность не нужна,согласен, но только задача стоит выводить команду(ы) в порт. И пусть это событие будет выполняться с задержкой к примеру +- 15...20 мс, но стабильно и с предсказуемыми , вычисляемыми промежутками во времяни
|
|
|
|
|
|
Rius
Давний друг
Сказали спасибо: +116/-5
Offline
Сообщений: 753
|
|
Re: Отстает синхронизация в Timer
« Ответ #16 : 27 Январь 2013, 13:39:58 »
|
|
но стабильно и с предсказуемыми , вычисляемыми промежутками во времяни
Возьмите RTOS. Или сделайте внешнее устройство на базе RTOS, управляемое с ПК. Поведение винды непредсказуемо.
|
|
|
|
|
|
MaxiMuz79
Участник
Сказали спасибо: +0/-0
Offline
Сообщений: 32
|
|
Re: Отстает синхронизация в Timer
« Ответ #17 : 27 Январь 2013, 13:43:58 »
|
|
Или сделайте внешнее устройство на базе RTOS, управляемое с ПК.
как раз внешнее устройство по идее должен синхронизировать частично ПК.
А вообще подумаю как обойти этот косячек
|
|
|
|
|
|
Rius
Давний друг
Сказали спасибо: +116/-5
Offline
Сообщений: 753
|
|
Re: Отстает синхронизация в Timer
« Ответ #18 : 27 Январь 2013, 13:45:32 »
|
|
Что за устройство? К чему там стабильность посылки запросов?
|
|
|
|
|
|
MaxiMuz79
Участник
Сказали спасибо: +0/-0
Offline
Сообщений: 32
|
|
Re: Отстает синхронизация в Timer
« Ответ #19 : 27 Январь 2013, 13:54:40 »
|
|
Что за устройство? К чему там стабильность посылки запросов?
электронный осциллограф управляемый с компа
|
|
|
|
|
|
POV
Участник
Сказали спасибо: +107/-7
Offline
Сообщений: 640
|
|
Re: Отстает синхронизация в Timer
« Ответ #20 : 27 Январь 2013, 13:56:24 »
|
|
как раз внешнее устройство по идее должен синхронизировать частично ПК.
Приходилось иметь задачу с погрешностью синхронизации устройств в 20 мс. Отказался от надежды на винду. Не даст винда такой точности.
В итоге внешнее устройство в пакеты добавляло значение аппаратного счетчика по 20 мс, а в паузах между запросами (от 1 секунды) все внешние устройства сами эти тики считали до прихода нового запроса, содержащего точное время. Потом вообще GPS везде поставил.
|
|
|
|
|
|
POV
Участник
Сказали спасибо: +107/-7
Offline
Сообщений: 640
|
|
Re: Отстает синхронизация в Timer
« Ответ #21 : 27 Январь 2013, 13:57:50 »
|
|
электронный осциллограф управляемый с компа
Дык, осциллографов цифровых масса. Уверен, что прога на компе сугубо принимает эпюру для отображения. Всё прочее (синхронизация с сигналом, накопление выборок) делается аппаратно.
Там же не только винда вносит непредсказуемые задержки, а ещё, например, USB. Ни на какой RTOS эта задача не решается надёжно.
|
|
|
|
|
|
POV
Участник
Сказали спасибо: +107/-7
Offline
Сообщений: 640
|
|
Re: Отстает синхронизация в Timer
« Ответ #22 : 27 Январь 2013, 14:05:17 »
|
|
Вообще скорее тут надо консультации у схемотехника брать, а не у программистов. Соответствующих площадок много.
Вот тут http://caxapa.ru/ я встречал обсуждения готовых USB-моделей и пара человек консультировалась по своим разработкам.
|
|
|
|
|
|