Собственный генератор прямоугольных импульсов 1 МГц на Arduino Nano — простое PWM-устройство
Компоненты и материалы
- Arduino Nano R3 — 1 шт.
- LCD-дисплей 16×2 (белый на синем) — 1 шт.
- Тактильные кнопки — 3 шт.
- Подстроечный резистор 10 кОм — 1 шт.
Необходимые инструменты и сервисы
- Arduino IDE
О проекте
Это простой генератор прямоугольных импульсов, использующий библиотеку TimerOne для формирования PWM-сигнала на пине 9 в диапазоне от ~5 Гц до 1 МГц с регулировкой коэффициента заполнения от 0 до 100%.
Устройство очень простое и состоит всего из нескольких компонентов:
- Микроконтроллер Arduino Nano
- LCD-дисплей
- Три подтягивающих резистора
- Три кнопки

Генератор позволяет регулировать период следования импульсов кнопками на входах D6 и D7. Вход D13 служит для регулировки коэффициента заполнения. Значения периода и коэффициента заполнения отображаются в первой строке LCD, частота — во второй.
Минимальный шаг изменения периода — 1 мкс, поэтому частота меняется дискретно: 1 мкс = 1 МГц, 2 мкс = 500 кГц, 3 мкс = 333,333 кГц и так далее. По мере уменьшения частоты плавность регулировки возрастает. На высоких частотах это неудобно, но такова цена простоты. В одном из предыдущих проектов я описывал похожее устройство на специализированном DDS-чипе, лишенном этих недостатков и с большим диапазоном, но более сложном в сборке.
Для визуализации выходного сигнала использовался одноканальный осциллограф. Готовое устройство размещено в корпусе и стало еще одним полезным инструментом в лаборатории.
Исходный код
#include
#include
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7
unsigned long t = 1000, f, k = 512; // по умолчанию 1000 мкс (1000 Гц), меандр
byte k1, kn, kn1, kn2;
int drive, drive0;
void setup() {
lcd.begin(16, 2);
pinMode(9, OUTPUT);
pinMode(6, INPUT); // кнопка уменьшения периода
pinMode(7, INPUT); // кнопка увеличения периода
pinMode(13, INPUT); // кнопка изменения коэффициента заполнения
}
void loop() {
Timer1.initialize(t); // период
Timer1.pwm(9, k); // k — коэффициент заполнения 0-1023
kn = digitalRead(6); // кнопка на входе 6 (- период)
kn1 = digitalRead(7); // кнопка на входе 7 (+ период)
kn2 = digitalRead(13); // кнопка на входе 13 (+ коэф. заполнения)
if (kn == HIGH) { // уменьшение периода
drive++;
if (drive < 30) t = t - 1;
else if (drive >= 30 && drive < 60) t = t - 10;
else if (drive >= 60 && drive < 100) t = t - 100;
else if (drive >= 100) t = t - 1000;
} else {
drive = 0;
}
if (kn1 == HIGH) { // увеличение периода
drive0++;
if (drive0 < 30) t = t + 1;
else if (drive0 >= 30 && drive0 < 60) t = t + 10;
else if (drive0 >= 60 && drive0 < 100) t = t + 100;
else if (drive0 >= 100) t = t + 1000;
} else {
drive0 = 0;
}
if (t == 0 || t > 300000) t = 1; // ограничение минимума
if (t > 200000 && t < 300000) t = 200000; // ограничение максимума
f = 1000000 / t; // расчет частоты
k1 = k * 100 / 1024; // расчет % заполнения
if (kn2 == HIGH) { // регулировка коэффициента заполнения
k = k + 16; // шаг 16 из 1024 (можно 8 для плавнее)
}
if (k == 1024) k = 0;
// вывод на дисплей
lcd.setCursor(0, 0);
lcd.print("T=");
lcd.print(t);
lcd.print(" us");
lcd.setCursor(12, 0);
lcd.print(k1);
lcd.print(" %");
lcd.setCursor(0, 1);
lcd.print("F=");
lcd.print(f);
lcd.print(" Hz");
delay(300);
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(" ");
}
Схема

Производственный процесс
- Понимание сигналов прямоугольной формы: основы и применения
- Сделай свой LUMAZOID: DIY Arduino музыкальный визуализатор
- Слово-часы (Word Clock) на Arduino — DIY-часы с текстовой индикацией времени
- Создание осциллографа на Arduino Nano с дисплеем Nokia 5110 (20 кГц): простое DIY-руководство
- Умный вольтметр на Arduino и смартфоне — простое DIY-проект
- JX Wave Generator — Генератор сигналов на Arduino с DDS AD9833 и OLED-дисплеем
- Простой ИК-датчик препятствий на Arduino: ИК-светодиод и фотодиод
- Сборка DIY VR-скейтборда на Arduino, Google Cardboard и Bluetooth
- Простой калькулятор на Arduino UNO — базовый проект для начинающих
- Сборка точного измерительного колеса на Arduino Nano и вращательном энкодере