Генератор плавающей частоты
- Войдите на сайт для отправки комментариев
Ср, 11/03/2015 - 17:04
Приветствую всех!
Возникла необходимость в генераторе "плавающей" частоты.
Суть такова:
На одном выходе должна быть частота 10кГц-20кГц, изменение частоты должно наростать в течение 1 секунду от 10кГц до 20кГц, одновременно на другом выходе должно происходить обратное от 20кГц до 10кГц. Процесс бесконечный, начинается с включения питания.
Пытался взять за основу сирену
http://arduino.ru/forum/proekty/imitatsiya-sireny-grazhdanskoi-oborony, но что-то на два выхода не получается.
Если кто-то делал подобное, поделитесь скетчем с пенсионером :)
Немного не верно написал.
На одном выходе частота втечение 1 секунды изменяется от 10кГц до 20кГц и снова от 20кГц до 10кГц, а на втором выходе обратная картина, от 20 до 10 и обратно от 10 до 20.
Kollega, это довольно непростая задача. Фактически нужно задействовать 3 таймера, на одном считать время (или использовать millis() ) , а на ещё 2х сделать 2 генератора. На 16-битном таймере не проблема, Он может считать отрезками по 0,0625 us, то есть на диапазон 10kHz-20kHz выпадет на 800...400 отсчётов таймера, вполне плавно. А на оставшимся 8-битном таймере плавной регулировки просто так уже не сделать, тут придётся мудрить что-то..
Вот для одного выхода -довольно просто сделать :)
Да, dimax, вот по этому и не получается у меня... Я думал может у кого-то есть решения, но наверное нет. Вся затея в том, чтобы ограничиться одной ардуинкой, конечно если пристроить генераторы, то проблем нет, но нужно именно одной. :)
.
Kollega, ну как же нет решения? Я вам его написал в общих чертах. Но привёл информацию для мк типа ардуино-уно, т.к. я только с ними работаю. Но возьмите ардуино- леонардо (микро) или ардуино-мега 2560, там по нескольку 16-битных счётчиков, без проблем реализуете свою задумку.
Есть готовая библиотека позволяющая на ATmega168/328 генерировать до 3 независимых частот одновременно с использованием таймеров - т.е. во время генерации может исполняться другой код не задействующий таймеры. А при двух частотах таймер 0 свободен и можно использовать и millis(), micros() и ШИМ.
Сама библиотека от того же автора что и функция tone() в стандартном наборе.
https://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation
или есть библиотека
многозадачность на основе таймера 2
вот инфо, вот библиотека
Спасибо Всем за полезную инфу, приму к сведению!
Вопрос решился немного по другому, на первом выходе действительно нужна была плавающая частота, а на втором достаточно было только постоянную середину между 10кГц и 20, т.е. 15кГц, поэтому работает на втором выходе функция tone с постоянной частотой.
В заблуждение иногда вводит proteus, не всегда корректно в нем работает то, что нормально на железе, и наоборот...
Снова столкнулся с проблемой. Частота у меня сейчас меняется в течение секунды от низкой к высокой и обратно.
Но не могу прикрутить к скетчу функцию котроля заряда батареи. По принципу, если батарея разряжена на 50%, то зажигается светодиод. Отдельно такой скетч работает, а как совместить, не разберусь...
Kollega, а где вы позаимствовали такую форму детектора напряжения? Он конечно будет работать, только идеологически неверно использовать цифровой вход для контроля уровня напряжения, для этого есть ацп или компаратор. И по первому скетчу -генерировать частоту в функции loop это очень плохая затея, меандр будет очень нестабилен, и любое изменение скетча сразу вызовет уход всех ваших настроек, . Вот набросал, посмотрите. На выводе D9 генератор качающейся частоты 10..20кГц, вывод неизменяем. Вывод 13 -светодиод, вывод A1 -вход для измерения напряжения, к нему подключите ваш делитель. Задействовано 2 таймера, таймер 1 генерит сигнал, от 10 до 20кГц с дискретностью 25 Гц., А что бы удобно обслуживать регулировку частоты используется таймер 2, он 400 раз в секунду вызывает прерывание, в котором увеличивается или уменьшается значение регистраOCR1 на единицу, и сответственно меняется частота на 25Гц. Порог срабатывания светодиода задаётся в строке 24.
Здравствуйте, dimax! Респект Вам и Уважуха, что отвечете мне и не отправляете, как на многих форумах сначала в гугел, потом в "автошколу" :).
Радиолюбительством я занимался с детства, еще с семидесятых, в восьмидесятых работал на радиозаводе. Но в те времена был "аналог", сейчас времена и технологии совершенно другие. Меня вот на пенсии снова потянуло к паяльнику и запаху канифоли. Я раньше понятия не имел, что такое arduino, случайно в иннете наткнулся на рекламу, когда искал осциллограх.
Тема показалась интересная, теперь пытаюсь постигать азы.
Еще раз Спасибо Вам!
Kollega, а где вы позаимствовали такую форму детектора напряжения? Он конечно будет работать, только идеологически неверно использовать цифровой вход для контроля уровня напряжения, для этого есть ацп или компаратор. И по первому скетчу -генерировать частоту в функции loop это очень плохая затея, меандр будет очень нестабилен, и любое изменение скетча сразу вызовет уход всех ваших настроек, . Вот набросал, посмотрите. На выводе D9 генератор качающейся частоты 10..20кГц, вывод неизменяем. Вывод 13 -светодиод, вывод A1 -вход для измерения напряжения, к нему подключите ваш делитель. Задействовано 2 таймера, таймер 1 генерит сигнал, от 10 до 20кГц с дискретностью 25 Гц., А что бы удобно обслуживать регулировку частоты используется таймер 2, он 400 раз в секунду вызывает прерывание, в котором увеличивается или уменьшается значение регистраOCR1 на единицу, и сответственно меняется частота на 25Гц. Порог срабатывания светодиода задаётся в строке 24.
У меня еще такой вопрос. Просимулировал в proteus_е, получается, что время изменения частоы несколько секунд. Мне не обходимо время от низкой к высокой и обратно за одну секунду. Подскажите, каким образом изменить время, и как можно изменить верхнюю и нижнюю частоту, и как можно зафиксировать (на время настройки верхнюю и нижнюю частоту, по тому, что proteus не успевает считывать.)
Kollega, Думаю вы не правильно что-то задали в протеусе. Возможно татовую частоту. (Я не пользуюсь этой прогой, так что не скажу точно) Время считается так - частота процессора (16 000 000 ) / делитель (задано 256), = тактовая частоту таймера, т.е. 62500Гц. Переведём их сразу в секунды для удобства, 1/62500 = 16uS. Далее в 6 строке скетча задаётся количество тактов, которые нужно пропустить перед прерыванием. 16 * 155= 2480 uS. Т.е. каждые 2,48 ms запускается прерывание. Цикл увеличения или уменьшения частоты состоит из 400 прерываний, 2,48 * 400 =992 миллисекунды . Если хотите за секунду и увеличить и уменьшить, то придётся поменять делитель на /1024
TCCR2B=(1<<CS20)|(1<<CS21)
и задержку|(1<<CS20)
;OCR2A=20;
Проверяем: 16 000 000 / 1024 = 15 625 ; 1/15 625 = 64us ; 64*20= 1280us прерывание. Нам нужно сделать их 800 за секунду, 1280*800 = 1,024 s
Зафиксировать частоту -закомментируйте тело прерывания или можно только 16 и 17 строчку.
Изменить частоту - в регистре OCR1A записывать другие значения, рассчитывать можно по аналогии, делитель там 1.
Да. Сейчас понятно. Я протеусом пользуюсь, чтобы хоть как-то сначала получить эмуляцию.
Более лучшей программы для эмуляции не нашел, или плохо искал. У меня стоит еще multisim, но этот эмулятор больше для аналога.
Я в скетч прикрутил еще один светодиод, на эмуляторе заработало.
Т.е. напряжение от 9 до 7 вольт - светится "высокий" заряд батарейки, от 7 до 5 - два светодиода, типа середина, и от 5 вольт и ниже типа "низкий" заряд батарейки.
Вы пользуетесь каким либо эмулятором?
Kollega, Думаю вы не правильно что-то задали в протеусе. Возможно татовую частоту. (Я не пользуюсь этой прогой, так что не скажу точно) Время считается так - частота процессора (16 000 000 ) / делитель (задано 256), = тактовая частоту таймера, т.е. 62500Гц. Переведём их сразу в секунды для удобства, 1/62500 = 16uS. Далее в 6 строке скетча задаётся количество тактов, которые нужно пропустить перед прерыванием. 16 * 155= 2480 uS. Т.е. каждые 2,48 ms запускается прерывание. Цикл увеличения или уменьшения частоты состоит из 400 прерываний, 2,48 * 400 =992 миллисекунды . Если хотите за секунду и увеличить и уменьшить, то придётся поменять делитель на /1024
TCCR2B=(1<<CS20)|(1<<CS21)
и задержку|(1<<CS20)
;OCR2A=20;
Проверяем: 16 000 000 / 1024 = 15 625 ; 1/15 625 = 64us ; 64*20= 1280us прерывание. Нам нужно сделать их 800 за секунду, 1280*800 = 1,024 s
Зафиксировать частоту -закомментируйте тело прерывания или можно только 16 и 17 строчку.
Изменить частоту - в регистре OCR1A записывать другие значения, рассчитывать можно по аналогии, делитель там 1.
Если я правильно понял, частота задана во втором таймере в строке 14. Это верхняя частота? По какой формуле мне нужно сделать расчет для изменения частоты и верхнего и нижнего предела.
Kollega, эмуляторами не пользуюсь, как-то всё не возникало надобности, сам удивляюсь. Но протеус давно скачал и установил, осталось научиться пользоваться)
Частота первый раз задаётся в 10 строке, в обаботчик вносится в регистр таймера в 18 строке. Инициализируется переменная в 14 строке, там задаётся с чего начинать движение частоты туда/сюда.Но на частоту влияет ещё делитель (который впрочем отключен -бит CS10 в 9 строке) Вычислить что писать в регистр для получения частоты можно так:
OCR1A= (16 000 000 /n /2 /div) -1 где n-заданная частота в Гц, div -делитель (стоит на 1)
Проверям для 10kHz (16000000 /10000 /2 /1) -1 = 799. Т.е. я на единицу в скетче ошибся, типа округлил..
Кстати уберите из 8 строки вот это, оно лишнее, не заметил сразу.
|(1<<COM1B0)
Kollega, эмуляторами не пользуюсь, как-то всё не возникало надобности, сам удивляюсь. Но протеус давно скачал и установил, осталось научиться пользоваться)
Частота первый раз задаётся в 10 строке, в обаботчик вносится в регистр таймера в 18 строке. Инициализируется переменная в 14 строке, там задаётся с чего начинать движение частоты туда/сюда.Но на частоту влияет ещё делитель (который впрочем отключен -бит CS10 в 9 строке) Вычислить что писать в регистр для получения частоты можно так:
OCR1A= (16 000 000 /n /2 /div) -1 где n-заданная частота в Гц, div -делитель (стоит на 1)
Проверям для 10kHz (16000000 /10000 /2 /1) -1 = 799. Т.е. я на единицу в скетче ошибся, типа округлил..
Спасибо!
Протеус сам по себе простой, как три копейки СССР :), я тоже его установил несколько дней назад, основные функции освоил за вечер. Только во первых не известно на сколько он врет (еще не сравнивал), но даже визуально видно на примерах, котрые я раньше щупал на идентичных схемах на железе. Во вторых, все "народные" версии протеуса, которые я пробовал, имеют разные глюки, может не сохранить проект, может просто выкинуть из программы...
Kollega, эмуляторами не пользуюсь, как-то всё не возникало надобности, сам удивляюсь. Но протеус давно скачал и установил, осталось научиться пользоваться)
Частота первый раз задаётся в 10 строке, в обаботчик вносится в регистр таймера в 18 строке. Инициализируется переменная в 14 строке, там задаётся с чего начинать движение частоты туда/сюда.Но на частоту влияет ещё делитель (который впрочем отключен -бит CS10 в 9 строке) Вычислить что писать в регистр для получения частоты можно так:
OCR1A= (16 000 000 /n /2 /div) -1 где n-заданная частота в Гц, div -делитель (стоит на 1)
Проверям для 10kHz (16000000 /10000 /2 /1) -1 = 799. Т.е. я на единицу в скетче ошибся, типа округлил..
Спасибо!
А как мы получаем 20 кГц, и что прописано в 19 и 20 строке
dimax, можно вашу электронку?
А как мы получаем 20 кГц, и что прописано в 19 и 20 строке
Что бы разделить повышение частоты от понижения я сделал флаг freq_up, когда счётчик "times" доходит до нужного конца флаг меняется, и в следущий заход частота начинает меняться в другую сторону. 20 кГц при значении OCR1A=400; Я ж вам формулу дал.
Здравствуйте, dimax!
Не могу понять, почему в протеусе нарастание и убывание частоты длится почти полторы минуты. Частота стоит правильно 16мГц, верхняя и нижняя частота совпадает.
Посмотреть можно здесь https://www.youtube.com/watch?v=m6gaJbh1Opc
Kollega, я же писал, что протеусом никогда не пользовался. Тут полно любителей протеуса, может кто подскажет вам. Живьём всё работает на рассчётных частотах, я заливал этот скетч и смотрел осциллографом.
Почитал на разных форумах о протеусе. Толком не нашел ответа, но иногда есть посты о том, что якобы при большом кол-ве прерываний в генераторе, осциллограф глючит, и нужно пользоваться анализатором. Но анализатор у меня почему-то не работает даже в готовых демо библиотеках...
Может позже разберусь.
У меня к Вам еще такой вопрос по светодиоду, я так понимаю, что значение задается от 1023, т.е. в вашем скетче 512 -это половина, начиная от половины заданного светодиод зажигается.
Как задать два условия, например выше 512 не светится, ниже 512 зажигается, а при понижении до 400 гаснет.
Так же хотелось узнать хорошие источники по изучению кода. На официальном сайте ардуино, как-то не совсем удобно написано...
Чтива по си и контроллерам -очень много, правда мало что конкретно касается ардуино, но главное принципы -они везде одинаковые.
http://we.easyelectronics.ru/AVR/dokumentaciya-po-avr-mikrokontrolleram-vse-na-russkom.html
PS: думаю вам стоит начать с вот этого http://robocraft.ru/files/books/arduino_notebook_rus_v1-1.pdf
Чтива по си и контроллерам -очень много, правда мало что конкретно касается ардуино, но главное принципы -они везде одинаковые.
http://we.easyelectronics.ru/AVR/dokumentaciya-po-avr-mikrokontrolleram-vse-na-russkom.html
PS: думаю вам стоит начать с вот этого http://robocraft.ru/files/books/arduino_notebook_rus_v1-1.pdf
Спасибо!
Правильно ли я мыслю, если мне например нужно изменить частоту. Начальная частота 20кГц
16000000/20000/2/div = 400
Верхняя частота 30кГц
16000000/30000/2/div = 266
(время 1 сек. оставляем без изменения)
Или я накосячил?
Здравствуйте, dimax! Я тут спрашивал у Вас по поводу частоы, правильно ли я изменил код.
Kollega, вы собираетесь теперь по каждому байту консультироваться? Взять да самостоятельно проверить свои идеи так трудно?