이 프로젝트는 TimerOne 라이브러리를 활용해 9번 핀에서 약 5Hz부터 1MHz까지의 PWM 신호를 생성하고, 듀티 사이클을 0~100%까지 조절할 수 있는 간단한 구형파 발생기입니다.
장치는 매우 단순하며 몇 가지 부품만으로 구성됩니다:
아두이노 나노 마이크로컨트롤러
LCD 디스플레이
풀업 저항 3개
푸시버튼 3개
펄스 발생기는 아두이노의 디지털 입력 6, 7번 핀에 연결된 버튼으로 펄스 반복 주기를 조절하고, 13번 입력 핀으로 듀티 사이클을 조절합니다. 펄스 주기와 듀티 사이클은 LCD 16×2 표시기의 첫 번째 줄에, 주파수는 두 번째 줄에 표시됩니다.
펄스 반복 주기 조정의 최소 단계는 1μs이므로 주파수는 이산적으로 변합니다. 예: 1μs = 1MHz, 2μs = 500kHz, 3μs = 333.333kHz 등. 주파수가 낮아질수록 조정의 부드러움이 증가합니다. 고주파 영역에서는 다소 비실용적이지만 단순함의 대가입니다. 이전 프로젝트에서는 전용 DDS 칩을 사용해 이러한 단점을 극복하고 더 넓은 범위를 구현했지만 회로가 더 복잡했습니다.
출력 신호 확인용으로 소형 단일 채널 오실로코프를 사용했습니다. 최종적으로 적절한 케이스에 장착해 전자 실험실의 또 다른 유용한 도구로 활용하고 있습니다.
코드
아두이노 코드 (C/C++)
#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(1000Hz), 매너드 펄스
byte k1, kn, kn1, kn2;
int drive, drive0;
void setup() {
lcd.begin(16, 2);
pinMode(9, OUTPUT);
pinMode(6, INPUT); // 버튼 입력 6 (- 펄스 주기)
pinMode(7, INPUT); // 버튼 입력 7 (+ 펄스 주기)
pinMode(13, INPUT); // 버튼 입력 13 (+ 듀티 사이클)
}
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 < 60) t = t - 10;
else if (drive < 100) t = t - 100;
else t = t - 1000;
} else drive = 0;
// 주기 증가 버튼 처리
if (kn1 == HIGH) {
drive0++;
if (drive0 < 30) t = t + 1;
else if (drive0 < 60) t = t + 10;
else if (drive0 < 100) t = t + 100;
else t = t + 1000;
} else drive0 = 0;
// 주기 제한 (최소 1μs, 최대 200000μs)
if (t == 0 || t > 300000) t = 1;
if (t > 200000 && t < 300000) t = 200000;
f = 1000000 / t; // 주파수 계산 (Hz)
k1 = k * 100 / 1024; // 듀티 사이클 백분율 계산
// 듀티 사이클 조절 버튼 (순환 방식, 스텝 16/1024)
if (kn2 == HIGH) {
k = k + 16;
if (k == 1024) k = 0;
}
// LCD에 정보 표시
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(" ");
}