| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > Частотомер |
| Автор: Семен78 31.3.2008, 14:02 |
| Хочу мерить частоту оборотов на двигателе - железо готово(опрос LPT) - набираюсь мыслей по софту: В MFC - Edit box и Кнопка на которой наввешу : таймер 1 сек . который запускает бесконечный цикл с опросом порта и записью единичек .... Ну и надеюсь видеть цифру новую каждую сек. Вопрос - как закончить цикл при наступлении следующей команды от таймера? |
| Автор: korian 31.3.2008, 14:11 |
это необходимо делать? вообще лучше расскажите, что надо сделать, не опираясь на реализацию, а то так не понятно... самый простой вариант, когда программа просто опрашивать порт каждую секунду: на диалог ставим Edit при инизиализации диалога, инициализируем таймер, устанавливаем обновление 1 сек. в функции таймера, читаем порт и выводим данные в edit |
| Автор: Семен78 31.3.2008, 14:23 |
| крутится вал около 10 -20 тыс. оборотов в секунду - на валу метка для датчика который висит на LPT. надо точно мерить частоту вращения не пропуская ни одного оборота - полагаю что частота выполнения бесконечного цикла с опросом порта много выше чем частота вала |
| Автор: Andrey44 31.3.2008, 14:25 |
| korian, поддерживаю твое мнение. Бесконечный цикл не нужен. Тогда это надо делать в другом потоке. Самый лучший вариант - таймер. |
| Автор: Семен78 31.3.2008, 14:46 | ||
что то типа этого ?
Добавлено через 7 минут и 50 секунд ну вобщем как уж получится - хочу попробовать возможно ли оценить погрешность ? как же работают всякие виртуальные приборы где важна точность? |
| Автор: korian 31.3.2008, 14:57 |
нет не так. необходимо создавать дополнительный поток, который будет считать частоту. основной поток будет брать данный из дополнительного и выводить их по таймеру или по Event'у из дополнительного потока. но еще раз повторяю, что есть большая вероятность терять куски данных. Добавлено через 8 минут и 16 секунд делается это на базе устройства. например, если нужна только частота, но не нужно ее изменение, то такое делается просто. устройство само считает частоту. при запросе частоты, на LPT порт подается значение частоты в данный момент времени. если нужно знать изменение частоты, то в устройстве должен быть буфер, в котором содержится изменение частоты с нужной дискретизацией по времени. и должна быть возможность дать программе прочитать этот буфер. |
| Автор: korian 31.3.2008, 15:19 |
| http://forum.ixbt.com/topic.cgi?id=26:38024 по поводу как это лучше делать в плане устройства. ну а в программном плане (если работать с тем что есть), вам нужно наследовать класс от CWinThread. и делать опрос устройства с подсчетом частоты в OnInitInstance. главная программа должна будет опрашивать этот поток... и не забудьте про сихнранизацию. в этом помогут классы CCriticalSection и CSingleLock. |
| Автор: Семен78 31.3.2008, 15:28 |
| Благодарю! пошел теорию "грызть" .... |
| Автор: Lazin 31.3.2008, 15:49 | ||
| Семен78, Во первых тебе нужен источник опорной частоты. всего есть 2 способа измерения частоты: в первом у тебя опорная частота меньше чем измеряемая, во втором - опорная частота больше чем измеряемая. описываю для первого случая... что-бы измерять частоту, во первых нужно как-то получать управление каждый раз когда приходит импульс на LPT (как это сделать хз, с параллельным портом никогда не работал), и тупо их считать. здесь важно что-бы не произошло переполнение переменной. то есть нужна переменная типа long, в которой у тебя-бы накапливалась сумма пришедших импульсов с датчика. В качестве источника опорной частоты можно использовать таймер, например с периодом 1с (для простоты))) при каждом срабатывании таймера рассчитываем частоту, а потом обнуляем счетчик как то так
при втором методе таймер и порт меняются местами, мы считаем сколько натикало по таймеру, и при появлении сигнала, переменная, в которой содержится количество тиков таймера будет содержать количество тиков таймера прошедших между приходами 2-х соседних импульсов с датчика. а с потоками заморачиваться не стоит, не думаю что погрешность будет заметна... |
| Автор: Семен78 31.3.2008, 16:04 |
| вот и проблемка как постоянно следить за появлением сигнала (опрашивать порт) - для двух случаев . вычитал что тик таймера 55 мсек. ( а точность вроде 10 мсек.) а мои импульсы примерно 3 мсек.(300 имп. в сек.) |
| Автор: korian 31.3.2008, 16:51 |
вешать сигнал надо не на данные, а на упровляющий "провод" LPT и обрабатывать соответствующие прерывание. в Windows на уровне пользователя обрабатывать прерывания нельзя, поэтому для такого варианта надо писать драйвер (вместо потока). что вообщем-то правильнее и обеспечит более лучшую работу (в том смысле что будет меньше или не будет вообще пропусков импульсов). |
| Автор: maxim1000 31.3.2008, 20:40 |
| не уверен, но, вгозможно, одна из линий LPT предназначена для индикации передачи данных т.е. можно повесить на неё сигнал и просто читать из LPT (обычным ReadFile) в зависимости от того, сколько байт получится читать в секунду, можно посчитать частоту обработкой прерывания будет заниматься драйвер LPT, тчо лучше, чем обычное приложение P.S. естественно, это всё при том условии, что есть такой сигнал и стандартный драйвер ведёт себя соответствующим образом |
| Автор: Семен78 31.3.2008, 23:20 |
| похоже это тема не для раздела новичков - (казалось бы научить комп. посчитать импульсы ..... думаю может легче и точнее такой вариант: собираю схемку - генератор секундных импульсов с кварцем (часовым) и через доп. логику ограничиваю подачу считываемых импульсой секундной полосой . запускаю таймер на бесконечный цикл опроса порта каждые 1.5 сек. и второй таймер который через 1 комп. тик(55 мсек.) будет killtimer( предыдущий) - вот тока как их сопрячь по фазе и чтоб результат обновлять...? |
| Автор: korian 31.3.2008, 23:48 |
| очень не плохой вариант предложил maxim1000, похожий сигнал у ECP Parallel LPT должен быть полюбому. осталость изучить как к нему прикрутиться правильно. а дальше... на таймере в программе читаем LPT порт. частота = количество прочитаных байт / (текущее время - предыдущее время чтения) при таком подходе, при 10-20кГц, пропусков поидее быть не должно. |
| Автор: Lazin 1.4.2008, 08:49 |
| млин, да наверняка можно сделать так, что-бы система вызывала твой callback при наступлени события от LPT порта, с ком портом такое прокатывает. постоянно опрашивать порт - бредовая идея, ты так ничего не посчитаешь, при некоторых соотношениях частоты опроса и частоты сигнала у тебя будет 0-я частота. Если так делать, то частота опроса должна быть на порядок больше частоты сигнала.. но это очень неэффективно с точки зрения производительности системы. Кстати, операционная система не предназначена, для того что-бы из нее делали частотомер )), может стоит использовать какой, нибудь контроллер, для измерения частоты? |
| Автор: Семен78 1.4.2008, 10:26 |
| на LPT в регистре контроля глянул - строб импульс данных или разрешение аппаратного прерывания? но не понимаю какая разница с какой линии читать биты . а про метод чтения если правильно уловил : запускаем цикл на чтение порта с подсчетом битов пока не на считает фиксированную цифру , при этом до и после цикла некой функцией извлекаем системное время , вычисляем разность и от туда частоту ....? |
| Автор: korian 1.4.2008, 10:43 | ||
не так. этим будет заниматься процессор на уровне прерываний. 1 импульс - одно прерывание. считать их будет Windows в ввиде байтов. сами значения байтов нам не важны, главное их количество. Драйвер для LTP порта уже существует, необходимо только правильно падать сигнал, чтобы комп считал, что вы ему передали байт инфы (за один такт передачи по ECP LPT передается байт). потом стандартными функциями CreateFile("LPT"....) ReadFile читаем байты. Накопленные байты винда сама буферезирует, так что нам просто на таймере надо читать LPT порт. Никаких циклов не надо. главное читать достаточно часто, т.к. у буфера поидее есть придел |
| Автор: Семен78 1.4.2008, 11:46 | ||
это резервный вариант будет |
| Автор: xvr 1.4.2008, 12:09 | ||
Для того, что бы Винда открыла порт как ECP, он должен определится как ECP в процессе PnP, а для этого надо, что бы то, что подключается к LPT порту понимало PnP протокол из IEEE 1284 и умело отвечать, что оно ECP устройство. Действо сие гораздо сложнее, чем подключить 1 провод к LPT. В общем, подключение к ECP будет сложнее, чем сделать частотомер на каком нибудь МК и скидывать инфу из него по COM порту (например) |
| Автор: Семен78 4.4.2008, 14:46 |
| Нашел инструментарий работы с прерыванием от LPT: http://www.pcports.ru/xDRV_sys.php Думаю зачем второй поток на чтение делать когда таймером буду запускать функцию работы с прерыванием...? |
| Автор: xvr 4.4.2008, 20:08 | ||
Подайте на LPT порт пачку из ~1000000 импульсов с частотой 20KHz, посчитайте, сколько импульсов пропустит этот драйвер, иначе вас ждут большие неожиданности в будущем |
| Автор: Семен78 4.4.2008, 23:47 |
| Ну вот - опять подножка. а какие частоты работают надежно? может делитель в промежуток воткну. странно как то 20khz - частота восприятия уха а порт не справится . зависит ли это от рабочих частот материнки ? через lpt - 1 mbit /c проходит вроде |
| Автор: korian 5.4.2008, 00:10 | ||
| делайте для своего устройства интерфейс ECP LPT и используйте стандартный драйвер оси. или как сказал xvr:
хотя я не уверен, что тот драйвер должен пропускать импульсы.. поидее не должен, если там реально прерывание используется... xvr, почему вы считаете, что будут пропуски? |
| Автор: xvr 7.4.2008, 12:17 | ||||||||||
Никакие
Добавлено через 1 минуту и 3 секунды
Драйвер пропускать не будет, а вот связка драйвер+call back в пользовательском приложении может просто не успеть их все отработать |