roboforum.ru

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

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

Раздел создан специально для людей которым интересна робототехника, но в силу разных причин они не знают с чего начать.
Задавайте ваши вопросы, какими бы простыми они не казались, постоянные посетители форума постараются ответить на них по мере своих сил.
Робот своими руками. Самодельный робот.

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

Сообщение Maxiik » 09 апр 2014, 18:49

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

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

Сообщение Myp » 09 апр 2014, 19:28

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

таким образом обороты будут известны не спустя секунду (за секунду они от 1000 до 6000 запросто могут прыгнуть) а непрерывно после каждого импульса коммутатора.
в основном цикле уже брать время таймера и считать из него по формуле об/минуту и отображать на экран
<telepathmode>На вопросы отвечает Бригадир Телепатов!</telepathmode>
Всё уже придумано до нас!
Аватара пользователя
Myp
скрытый хозяин вселенной :)
 
Сообщения: 18018
Зарегистрирован: 18 сен 2006, 12:26
Откуда: Тверь по прозвищу Дверь
прог. языки: псевдокод =) сила в алгоритме!
ФИО: глубокоуважаемый Фёдор Анатольевич

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

Сообщение avr123.nm.ru » 09 апр 2014, 20:08

какой сигнал с коммутатор - сигнал управления с холла (или какой?) или тот что на первичку катушки идет?
Читайте !
Аватара пользователя
avr123.nm.ru
отсылающий читать курс
 
Сообщения: 14195
Зарегистрирован: 06 ноя 2005, 04:18
Откуда: Москва
Предупреждения: -8

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

Сообщение Maxiik » 09 апр 2014, 22:39

Мур, спасибо большое за совет, буду пробывать !
***
На данный момент машинка ВАЗ-2108, планирую с первички катушки брать сигнал, он же туда с комутатора идёт, если я не ошибаюсь *)))
Но в будущем, если вдруг на другую машинку брать, то сигнал уже от тахометра из приборной панели брать придётся, еслиопятьже я правильновсё понимаю....?
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

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

Сообщение RootAdmin » 09 апр 2014, 22:57

Я бы учел что на первичке катушки импульсы более ста вольт и и затухающие колебания.
Дым, идущий из всех устройств в помещении предвещает появление электрика.
RootAdmin
 
Сообщения: 1725
Зарегистрирован: 07 авг 2010, 21:29
Откуда: КМВ
прог. языки: C
ФИО: Андрей

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

Сообщение Myp » 10 апр 2014, 00:00

нафик первичку, там чёрти чо творится
сигнал лучше брать на входе мутатора, от холла.
<telepathmode>На вопросы отвечает Бригадир Телепатов!</telepathmode>
Всё уже придумано до нас!
Аватара пользователя
Myp
скрытый хозяин вселенной :)
 
Сообщения: 18018
Зарегистрирован: 18 сен 2006, 12:26
Откуда: Тверь по прозвищу Дверь
прог. языки: псевдокод =) сила в алгоритме!
ФИО: глубокоуважаемый Фёдор Анатольевич

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

Сообщение Maxiik » 10 апр 2014, 00:51

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

Добавлено спустя 10 минут 56 секунд:
Собрал простейший генератор прямоугольных импульсов и сходил к другу настроил его по осциллографу, чтобы было конкретное значение, получили 50 импульсов в секунду. Теперь нужно программу написать, чтобы контроллер определил такое же количество импульсов, ну а дальше дело за малым, написать основную часть перевода импульсов в обороты в минуту *)
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

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

Сообщение Radist » 10 апр 2014, 17:48

Это в лабораторных условиях сигнал чистый и его можно ловить по фронту. А на практике помех куча, и среди них надо жить. Любая иголка сойдет за импульс, так что надо или их давить хорошо, или алгоритмически бороться (зная минимальную ширину импульса).
Аватара пользователя
Radist
 
Сообщения: 2253
Зарегистрирован: 01 июл 2009, 08:59
Откуда: Екатеринбург
прог. языки: асемблер AVR

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

Сообщение dccharacter » 10 апр 2014, 19:46

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


Хе хе, я тоже так думал, пока тахометр не сделал :-)
Есть там нюансики, ггг
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

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....
Как сделать чтобы весь диапазон чисел выводился ?
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

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

Сообщение Radist » 05 май 2014, 03:44

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

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 ();
};
}


Теперь хочу научиться считать время между каждым импульсом, подскажите как это сделать ?
В каком режиме запускать таймер и как это сделать ?
Или может без таймера можно обойтись ?
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

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

Сообщение Myp » 05 май 2014, 09:41

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

всё остальное надо не спеша делать в программе.
в нужный момент основная программа берёт из переменной последнее актуальное значение таймера и считает время.
<telepathmode>На вопросы отвечает Бригадир Телепатов!</telepathmode>
Всё уже придумано до нас!
Аватара пользователя
Myp
скрытый хозяин вселенной :)
 
Сообщения: 18018
Зарегистрирован: 18 сен 2006, 12:26
Откуда: Тверь по прозвищу Дверь
прог. языки: псевдокод =) сила в алгоритме!
ФИО: глубокоуважаемый Фёдор Анатольевич

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);
};
}
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

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

Сообщение Radist » 05 май 2014, 14:32

Может быть уже отвечаю позже и все ясно, но вдруг... Как посчитать время между фронтами импульсов. Лучше всего (имхо, конечно) подать отфильтрованный сигнал на вход таймера ICP. Ждете фронт импульса (в основной программе), поймали его, включили таймер. Новый фронт на ноге ICP перезапишет содержимое таймера в регистр захвата, аппаратно. Все, один период посчитан. И будет прерывание (можно и в нем ждать первый фронт). Как то так, подробности в даташите.
Аватара пользователя
Radist
 
Сообщения: 2253
Зарегистрирован: 01 июл 2009, 08:59
Откуда: Екатеринбург
прог. языки: асемблер AVR

След.

Вернуться в Новичкам или основы основ роботостроения.

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 48