Управление частотой и скважностью ШИМ-сигнала
- Войдите на сайт для отправки комментариев
Добрый день, коллеги!
Прошу у Вас совета по управлению высокочастотным сигналом.
Проблема следующая: Требуется получить световые импульсы (светодиода, лазера и проч. источников) с частотой от 0 до 10 000 Гц, при этом время импульса должно быть управляемым. Импульсы нужны прямоугольные, как на рисунке:

На ум сразу пришло два пути:
1. Управление родным 8-битным ШИМ Arduino. Но тут проблема в частоте - она составляет примерно 500 Гц, не регулируется и даже иногда скачет, как пишут коллеги на форуме. И точность ограничена 8 битами.
2. Управление через классический сценарий мигания светодиодом.
void loop()
{
digitalWrite(13, HIGH); // зажигаем светодиод
delay(1000); // ждем секунду
digitalWrite(13, LOW); // выключаем светодиод
delay(1000); // ждем секунду
}
Однако, здесь не понятно - гарантируется ли прямоугольный сигнал или это будет периодическое включение / выключение всё того же сигнала 500 Гц?
Можно ли организовать на Arduino управление частотой прямоугольного сигнала от 0 до 10 000 Гц при заданной скважности?
Организовываете прерывание по любому таймеру, например 1раз в 10мкс, затем выставляете значение вывода с нужной частотой и скважностью.
Anatolyekb, это не то что нужно? http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-a...
Спасибо! Правда Вы работаете с довольно высокими частотами, мне будет достаточно и 10 кГц. Но скетч, как мне кажется, может подойти. Вообще идея проекта - высокочастотный стробоскоп для съемки летящих со скоростью 10-30 м/с частиц при выдержке фотокамеры 0,01-1 с. Как думаете, можно ли бужет реализовать прерыватель света на таком коде?
Добрый день!
Я попробовал Ваш код, всё работает.
Только один вопрос:
Как регулировать время импульса? Я пытаюсь задась время импульса от 1 мкс и выше при частоте до 50 кГц.
Anatolyekb, не понял вопроса. Что значит время импульса?. В смысле скважность? Там всё написано -энкодером. Duty cycle регулируется в процентах от 1 до 100.
Постараюсь объяснить языком неэлектронщика.
Хочу иметь управляющий сигнал для регулирования частоты мерцания светодиода (лазера). Управляющий сигнал будет идти на базу транзистора для управления питанием светодиода (лазера). Предполагается частота до 50 кГц. Но помимо частоты я ещё имею желание управлять временем импульса (чтобы с момента подачи напряжения на базу транзистора до прекращения подачи напряжения проходило заданное время). Время импульса не обязательно задавать в секундах, я был был рад и процентам от "длины волны".
Например, на подграфике "а" я получил частоту 1 Гц, соответственно "длину волны" 1 с, а время импульса 0,5 с (или 50 % от длины волны). А вот на подграфике "б" при тех же Ч = 1 Гц и ДВ = 1 с уже другое время импульса 0,25 с (или 25 % от длины волны).
Как же управлять временем импульса?
Простите, если я нарушил какие законы физики при описании проблемы.
Anatolyekb, это и есть скважность, или duty cycle по зарубежному. В чём проблема то, вы не нашли как регулируется скважность?
Да, я не могу найти, как регулировать скважность. Я использую Ваш код, но в нём нет duty cycle.
void setup() { Serial.begin(9600); pinMode (9,OUTPUT); // выход генератора TCCR1A=1<<COM1A0; //подключить выход OC1A первого таймера TCCR1B=0;// } void loop() { static uint32_t enc=1; //переменная счёта энкодера uint32_t ocr; uint32_t divider; float freq; if (Serial.available() > 0) { enc = Serial.parseInt(); //расчёт прескалера и OCR по нужной частоте divider=1; ocr = (F_CPU / enc /2 /divider); if (ocr >65536) { divider=8; ocr = F_CPU / enc /2 /divider; if (ocr >65536) { divider=64; ocr = F_CPU / enc /2 /divider; if (ocr >65536) { divider=256; ocr = F_CPU / enc /2 /divider; if (ocr >65536) { divider=1024; ocr = F_CPU / enc /2 /divider; if (ocr >65536) {ocr=65536; }}}}} OCR1A=ocr-1; //запись в регистр прескалера switch (divider) { case 1: TCCR1B=1|(1<<WGM12); break; case 8: TCCR1B=2|(1<<WGM12); break; case 64: TCCR1B=3|(1<<WGM12); break; case 256: TCCR1B=4|(1<<WGM12); break; case 1024: TCCR1B=5|(1<<WGM12); break; } freq= (float) F_CPU/2 / (OCR1A+1) /divider; if (freq <10000) { Serial.print(freq,1);Serial.println(" Hz "); } if (freq >10000) { Serial.print(freq/1000,3);Serial.println(" kHz");} } //end if serial.. } //end void loopAnatolyekb, Это вообще набросок был. Последняя рабочая версия в сообщении #77
Anatolyekb, не понял вопроса. Что значит время импульса?. В смысле скважность? Там всё написано -энкодером. Duty cycle регулируется в процентах от 1 до 100.
Mining, да щёлкает по 1 проценту, до тех пор пока есть такая возможность. Ближе к концу верхнего диапазона генерируемых частот возможность кончается, и там как получится. Я писал про этот небольшой недостаток)
Mining, да щёлкает по 1 проценту, до тех пор пока есть такая возможность. Ближе к концу верхнего диапазона генерируемых частот возможность кончается, и там как получится. Я писал про этот небольшой недостаток)
Или процессор посчитает а порт не позволит?
Mining, я по DUE не специалист :) Но если вам нужно больший диапазон и точность -то есть смысл сделать на специализированном чипе -синтезаторе частот типа ad9850 или аналогичных. У них гораздо лучшее разрешение, и гораздо больший диапазон частот. Практически серьёзная вещь за относительно небольшие деньги.
Mining, я по DUE не специалист :) Но если вам нужно больший диапазон и точность -то есть смысл сделать на специализированном чипе -синтезаторе частот типа ad9850 или аналогичных. У них гораздо лучшее разрешение, и гораздо больший диапазон частот. Практически серьёзная вещь за относительно небольшие деньги.
Mining, в принципе можно высчитать реальную возможность ардуино в регулировки скважности. Если вы хотите по 0,01% двигать, значит всего нужно 10000 градаций. Вычисляем максимальную частоту, на которой это возможно 16000000 /2 / 10000 = 800герц Аналогично можно прикинуть для DUE, если конечно к ней эти расчёты применимы: 84000000 /2 / 10000 = 4200 Герц Так что с вашими "скромными" запросами покупать синтезатор -единственный вариант.
Спасибо!
Т.е. теоретически можно двигать скважность с точностью 0,1% до 42кГц?
Уважаемый Mining, можно ли связаться с Вами?
Я ковыряюсь со схемой с переменным успехом. Не поделитесь ли своими наработками по теме?
Уважаемый Mining, можно ли связаться с Вами?
Я ковыряюсь со схемой с переменным успехом. Не поделитесь ли своими наработками по теме?
Т.е. теоретически можно двигать скважность с точностью 0,1% до 42кГц?
В DUE не знаю, я в них не разбираюсь, просто предположил что там скорее всего такой же принцип. В некоторых МК есть ещё PLL синтезатор, он умеет умножать тактовую частоту в несколько раз. Например в Леонардо есть такой, его таймер можно завести чуть ли ни на 96 (или 64, непомню) МГц. Но для глубокой регулировки скважности он не пойдёт, ибо там только один 10-битный таймер умеет пользоваться PLL клоками. Т.е. на нём можно получить 1024 градации скважности, но будет всего 15 фиксированных частот, на которых возможна такая регулировка.
Народ, выручайте!
Нужен генератор импульсов от 350 герц до 4000 герц с шагом 100 герц. Длительность импульсов не должна зависеть от частоты и должна регулироваться отдельно в диапазоне от 1 милисекунды до 50 милисекунд с шагом 0.5 милисекунды. Очень надо!
ali_vlad, а какая по-вашему частота будет у импульса длиной 50ms ? :)
Если у вас есть куча времени, а также неиссякаемое желание геморроиться с Ардуиной, синтезаторами, сдвиговыми чипами и всем прочим в отсутствие подробнейших консультаций со стороны "шаг за шагом" - пройдите по ссылке в первых сообщениях. Там вкратце разобрано как сделать чудо-машинку на Ардуине и дополнительных микросхемках. Ещё понадобится рублей 700-1500 на Ардуинку и доп. детали.
Если у Вас нет времени и тяга к неизведанному не бъёт во всех сферах жизни, то купите готовое решение за 3900 рублей. Я пытался собрать схему, как описывают господа на форуме, но ничего не вышло.
http://www.aliexpress.com/item/200MSa-s-25MHz-Dual-channel-Signal-Source-Generator-High-Precision-Arbitrary-Waveform-Frequency-Meter-Digital-DDS/32437000474.html?spm=2114.13010608.0.95.8kZCZv
Для деревяного клепания можно взять это. Дешево и сердито. кхе очень сердито. кхе очень дешево.
void antidelayMicroseconds(unsigned long timing){ timing += micros(); while(micros()<=timing); } void setup() { pinMode(13, OUTPUT); } void loop() { digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) antidelayMicroseconds(1000000); // wait for a second digitalWrite(13, LOW); // turn the LED off by making the voltage LOW antidelayMicroseconds(1000000); }Да, Вы правы, это один из самых простых кодов. А как будет выглядеть меандр на осцилоскопе?
Зловеще.
Да, Вы правы, это один из самых простых кодов. А как будет выглядеть меандр на осцилоскопе?
Дальше надо "пилить напильником". Текущий вроде 1 секунда. Но надо мерить. Нужны новые параметры генератора , то делать нову прошивку. Наберете статистику, прикрутите управление и генератор с нужными параметрами готов.
ali_vlad, а какая по-вашему частота будет у импульса длиной 50ms ? :)
Тупанул я что-то
От 350 герц до 6000 герц с шагом 50 герц. Длинна импулься от 2 до 20 МИКРОсекунд с шагом 0.1 микросекунда.
Запуск по умолчанию с нижних границ, изменение энкодером.
ali_vlad, у меня был похожий шаблончик, подогнал немножко под вашу задачу. Энкодер прикрутите самостоятельно :)
Терминал принимает два числа через пробел. Первое - (целое) число герц (от 123) , второе (float) длительность импульса в микросекундах. Например "320 10.5" шаг регулировки длительности - 0.0625 микросекунд.
void setup() { Serial.begin(9600); pinMode(9,OUTPUT); TCCR1A=(1<<COM1A1)|(1<<WGM11); TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS10); OCR1A=0; ICR1=0; } void loop() { if (Serial.available()) { uint16_t x = Serial.parseInt(); float y = Serial.parseFloat(); ICR1= (F_CPU/x)-1; OCR1A= ((float) y / 0.0625 ) -1 ; } }Огромное спасибо, попробую. На Arduino Pro Micro (ATmega23U4), надеюсь, заработает. Энкодер и дисплей сам прикручу.
Привет!Я начинающий, я испльзую написаный табою код. Подскажи пожалуста кокое максимальное значение может иметь antidelayMicroseconds(????????)
http://arduino.ru/Reference/UnsignedLong
добрый день. у меня есть задачка, но познания не позволяют решить её гладко. я хочю сделать управляемый инвентор, тоесть управлять мостом из 4 НПН транзисторов. частота от 50 до 150 Гц. регулировка потенциометром с шагом 1 или 2 Гц( не пренципиально). транзисторы будут в ключевом режиме. помогите пожалуйста
для начала, идти майнить познания.
Вот здесь оно, скетч №2, регулировка энкодером частоты и скважности. Проверял до частоты 32 кГц.
http://cyber-place.ru/showthread.php?t=2703
dimax, а как в этом примере: ali_vlad, у меня был похожий шаблончик, подогнал немножко под вашу задачу. Энкодер прикрутите самостоятельно :)
сделать так, чтобы каждый 4 импульс был с другой скважностью?
01voidsetup() {02Serial.begin(9600);03pinMode(9,OUTPUT);04TCCR1A=(1<<COM1A1)|(1<<WGM11);05TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS10);06OCR1A=0; ICR1=0;07}0809voidloop() {10if(Serial.available()) {11uint16_t x =Serial.parseInt();12floaty =Serial.parseFloat();13ICR1= (F_CPU/x)-1;14OCR1A= ((float) y / 0.0625 ) -1 ;15}16}AndreyTU, настроить прерывание по совпадению с регистром сравнения, каждый вход в перывание считать. На 3-ем входе изменить регистр сравнения до нужной величины, на 4-ом вернуть обратно и обнулить счётчик входов.
Спасибо, понял.
Всем добрый день.
Коллеги прошу помощи в решении задачи, суть ее такова нужно генерировать ШИМ на двух пинах с зависимой регулируемой скважностью и частотой, частота изменяется от от 20 до 200 Гц скважность как на картинке. суммарно заполнение обоих импульсов всегда 100%
Т.к. не указан контроллер, а частоты достаточно низкие, могу предположить, что самый простой и универсальный метод - программный. Т.е. пресловутый blink, с delay[Microseconds]() или millis()/micros() по вкусу.
пододет с millis()/micros(), забыл нарисовать DeadTime между импульсами по форнту и по спаду
что мешаеть сделать 1 ногу Шим + простейший инвертор на ЛА3?
А если, скажем, нужно период 10 с и скважность от 2% до 50%, которая будет функцией температуры в узком диапазоне. Сгодится ли предлагаемый выше вариант?
Есть готовая библиотека TimerOne, но там тоже оперируется микросекундами. А delay плохо дружит с DS18B20.
А если, скажем, нужно период 10 с и скважность от 2% до 50%, которая будет функцией температуры в узком диапазоне. Сгодится ли предлагаемый выше вариант?
Ну так попробуйте и потом нам расскажете.
Есть готовая библиотека TimerOne, но там тоже оперируется микросекундами. А delay плохо дружит с DS18B20.
Вы бы предпочли, чтобы оперировали месяцами? Притом, только в целых числах?
Или Вы не знаете, как переводить микросекунды в секунды, минуты и часы?
Вы бы предпочли, чтобы оперировали месяцами? Притом, только в целых числах?
Или Вы не знаете, как переводить микросекунды в секунды, минуты и часы?
Для этой библиотеки верхний предел 8,3 сек. А мне нужно минимум 10 сек период.
Вы бы предпочли, чтобы оперировали месяцами? Притом, только в целых числах?
Или Вы не знаете, как переводить микросекунды в секунды, минуты и часы?
Для этой библиотеки верхний предел 8,3 сек. А мне нужно минимум 10 сек период.
И что? Вызывать раз в 5 сек и реагировать только на каждый второй вызов не судьба?
И что? Вызывать раз в 5 сек и реагировать только на каждый второй вызов не судьба?
И при этом нужно управлять скважностью в зависимости от температуры. Пока не придумал как.
Возможность управления скважностью в зависимости от температуры как-то зависит от величины периода?
Бился с разными готовыми библиотеками. Пытался в таймер вставить переменную, но к сожалению ничего не получилось. (((
Т.к. с таймерами и прерываниями я пока плохо дружу и на уровне регистров "нихт фершеен", может кто подскажет, как можно изящно решить эту задачу? Чтобы скважность менялась в зависимости от температуры.
Т.к. с таймерами и прерываниями я пока плохо дружу и на уровне регистров "нихт фершеен", может кто подскажет, как можно изящно решить эту задачу? Чтобы скважность менялась в зависимости от температуры.
если правильно понял, период ШИМ у вас 10 секунд? - то есть частота = 0.1 гц?
Для таких длинных периодов никакие таймеры и прерывания. имхо, не нужны, все достаточно легко сделать программно.
если правильно понял, период ШИМ у вас 10 секунд? - то есть частота = 0.1 гц?
Для таких длинных периодов никакие таймеры и прерывания. имхо, не нужны, все достаточно легко сделать программно.
без delay? т.к. ds18b20 не дружит с delay. хоть примерно подскажите как