В этой статье мы рассмотрим простой генератор прямоугольных импульсов (square-wave generator) с частотой до 1 МГц на основе платы Arduino. Генератор будет использовать библиотеку TimerOne, позволяющую формировать сигнал широтно-импульсной модуляции (ШИМ) на контакте 9 платы Arduino.
Также на нашем сайте вы можете посмотреть проекты генераторов сигналов (в том числе и прямоугольных импульсов) на основе платы Arduino и DDS модуля и на основе просто платы Arduino, без использования каких-либо дополнительных устройств. Также задачу формирования подобных импульсов можно решить с помощью генератора на Arduino и модуле SI5351.
Необходимые компоненты
- Плата Arduino Nano (купить на AliExpress).
- ЖК дисплей 16х2 (купить на AliExpress).
- Потенциометр 10 кОм (купить на AliExpress).
- Подтягивающие резисторы – 3 шт. (купить на AliExpress).
- Кнопка – 3 шт.
Общие принципы работы проекта
Рассматриваемый в данной статье простой генератор прямоугольных импульсов будет использовать библиотеку TimerOne, которая позволяет формировать ШИМ сигнал на контакте 9 платы Arduino с частотой от 5 Гц до 1 МГц с настраиваемой скважностью (коэффициентом заполнения, duty cycle) от 0 до 100%. Скачать библиотеку TimerOne можно по следующей ссылке.
Генератор состоит из небольшого числа компонентов: платы Arduino Nano, ЖК дисплея, 3-х подтягивающих резисторов и 3-х кнопок.
В генераторе можно изменять период (частоту) повторения импульсов с помощью кнопок, подключенных к контактам 6 и 7 платы Arduino. С помощью кнопки, подключенной к контакту 13, можно изменять скважность импульсов. Длительность импульсов и скважность будут отображаться в первой строке ЖК дисплея, а частота – во второй строке ЖК дисплея. Минимальный шаг для настройки периода повторения импульсов составляет 1 мкс, поэтому частота импульсов будет изменяться также дискретно, например, периоду 1 мкс будет соответствовать частота 1 МГц, периоду 2 мкс – частота 500 кГц, периоду 3 мкс – частота 333.333 Гц и т.д. То есть по мере уменьшения частоты увеличивается плавность ее настройки. Конечно, это не очень практично для высоких частот, но это вынужденная плата за простоту устройства. Более продвинутый генератор можно собрать на основе использования DDS модуля, но это уже будет значительно более сложное устройство.
Для проверки работы генератора автор проекта использовал простой одноканальный осциллограф (который также можно собрать на основе платы Arduino). Для удобства работы с генератором он был помещен в небольшой корпус.
Схема проекта
Схема простого генератора прямоугольных импульсов на основе платы Arduino представлена на следующем рисунке.
Исходный код программы (скетча)
Комментарии к коду программы частично переведены.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
#include <TimerOne.h> #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// RS,E,D4,D5,D6,D7 (контакты, к которым подключен ЖК дисплей) unsigned long t=1000,f,k=512;// по умолчанию период равен 1000 μs (1000 Hz), меандр, длительность импульса равна скважности k = 512 (50%) byte k1,kn,kn1,kn2; int drive,drive0; void setup() { lcd.begin(16, 2);// LCD 16X2 pinMode(9, OUTPUT); pinMode(6,INPUT);// button at input 6 pinMode(7,INPUT);// button at input 7 pinMode(13,INPUT);// button at input 13 } void loop() { Timer1.initialize(t); // period Timer1.pwm(9, k); // k - fill factor 0-1023 (скважность, коэффициент заполнения) kn=digitalRead(6);// button input 6 (- pulse period) (уменьшить период) kn1=digitalRead(7);// button input 7 (+ pulse period) (увеличить период) kn2=digitalRead(13);// button input 13 (+ circle fill factor) (изменять скважность, по кругу) if(kn==HIGH){ // уменьшаем период drive++; if(drive<30){ t=t-1; } // если кнопку удерживать в течение длительного времени, то к коррекции периода импульса будет применяться коэффициент x10 x100 x1000 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; // если кнопку удерживать в течение длительного времени, то к коррекции периода импульса будет применяться коэффициент x10 x100 x1000 } 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){ //ограничиваем минимальную длительность импульса, если 0 μs или больше чем 300 ms (3.33 Hz), то период делаем равным 1 μs t=1; } if(t>200000 && t<300000){ // ограничиваем максимальную длительность импульса, если больше чем 200 ms, но меньше чем 300 ms (3.33 Hz), то период делаем равным 200 ms (5 Hz) t=200000; } f=1000000/t; // рассчитываем частоту k1=k*100/1024; // рассчитываем скважность if(kn2==HIGH){// кнопка для регулировки скважности (по кругу от 50 до 100%, затем от 0 до 100%) 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(" "); } |
Добрый день. В общем работает. На выход лезет кая- то одногерцовая пульсация. даже индикатор подмаргивает. Во всем диапазоне так.
Доброе утро. Я рад что у вас хотя бы этот проект генератора заработал. У автора проекта на видео вроде не видно никакой одногерцовой пульсации
сначала думал, что китайская ардуинка чудит. Но перезалил проект генератора с синусом- сигнал ровный, ничего лишнего. Здесь шаг регулировки на ВЧ огромный, не подходит.
Вы пытались это как то исправить или оставили так, как есть?
не исправлял же. перешел на синус генератор. там более плавное управление
Хорошо, спасибо, я понял