パッシブブザーをPWM制御して電子オルゴールをつくる
先日、Raspberry Pi 4 Model BでパッシブブザーをPWM制御して電子オルゴールをつくった。今回はその回路を流用してAuduinoでも電子オルゴールを鳴らしてみたので、回路図やコードを載せておく。ちなみに以下が鳴らしてみた様子。曲はラズパイの時とおなじく「子犬のマーチ」。
ラズパイの回路を流用して、今度はパッシブブザー + ArduinoでPWM制御して電子オルゴール。PWMの周波数はATmegaのレジスタ直接叩いて変えたのでラズパイの時よりややめんどかった #Arduino #電子工作 pic.twitter.com/VG4sfNwlg1
— Wakky (@wakky_free) May 22, 2022
GPIOの電圧がラズパイは3.3V、Arduinoは5Vという違いはあるが、作成した電子オルゴールの回路ではどちらでも問題ない。ちなみに部品は全てRaspberry Piのキットについてきたものを使っている。
部品の使い方や内容についてはSunfounder社のWebサイトに書いてある。(ちょっと色々内容が怪しいところはあるが…)
開発環境
Arduino Uno R3
Windows 10(開発用PC)
Arduino IDE 1.8.19
ブレッドボードに回路をつくる
回路図は以下の通り。といっても基本的には先日の回路のRaspberry PiをArduinoに変えただけ。今回はGPIOのD9ピンをパッシブブザーと接続して、PWM制御して周波数を変えることで音楽を鳴らす。また、ボタン(タクトスイッチ)はD2ピンと接続しているが、D2ピンの内部で5Vにプルアップしているのでプルアップ/プルダウン抵抗はつけていない。。
ブレッドボードに接続してみたのが以下の図。
以下が実際に繋いでみた写真。
電子オルゴールのプログラムを書いて実行する
ラズパイだとPythonのライブラリでサクッとPWM制御の周波数を設定したのだが、Arduinoの場合はPWM制御の周波数を任意に設定するときはマイコン(ATmega328)のレジスタ設定を直接変える方法が一般的らしい。
ネットを調べると色々と文献があるのだが、以下のサイトのコードがシンプルでわかりやすかったので参考にさせて頂いたm(_ _)m
Arduino Uno – PWM周波数を”自由に”変更する
実際に作成したコードがこちら。ボタンを押してブザーを鳴らすコードについてはラズパイの時に書いたPythonのコードと内容的には同じ。PWM制御について、上のサイトではGPIOのD10ピンを使用しているが、私はD9ピンを使用しているので設定先のレジスタが異なる。
#include <avr/io.h> int pwm_pin = 9; int button_pin = 2; unsigned int c_freq = 262; unsigned int d_freq = 294; unsigned int e_freq = 330; unsigned int f_freq = 349; unsigned int g_freq = 392; float duty = 0.1; void setup() { pinMode(pwm_pin, OUTPUT); pinMode(button_pin, INPUT_PULLUP); TCCR1A = 0b10000000; TCCR1B = 0b00010010; } void buzzer(unsigned int freq, int t){ ICR1 = (unsigned int)(1000000 / freq); OCR1A = (unsigned int)(1000000 / freq * duty); delay(t); } void buzzer_short(unsigned int freq, int t){ ICR1 = (unsigned int)(1000000 / freq); OCR1A = (unsigned int)(1000000 / freq * duty); delay(100); OCR1A = 0; delay(t - 100); } void loop() { if(digitalRead(button_pin) == LOW) { // Bee March buzzer(e_freq, 500); buzzer(c_freq, 500); buzzer(e_freq, 500); buzzer(c_freq, 500); buzzer(e_freq, 500); buzzer_short(g_freq, 500); buzzer(g_freq, 1000); buzzer(f_freq, 500); buzzer_short(d_freq, 500); buzzer(d_freq, 1000); buzzer(e_freq, 500); buzzer_short(c_freq, 500); buzzer(c_freq, 1000); buzzer(e_freq, 500); buzzer(c_freq, 500); buzzer(e_freq, 500); buzzer(c_freq, 500); buzzer(e_freq, 500); buzzer_short(g_freq, 500); buzzer(g_freq, 1000); buzzer(f_freq, 500); buzzer_short(d_freq, 500); buzzer_short(d_freq, 500); buzzer_short(d_freq, 500); buzzer(c_freq, 500); buzzer(e_freq, 500); buzzer(c_freq, 500); } OCR1A = 0; }
GPIOの入力、出力の使い方についてはざっくり理解することができた。ブザーはある程度遊びつくしたかな~という感じなので、次回はまた違う部品を使って遊んでみたいと思う。
日記まとめ
Arduinoで遊んでみた軌跡を以下でまとめてます。