roboforum.ru

Технический форум по робототехнике.

Счётчик импульсов

Счётчик импульсов

Maxiik » 09 апр 2014, 18:49

Доброго времени суток !
Подскажите пожалуйста как правильно сделать счётчик импульсов.
Практическая задача состоит в том, чтобы сделать тахометр на машину. Хочу брать импульсы от комутатора и подсчитав их количество расчитать обороты двигателя и выводить на ЖК экран.
Я думаю сделать следующим образом.
Контроллер АТмега8
1) Настроить внешние прерывания на срабатывание по нарастающему фронту. В обработчике прерывания сделать так чтобы определённая переменная увеличивалась на еденицу при каждом срабатывании прерывания.
2) Настроить таймер_0 таким образом чтобы при истичении 1 секунды вызывался обработчик прерывания таймера, бралась подсчитанная переменная и расчитывалось количество импульсов в секунду. Ну а дальше уже перевести в обороты в минуту.
***
Интересует вопрос будет ли там дребезг контактов ?
Возможно ли чтобы однавременно работал таймер счётчик отсчитывающий секунды и считалась переменная по внешним прерываниям INT_1 ?
***
Зарание благодарю за советы !

Re: Счётчик импульсов

Myp » 09 апр 2014, 19:28

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

таким образом обороты будут известны не спустя секунду (за секунду они от 1000 до 6000 запросто могут прыгнуть) а непрерывно после каждого импульса коммутатора.
в основном цикле уже брать время таймера и считать из него по формуле об/минуту и отображать на экран

Re: Счётчик импульсов

avr123.nm.ru » 09 апр 2014, 20:08

какой сигнал с коммутатор - сигнал управления с холла (или какой?) или тот что на первичку катушки идет?

Re: Счётчик импульсов

Maxiik » 09 апр 2014, 22:39

Мур, спасибо большое за совет, буду пробывать !
***
На данный момент машинка ВАЗ-2108, планирую с первички катушки брать сигнал, он же туда с комутатора идёт, если я не ошибаюсь *)))
Но в будущем, если вдруг на другую машинку брать, то сигнал уже от тахометра из приборной панели брать придётся, еслиопятьже я правильновсё понимаю....?

Re: Счётчик импульсов

RootAdmin » 09 апр 2014, 22:57

Я бы учел что на первичке катушки импульсы более ста вольт и и затухающие колебания.

Re: Счётчик импульсов

Myp » 10 апр 2014, 00:00

нафик первичку, там чёрти чо творится
сигнал лучше брать на входе мутатора, от холла.

Re: Счётчик импульсов

Maxiik » 10 апр 2014, 00:51

На входе камутатора от датчика холла, там чистый прямоугольный сигнал получается, правильно ?
Тобишь дребезга контактов быть не должно ?

Добавлено спустя 10 минут 56 секунд:
Собрал простейший генератор прямоугольных импульсов и сходил к другу настроил его по осциллографу, чтобы было конкретное значение, получили 50 импульсов в секунду. Теперь нужно программу написать, чтобы контроллер определил такое же количество импульсов, ну а дальше дело за малым, написать основную часть перевода импульсов в обороты в минуту *)

Re: Счётчик импульсов

Radist » 10 апр 2014, 17:48

Это в лабораторных условиях сигнал чистый и его можно ловить по фронту. А на практике помех куча, и среди них надо жить. Любая иголка сойдет за импульс, так что надо или их давить хорошо, или алгоритмически бороться (зная минимальную ширину импульса).

Re: Счётчик импульсов

dccharacter » 10 апр 2014, 19:46

Maxiik писал(а):ну а дальше дело за малым, написать основную часть перевода импульсов в обороты в минуту *)


Хе хе, я тоже так думал, пока тахометр не сделал :-)
Есть там нюансики, ггг

Re: Счётчик импульсов

Maxiik » 05 май 2014, 01:10

что-то не получается ...(
Сделал вот как:
1) Счётчик внешних прерываний считает импульсы и с каждым импульсом увеличивает счётную переменную на 1.
2) Таймер счётчик запрограммирован на генерацию прерывания по переполнению. От начала счёта до переполнения таймер отсчитывает 32 миллисекунды.
При каждом переполнении таймера_0 генерируется прерывание где значение переменной i (количество импульсов) умножается на 31 и получается значение импульсов в секунду.
Далее обнуляем значение переменной i и завершаем прерывание.
Прикладываю кусок кода.
***
int s; // переменная для хранения выводимого значения
int i; // переменная счётчик прерываний - импульсов

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
i++; // при каждом импульсе увеличиваем i на еденицу
}

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0x00;
// Place your code here
#asm ("cli") // глобально запрещаем прерывания на время обработки
s = i*31; // расчитываем сколько импульсов за секунду
i=0; // обнуляем счётчик импульсов
#asm ("sei") // разрешаем глобальные прерывания

}

***
Получается так, что выводится только значение кратное 31, тобишь выводится только 31 или 62 или 93....
Как сделать чтобы весь диапазон чисел выводился ?

Re: Счётчик импульсов

Radist » 05 май 2014, 03:44

Ну а вы как хотели? Если умножаете на 31, то так и будет.Чтобы было как вы хотите, надо делать так: тахометр выдает импульсы в секунду. Если измерять их количество в течение секунды - сразу получите результат плюс минус один оборот в секунду. Затем их надо перевести в число оборотов в минуту. Умножаете на 60. Этот способ лучше применять для больших оборотов, чтобы было много импульсов в секунду. А для малых лучше измерять период импульсов, но не одного, а сколько их будет за секунду, а затем усреднить. Границей переключения режимов предлагаю 1 кГц.

Re: Счётчик импульсов

Maxiik » 05 май 2014, 09:41

Radist, спасибо большое за советы! Сейчас попробую переделать чтобы импульсы за секунду считались...
Мне вот только не совсем понятно что это значит:
А для малых лучше измерять период импульсов, но не одного, а сколько их будет за секунду, а затем усреднить. Границей переключения режимов предлагаю 1 кГц.

Ещё не совсем понятно как сделать так, чтобы считалось время от каждого импульса, чтобы считать не число импульсов , а время между ними как говорил Мур.???
Попробую порассуждать...
При возникновении импульса по нарастающему фронту генерирую прерывание и в обработчике должен прописать:
...Запрещаю глобально прерывания
1) Читаю значение из таймера.
2) Перевожу в секунды.
3) Вывожу на экран.
4) Обнуляю таймер.
... Разрешаю глобально прерывания


Не совсем понимаю в каком режиме нужно запустить таймер и как из него прочитать текущее значение ???
По сути функция main будет пустая ? ...вся программа в обработчике прерывания ?

Извините, если есть глупые вопросы, просто по воле судьбы я то занимаюсь своим хобби, то приходится забросить на время работы, вот и забывается многое и опыт медленно нарабатывается...
Спасибо Вам за помощь !

Добавлено спустя 18 минут 5 секунд:
Считать за секунду получилось *)
Вот куски кода, сначала обработчик внешнего прерывания и переполнения таймера, а потом бесконечный цикл из основной функции...
***
int s; // переменная для хранения выводимого значения
int i; // переменная счётчик прерываний - импульсов
int a; // переменная для подсчёта 31-ого переполнения таймера для выделения секунды

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
i++; // при каждом импульсе увеличиваем i на еденицу
}

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0x00;
// Place your code here
a++;
}


***

А теперь основная функция...
***
// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
{ if (a == 31)
{
#asm ("cli") // глобально запрещаем прерывания на время обработки
s = i; // расчитываем сколько импульсов за секунду
i=0; // обнуляем счётчик импульсов
a=0; // обнуляем счётчик секунды
#asm ("sei") // разрешаем глобальные прерывания
};

// Place your code here
lcd_gotoxy(0,0);
lcd_putchar(s/10+0x30);
lcd_putchar(s%10+0x30);
// delay_ms ();
};
}


Теперь хочу научиться считать время между каждым импульсом, подскажите как это сделать ?
В каком режиме запускать таймер и как это сделать ?
Или может без таймера можно обойтись ?

Re: Счётчик импульсов

Myp » 05 май 2014, 09:41

вот так
Maxiik писал(а): ...Запрещаю глобально прерывания
1) сохраняю в переменную значение из таймера.
... Разрешаю глобально прерывания

всё остальное надо не спеша делать в программе.
в нужный момент основная программа берёт из переменной последнее актуальное значение таймера и считает время.

Re: Счётчик импульсов

Maxiik » 05 май 2014, 10:22

Спасибо, Мур !
Вроде получилось! Глянь пожалуйста *)
***
Обработчик внешнего прерывания и таймера
***

int s; // переменная для хранения выводимого значения
int i; // промежуточная переменная для хранения времени между импульсами в миллисекундах
int a; // переменная для хранения натиканого значения таймера

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
#asm ("cli") // глобально запрещаем прерывания на время обработки
a = TCNT0; // Присваиваем переменной а число натиканое таймером
TCNT0 = 0; // обнуляем таймер
#asm ("sei") // разрешаем глобальные прерывания
}

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0x00;
}


***
основная функция...
***

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
{
i = a * 0.128; // преобразуем число натиканое таймером в время между импульсами в милесекундах
s = 1000 / i; // делим секунды на количество милесекунд и получаем число импульсов в секунду

lcd_gotoxy(0,0);
lcd_putchar(s/10+0x30);
lcd_putchar(s%10+0x30);
};
}

Re: Счётчик импульсов

Radist » 05 май 2014, 14:32

Может быть уже отвечаю позже и все ясно, но вдруг... Как посчитать время между фронтами импульсов. Лучше всего (имхо, конечно) подать отфильтрованный сигнал на вход таймера ICP. Ждете фронт импульса (в основной программе), поймали его, включили таймер. Новый фронт на ноге ICP перезапишет содержимое таймера в регистр захвата, аппаратно. Все, один период посчитан. И будет прерывание (можно и в нем ждать первый фронт). Как то так, подробности в даташите.


cron
Rambler\'s Top100 Mail.ru counter