Arduino Nanoで作る1MHz対応 矩形波発生器 ─ PWM周波数・デューティ比可変
概要
TimerOneライブラリを活用し、Arduino NanoのD9ピンから約5Hz〜1MHzの矩形波(PWM)を出力する発生器を自作します。周波数・デューティ比ともにボタンでリアルタイム調整可能、16×2 LCDでパラメータを表示します。
必要な部品
- Arduino Nano R3 ×1
- 16×2 キャラクタLCD(白文字/青背景) ×1
- タクトスイッチ ×3個
- 10kΩ 半固定抵抗(LCDコントラスト用) ×1
- プルアップ抵抗(内部プルアップ使用可)
- Arduino IDE
回路構成
- D9:PWM出力(Timer1出力ピン)
- D6:周波数ダウンボタン
- D7:周波数アップボタン
- D13:デューティ比アップボタン
- LCD:RS=D12, E=D11, D4〜D7 = D5〜D2
動作原理
Timer1の16ビットカウンタを用い、クロック分周比を固定(1/1)としてOCR1Aで周期を、OCR1Bでデューティ比を制御します。最小ステップ1μsのため、高周波側では周波数分解能が粗くなります(1μs=1MHz, 2μs=500kHz, 3μs≈333kHz…)。
ボタン操作の加速機能
長押し時間に応じて変化量を段階的に加速:
- 0〜30ループ:±1μs
- 30〜60ループ:±10μs
- 60〜100ループ:±100μs
- 100ループ以上:±1000μs
周期範囲は1μs〜200,000μs(5Hz〜1MHz)に制限。
表示内容
| 行 | 表示項目 |
|---|---|
| 1行目 | 周期 T=xxxx μs / デューティ比 xx% |
| 2行目 | 周波数 F=xxxxxx Hz |
サンプルコード
#include
#include
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
unsigned long period = 1000; // μs (初期 1kHz)
unsigned int duty = 512; // 0-1023 (50%)
int btnDec = 6, btnInc = 7, btnDuty = 13;
int holdDec = 0, holdInc = 0;
void setup() {
lcd.begin(16, 2);
pinMode(9, OUTPUT);
pinMode(btnDec, INPUT_PULLUP);
pinMode(btnInc, INPUT_PULLUP);
pinMode(btnDuty, INPUT_PULLUP);
Timer1.initialize(period);
Timer1.pwm(9, duty);
}
void loop() {
// 周波数ダウン
if (!digitalRead(btnDec)) {
holdDec++;
if (holdDec < 30) period -= 1;
else if (holdDec < 60) period -= 10;
else if (holdDec < 100) period -= 100;
else period -= 1000;
} else holdDec = 0;
// 周波数アップ
if (!digitalRead(btnInc)) {
holdInc++;
if (holdInc < 30) period += 1;
else if (holdInc < 60) period += 10;
else if (holdInc < 100) period += 100;
else period += 1000;
} else holdInc = 0;
// 範囲制限
period = constrain(period, 1, 200000);
// デューティ比調整(循環)
if (!digitalRead(btnDuty)) {
duty = (duty + 16) % 1024; // 16/1024 ≈ 1.56% ステップ
delay(50); // チャタリング防止
}
Timer1.initialize(period);
Timer1.pwm(9, duty);
// LCD表示
unsigned long freq = 1000000UL / period;
int dutyPct = duty * 100 / 1024;
lcd.setCursor(0, 0);
lcd.print("T="); lcd.print(period); lcd.print(" us");
lcd.setCursor(12, 0);
lcd.print(dutyPct); lcd.print(" %");
lcd.setCursor(0, 1);
lcd.print("F="); lcd.print(freq); lcd.print(" Hz");
delay(300);
lcd.clear();
}
実用上の注意点
- 高周波(>100kHz)ではブレッドボードの配線容量で波形が鈍るため、短い配線・グランド強化推奨
- 1MHz付近では
Timer1.initialize(1)がギリギリ動作するが、ジッタが大きい - より高精度・広帯域が必要なら、AD9833等のDDSチップ検討を
まとめ
少ない部品で手軽に作れる実験用・学習用矩形波発生器として優秀です。LCD表示付きでスタンドアロン動作し、電子工作のテスト信号源として活躍します。
製造プロセス
- 自作LUMAZOID:Arduino音楽ビジュアライザーDIYガイド
- DIY Arduinoワードクロック – 文字で時刻を表示する洗練されたリアルタイムクロック
- Arduino Nanoで20kHzオシロスコープを自作:Nokia 5110 LCD搭載・簡易DIYガイド
- Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
- JX Wave Generator – Arduino互換DDS発振器(OLEDディスプレイ搭載)
- Arduinoでシンプルな障害物センサーを自作 – IR LEDとフォトダイオード入門
- Arduino、Google Cardboard、Bluetoothで作るDIY VRスケートボード
- Arduino UNOで作るシンプル電卓 - シリアルモニターで四則演算
- Arduino Nanoとロータリーエンコーダーで作る高精度測定ホイール
- シンプルなArduinoストップウォッチ:ボタンで動作するクロノメーターの作り方
- 矩形波信号の理解:基礎と応用