Создание регулируемого низкочастотного ШИМ-контроллера на Arduino

Я ищу способ создать регулируемый ШИМ-контроллер с частотой модуляции от 0 до 100 Гц (предпочтительнее от 0 до 1000) Гц, скважностью от 0 до 100% и напряжением от 5 до 30 В постоянного тока. Я искал на Sparkfun и Adafruit продукты или шилды ШИМ, поддерживающие эту технологию, но пока не нашёл ни одного. Некоторые сервошилды можно запрограммировать на частоту 50 Гц, а саму Arduino можно замедлить до 30 Гц, изменяя параметры timer0 и timer1. Однако ни один из этих вариантов не позволяет легко изменять частоту, и ни один из них не может работать с напряжением больше 6 В.

Я долго искал и нашел несколько интересных вещей:

1) http://www.instructables.com/id/The-ultimate-PWM-driver-for-many-applications/

В этой инструкции показан аналоговый ШИМ-драйвер без датчика. Он бы справился с этой задачей, однако мне нужно знать, как считывать частоту и скважность.

2) https://www.electronicsblog.net/arduino- frequency-counterduty-cycle-meter/

Здесь есть способ использовать pulsein() и другие функции Arduino для считывания частоты и коэффициента заполнения, как показано выше. Но тогда предполагается, что напряжение ШИМ составляет 5 В. Может быть, стоит использовать 5-вольтовый стабилизатор сигнала, подаваемого на Arduino? Подойдет ли такой простой вариант или он исказит сигнал и помешает точным измерениям?

Разумеется, если у кого-то есть идеи получше, я открыт для них. Я уже давно ищу решение. Похоже, проблема действительно в низкочастотном ШИМ-запросе.

, 👍2


2 ответа


Лучший ответ:

4

ATmega328 в Arduino Uno оснащён 16-битным таймером (Таймер/Счётчик 1), поддерживающим ШИМ. Он также имеет предделитель с возможностью деления на 1024. Минимальная частота , которую он может генерировать, составляет около 0,12 Гц:

16MHz / 1024 / 65535 / 2 = 0.1192 Hz

Мы изменяем частоту ШИМ, изменяя «верхнее» значение. Для более высоких частот уменьшите верхнее значение и/или выберите меньший предделитель.

(И что вообще означает 0 Гц ШИМ?!? :-)

Рабочий цикл может варьироваться от 0 до 100%, при этом разрешение меняется в зависимости от конкретной генерируемой частоты.

Что касается высокого напряжения... используйте драйвер двигателя, или Дарлингтон, или шестигранный транзистор, или что-то ещё...

Я не понимаю, зачем вы считываете частоту. С кварцевым резонатором на 16 МГц вы устанавливаете её и получаете то, что запрашивали (в пределах допусков кварцевого резонатора, температуры и т.д.).

По крайней мере, я так думаю. Удачи!

,

Итак, для 440 Гц при 25% на контактах 9 и 10 вы можете выбрать быстрый ШИМ с режимом генерации волны 14, 16e6 /1/440 = 36363 TOP с предварительным масштабированием /1, поэтому: ICR1 = 36363 ; TCCR1A = 0b10100010; TCCR1B = 0b00011001; TCCR1C = 0; OCR1A = 36363/4, @Dave X

Режимы генерации ШИМ-сигнала с настраиваемым значением TOP (например, с помощью OCR1A или ICR1) позволяют достичь таких низких, регулируемых частот. Установите режим генерации сигнала и предделитель с помощью регистров TCCR1*, а затем измените рабочие циклы, настроив OCR?B. Для частот ниже порогового значения, поддерживаемого таймерами, можно переключиться на переключение на основе прошедшего времени (millis()) и обрабатывать частоты вплоть до 1 цикла за 50 дней., @Dave X

@Mike, я ценю помощь. Однако я действительно хочу, чтобы частота ШИМ была переменной. И да, 0 Гц — это неправильно, но я хочу сделать её очень низкой. Используя коэффициент масштабирования, как показано в этой [ссылке](http://playground.arduino.cc/Main/TimerPWMCheatsheet), можно достичь частоты только 30 Гц. Если вы также модулируете значения TOP, я полагаю, вы получите любое 16-битное значение в диапазоне от 1 до 65535. 2 указывает на разницу между двумя выходами? [ссылка](https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM), @Austin McShan

@Mike В любом случае, похоже, я смогу легко модулировать частоту... Осталось только высокое напряжение. Нужно будет ещё над этим подумать. Но я определённо считаю, что ты решил мою проблему с частотой., @Austin McShan


0

Ваш вопрос настолько близок к моему собственному проекту, что на секунду мне показалось, будто я уже публиковал это какое-то время назад, вот так. Не думаю, что мой ответ будет вам полезен, ведь я пришёл и нашёл ваш вопрос спустя два года и пять месяцев. Возможно, он будет полезен другим, кто пройдёт мимо. Сейчас я работаю над точно таким же контроллером переменного рабочего цикла и поделюсь своими находками.

Следующий программный код — результат примерно 5 месяцев изучения программирования Arduino, а также долгих безуспешных попыток добиться управления с помощью серии сборок микросхем таймера 555. Я забросил метод микросхемы таймера 555 и транзистора Дарлингтона. Я считал его слишком примитивным, и все «инженерные» схемы никогда не позволяли мне контролировать коэффициент заполнения больше 50%. Мне нужен был контроль над всеми переменными ШИМ. Сегодня я куплю металлический корпус или сделаю такой, в который поместятся примерно 5-6 потенциометров, что позволит мне регулировать все возможные переменные в области параметров ШИМ (их больше, чем в этом коде ниже). Сначала я расскажу вам о некоторых деталях кода, которые дадут вам представление о том, какой невероятно точный контроль я требую от своего проекта ШИМ:

Вникаем в суть переменного управления HIGH/LOW. Обязательно прочтите всё, что сможете, чтобы полностью понять, зачем нужны эти функции. Кроме того, имейте в виду, что при 10 битах значение 1023 обеспечивает разрешение 0,0043 вольта (очень здорово):

void loop() 
{ 
Potentiometer1 = analogRead(PotHzHIGH); 
Potentiometer1 = map(Potentiometer1, 0, 1023, 1023, 0); 
Potentiometer1 = constrain(Potentiometer1, 500, 1023);

Potentiometer2 = analogRead(PotHzLOW); 
Potentiometer2 = map(Potentiometer2, 0, 1023, 1023, 0); 
Potentiometer2 = constrain(Potentiometer2, 500, 1023);

Potentiometer3 = analogRead(Pot5Volts);     
Potentiometer3 = map(Potentiometer3, 0, 1023, 1023, 1023); //Удерживать на уровне 12 Вольт
Potentiometer3 = constrain(Potentiometer3, 0, 1023); 
//Потенциометр3 можно либо заблокировать на 12 вольт с помощью функции карты, либо
//Вы можете использовать потенциометр для изменения напряжения. Я иллюстрирую
//постоянно на уровне 12 вольт с функцией карты - оба уровня установлены на низкий/высокий
//1023 и 1023

digitalWrite(PotHzHIGH, HIGH); 
//включаем delayMicroseconds(PotHzHIGH);
// Оставить включенным на потенциометре 1=PotHzHIGH микросекунд
//1000 микросекунд = 1 миллисекунда; 1000 мс = 1 секунда

digitalWrite(PotHzLOW, LOW); 
//выключить delayMicroseconds(PotHzLOW); //держать выключенным в течение
Potentiometer2=PotHzLOW Microseconds 
//1000 микросекунд = 1 миллисекунда; 1000 мс = 1 секунда;
// Наибольшее значение в функции delayMicroseconds: 16383 микросекунды
// Наибольшее значение при переводе в миллисекунды составляет 16,383 мс, или 1/20 от
//...секунду

}

//другие вещи, которые нужно знать о вышеприведенной программе. Возможно
// записать LOW с помощью: delayMicroseconds(PotHzLOW+100);
//или delayMicroseconds(PotHzLOW*1.1);
//Вы можете добавить дополнительный потенциометр, который будет множителем LOW.
//эти дополнительные элементы управления не позволяют значению LOW когда-либо быть меньше значения High.
//это может пригодиться, если вы хотите работать в рабочих циклах, которые
//между 1% и 50%. Мне это интересно, потому что я имею дело с
//высокие частоты.

timkasey1@gmail.com

,