Arduino UNOで周波数とデューティサイクルを高精度測定
必要な部品と用品
| Arduino UNO | ×1 |
| 英数字LCD(20×4文字、HD44780互換) | ×1 |
必要な工具
- ブレッドボード(270ピン)
アプリとオンラインサービス
- Arduino IDE
プロジェクトについて
Arduino UNOを使ってパルス信号の周波数、ON時間、OFF時間、デューティサイクルを測定し、LCDにリアルタイム表示するシンプルで実用的な計測器です。通信分野、モーター制御(DCモーター速度/PWM、サーボ角度制御)、デジタル信号解析など幅広い用途で活用できます。
回路構成
- 入力信号: 測定対象のパルス波形をArduinoデジタルピン D7 に直接入力(5Vロジックレベル)。
- LCD接続 (4ビットモード):
- RS → D8, Enable → D9
- D4〜D7 → D10〜D13
- RW → GND(書き込み専用)
- VSS(1)・LEDカソード(16) → GND
- VDD(2)・LEDアノード(15) → 5V
- Vo(3) → 10kΩ可変抵抗の中央タップ(コントラスト調整)、両端を5V/GND
動作原理
- Arduino起動時、LCDに
Freq:,Ton:,Toff:,Duty:のラベルを各行に表示。 pulseIn(pin, HIGH)でパルスのHigh期間(Ton、マイクロ秒)を測定。pulseIn(pin, LOW)でLow期間(Toff、マイクロ秒)を測定。- 周期 = Ton + Toff、周波数 = 1,000,000 / 周期 (Hz)。
- デューティサイクル = (Ton / 周期) × 100 (%)。
- 測定値をLCDの対応行に上書き表示。1秒ごとに更新(
delay(1000))。
測定範囲と精度
pulseIn()の測定範囲: 約 10μs 〜 3分(オーバーフローで0返却)。- 実用的な周波数範囲: 約 5Hz 〜 50kHz 程度(Ton/Toff が最小パルス幅以上確保できる範囲)。
- 分解能: 1μs(16MHzクロックの
micros()ベース)。 - 精度向上のヒント: 複数回測定して平均化、入力信号のノイズ対策(シュミットトリガーIC追加等)。
ソースコード(全文)
#include <LiquidCrystal.h>
// LCDピン接続: RS=8, EN=9, D4=10, D5=11, D6=12, D7=13
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
#define PULSE_IN_PIN 7
int onTime, offTime, duty;
float freq, period;
void setup() {
pinMode(PULSE_IN_PIN, INPUT);
lcd.begin(16, 4); // 16列×4行(20×4の場合は lcd.begin(20, 4))
lcd.clear();
lcd.print("Freq:");
lcd.setCursor(0, 1);
lcd.print("Ton:");
lcd.setCursor(0, 2);
lcd.print("Toff:");
lcd.setCursor(0, 3);
lcd.print("Duty:");
}
void loop() {
// パルス幅測定(ブロッキング関数)
onTime = pulseIn(PULSE_IN_PIN, HIGH);
offTime = pulseIn(PULSE_IN_PIN, LOW);
// 周期・周波数・デューティ計算
period = onTime + offTime;
if (period > 0) {
freq = 1000000.0 / period; // Hz
duty = (onTime * 100) / period; // %
} else {
freq = 0;
duty = 0;
}
// LCD表示更新(桁数固定でチラつき防止)
lcd.setCursor(5, 0);
lcd.print(" "); // クリア
lcd.setCursor(5, 0);
lcd.print(freq);
lcd.print(" Hz");
lcd.setCursor(4, 1);
lcd.print(" ");
lcd.setCursor(4, 1);
lcd.print(onTime);
lcd.print(" us");
lcd.setCursor(5, 2);
lcd.print(" ");
lcd.setCursor(5, 2);
lcd.print(offTime);
lcd.print(" us");
lcd.setCursor(6, 3);
lcd.print(" ");
lcd.setCursor(6, 3);
lcd.print(duty);
lcd.print("%");
delay(1000); // 1秒ごとに更新
}
回路図
シンプルな2部品構成。パルス信号源(ファンクションジェネレーター、555タイマー回路、マイコンPWM出力等)をD7に接続。LCDは標準的な4ビットモード配線。可変抵抗でコントラスト調整可能。
応用・拡張アイデア
- データロガー化: SDカードシールドを追加し、タイムスタンプ付きでCSV保存。
- シリアルプロッター対応:
Serial.print() で値を出力し、Arduino IDEのシリアルプロッターで波形表示。
- デューティサイクル精度向上:
pulseIn() はブロッキングで割り込み無効化するため、高周波では誤差大。Timer1の入力キャプチャ機能(ICP1ピン=D8)を使えばハードウェアレベルで高精度測定可能。
- 電圧測定追加: アナログピンでピーク電圧も同時測定。
Serial.print() で値を出力し、Arduino IDEのシリアルプロッターで波形表示。pulseIn() はブロッキングで割り込み無効化するため、高周波では誤差大。Timer1の入力キャプチャ機能(ICP1ピン=D8)を使えばハードウェアレベルで高精度測定可能。製造プロセス
- Python連携で信頼性向上: Arduino RFID勤怠管理システム
- Arduinoと1Sheeldで作る万能Androidリモコン──IR制御で家電を一括操作
- Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
- ESP8266・Arduino・超音波センサーで作るスマートIoTジャー:リアルタイム中身監視
- Arduino UNOで周波数とデューティサイクルを高精度測定
- FirmataとXbox OneコントローラーでArduinoローバーをシームレス操作
- Arduinoで地球の質量を測定:ステップバイステップDIYガイド
- Arduino超音波センサーとProcessingで作るリアルタイム距離測定ソナー
- Bolt IoTとArduino UNOでLED輝度をシームレス制御
- ArduinoとProcessingで作るリアルタイムデジタルコンパス
- AC電力システムにおける周波数と位相の測定