こんにちは、ENGかぴです。
Seeeduino XIAOに標準搭載されているライブラリを使用しパルス波形を生成することでブザーを鳴らすことができます。ブザーを鳴らす原理が分かっていればタイマ割り込みを使用することでブザーの音程を変えながら鳴らすことができます。
今回は標準ライブラリであるtone()を使用する方法とタイマ割り込みを使用する方法の2つを紹介します。タイマ割り込みを使用する方法は、マイコンを問わず同じ考え方でブザーを鳴らすことができるため参考になると思います。
analogWrite()を使ってPWMのデューティ比を変えてブザーを鳴らす方法を下記にまとめています。
Seeeduino XIAOで動作確認したことについてリンクをまとめています。
Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方
Seeeduino XIAOでブザーを鳴らす方法
ブザーを鳴らすためには振動波形を与える必要があります。パルス波形のように出力が一定でなく振幅が上下しているような波形を与えるイメージになります。ブザーの音程はパルス波形の周波数を変更することで実現できます。
標準ライブラリを使用する方法
Seeeduino XIAOはArduinoと互換性があるため標準ライブラリが使用できます。ブザーを鳴らすために準備されているtone()関数を使用することで簡単にブザーを鳴らすことができます。
#define PIN_PULSE 8
void loop() {
tone(PIN_PULSE, 1000, 100); //8ピンにキャリア周波数1000msのパルスを100ms間出力
delay(1000);
//noTone(6); //ピンを変更する場合に必要(8ピンから6ピンに変更してブザーを鳴らす場合など)
tone(PIN_PULSE, 2000, 100);
delay(1000);
}
tone(引数1, 引数2, 引数3)において引数1にはピン番号、引数2には振動波形の周波数、引数3には振動波形を出力する期間を指定します。引数3に値を指定しない場合は出力を続ける指定となります。
実装する際の注意事項はパルス波形が出力される前にtone()関数を上書きすると状態変化によるウェイトなどによって出力されない状態になるので一度tone()を発行したら変更するまで上書きしないように実装する必要があります。実装例ではtone()発効後、delay(1000)で遅延しています。
PR:企業で求められる即戦力技術を身に付ける テックキャンプエンジニア転職
キャリア周波数の制御について

tone()関数を使用せずにSeeeduino XIAOのタイマライブラリであるTimerTC3.hを使用して割り込み設定を行い振動波形を生成します。
振動波形のデューティ比は1:1(50%)としています。デューティ比が低すぎると電圧が低下するため音が小さくなることがあります。
標準ライブラリのtone()を使用した場合はデューティ比が1:1(50%)固定となりますが、タイマライブラリによる方法はキャリア周波数を変更しながらデューディ比の変更ができます。デューティ比を変化させる場合は説明図のcntmax/2を可変することで実現できます。
#include <TimerTC3.h>
void setup() {
TimerTc3.initialize(10); //10us毎に割り込み
TimerTc3.attachInterrupt(TimerCnt); //TimerCntにコールバック
pinMode(PIN_PULSE, OUTPUT);
}
/* callback function add */
void TimerCnt(){
++cnt10us;
if( ++cnt >= cntmax ){
cnt = 0;
}
if( cnt > cnthalf ){ //MAX値の半分でDOのHとLを切り替えて振動波形を生成
digitalWrite(PIN_PULSE,LOW);
}
else{
digitalWrite(PIN_PULSE,HIGH);
}
}
TimerTc3.initialize(10)とすることで10us毎にコールバックであるTimerCnt()に遷移します。TimerCnt()では10us毎にカウントしてながら一定の値を超えるとDOの出力を切り替えています。
cntmaxを変更することでキャリア周波数を変更することができます。またcnthalfを変更することでデューディ比を変更することができます。
キャリア周波数とデューティ比を同時に変更したい場合はSeeeduino XIAOの内部のレジスタを操作する必要がありますが、簡単に使用できて動作確認ができることがArduino環境の良さであるためレジスタの操作せずとも代用できる方法としてタイマ割り込みを使う方法を選択しています。
割り込みの考え方と注意事項については下記でまとめています。
PICマイコン(PIC12F675)の割り込みの考え方と注意事項
PIC12F675を元にまとめていますが、考え方はマイコンを問わず共通なので参考になると思います。
動作確認

Seeeduino XIAOのDOを使って圧電ブザーを鳴らします。動作確認用のプログラムはタイマ割り込みを使用したものと標準関数のtone()を使用したものの2通りで確認しています。
標準ライブラリのtone()を使用する方法とタイマ割り込みを使ってブザーを鳴らす方法の動作確認は同じ回路を使用します。
ブザーはインピーダンスが高いものを使用していれば抵抗は不要ですが、短絡故障したときにマイコンに負荷がかかることから抵抗で電流制限を行っています。抵抗を大きくしすぎるとブザーの音が小さくなったり鳴らなくなるので注意が必要です。
ブザーと抵抗で分圧されることになるのでブザーに対して十分に電圧が供給できれば抵抗値であれば任意の値で問題ありませんが、短絡故障したとき0.3mAに制限したい場合は10kΩとなります。
ブザーを持続して鳴らしていると耳障りに感じたため100ms間鳴らした後900msはOFFするようにしています。
SWはブザーの音程を切り替えるために実装しています。ボタンを押したときのチャタリング防止対策をソフト内で行っています。
どちらのソフトにおいてもSWを押すことで音程が変更され「ピッ」と1秒間隔でブザーが鳴っていることが確認でき音程も同じでした。(音程がずれているかもしれませんが気にならないレベルです。)
ソースコード全体
ソースコードは記事作成時点において動作確認できていますが、使用しているライブラリの更新により動作が保証できなくなる可能性があります。また、ソースコードを使用したことによって生じた不利益などの一切の責任を負いかねます。参考資料としてお使いください。
リンクからZIPファイル形式のファイルをダウンロードし、任意の場所に展開していただくとテキストファイルが生成されます。
tone()を使用した場合のスケッチ例とタイマ割り込みを使用した場合のスケッチ例を入れています。
関連リンク
Arduinoのライブラリを使って動作確認を行ったことを下記リンクにまとめています。
Arduinoで学べるマイコンのソフト開発と標準ライブラリの使い方
Seeeduino XIAOで学べるソフト開発と標準ライブラリの使い方
ESP32-WROOM-32Eで学べるソフト開発と標準ライブラリの使い方
最後まで、読んでいただきありがとうございました。