つれづれなる備忘録

日々の発見をあるがままに綴る

TinkercadによるArduinoシミュレーション13 ~ 圧電スピーカー

1. 圧電スピーカー

 今回は圧電素子Arduinoから信号を与えてスピーカーとして使用してみたい。圧電素子から音を鳴らすのは簡単で、デジタル出力ピンを圧電と接続し、tone(pin,f);によりpinで出力ピンを指定し、fで鳴らす音の周波数を指定するとそれに応じた矩形波が出力される。

2. フィルタ付き回路

 矩形信号をそのまま圧電に入力する場合、指定した周波数よりも本来の音よりも高い高調波の音が発生してしまう。そこでRLCのローパスフィルタを通して高調波を抑えた電圧を圧電スピーカーに入力することで、高調波の音を抑えることを考える。Tinkercad上はインダクタは"導体"と表示されているが、実際にはL成分を設定できるインダクタとなる。R(抵抗)とL(インダクタ)を直列に入れて、コンデンサを並列になるようにする。各素子の値はR=10Ω, C=20uF, L=100uHとするとカットオフ周波数が3500Hz程度となる。RLC等のフィルタの性能の計算は(サンプル)RLCローパス・フィルタ計算ツールのサイト上で実行できる。入力波形が確認できるようにオシロスコープを接続しておく。デジタル出力ピン2とフィルタ付きの圧電スピーカーを接続する。フィルタ効果を確認するため、フィルタなしの圧電スピーカーとデジタル出力ピン3を接続する。具体的には下図を参照。

圧電スピーカーへの接続
フィルター付き圧電スピーカーへの接続

3. スケッチ

以下にメロディーを圧電スピーカーから鳴らすためのスケッチを示す。まず最初にピン2からの矩形波を出力してフィルタ付きの圧電からメロディーを鳴らし、次にフィルタなしの圧電から同じメロディを鳴らして比較できるようにした。

//音階の定義
int d0=523;
int re=587;
int mi=659;
int fa=698;
int so=784;
int ra=880;
int si=988;
int d00=d0*2;
int f; //周波数
int pin; //出力ピン
int t=250; //音を鳴らす時間

//再生する音階
int ogw[]={mi,so,ra,so,mi,so,d00,d00,ra,ra,so,mi,d0,re,mi};
void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
}

// Tone信号生成
int sound(int pin,int f,int t)
{
tone(pin,f);
delay(t);
}
  
void loop()
{  
  pin=2;
  for (int i=0;i<15;i++){
  sound(pin,ogw[i],t);
  }
  noTone(pin); //Tone信号の停止(ピン2)
  delay(500);
  pin=3;
  for (int i=0;i<15;i++){
  sound(pin,ogw[i],t);
  }
  noTone(pin);//Tone信号の停止(ピン3)

}

最初に各音階の周波数を定義した。音階と周波数の関係は14 圧電スピーカを使って音を出すを参考にした。*1

メロディogw[]については音階を並べた配列という形で定義している。 出力ピンから矩形波を出力する処理はint sound(int pin,int f,int t);内に記述して、loop関数内で呼び出している。tone(pin,f);矩形波を出力するpinを指定し、fでその周波数を指定する。次にdelay(t);でt msの間矩形波を出力する。loop関数内ではまずピン2を指定し、for文ないでogw[]の音階(周波数)を一音づつ読み出して圧電に出力する。なお音を出力する長さは、Tnkercad上のシミュレーションの実行速度が実時間と一致しないので、適宜調整してt=250;としている。ピン2のフィルタ付きの圧電でメロディーを再生したら、一度noTone(pin);とすることでtone(pin,f);で出力した矩形波を停止させる。出力を停止しないと次のピンから出力できない。同様にピン3からフィルタなしの圧電でメロディを再生する。(これを繰り返す)

3. 実行結果

 結果から言うと、フィルタなしの音に比べて高い音は抑えられているものの、ノイズ音が目立つのと音の大きさが安定しないという結果だった。以下オシロスコープで観察した、フィルターある(左)なし(右)の波形の比較を示す。

フィルターありなしの波形比較
フィルターありなしの波形比較
 あくまでTinkercad上での実行の話だが、まずローパスフィルタの効果として、矩形波の高調波を抑えた結果、矩形から三角波に近い波形になっている。しかし波形の振幅が矩形波と比べて小さくなった結果、音の出力が小さくなっており、また音階(周波数)によっても変化している。ノイズ音に関しては音の大きさが小さくなって目立ってきているという印象。ただしファンクションジェネレーター(Tinkercad上では関数ジェネレータ)でサイン波を入力しても、ノイズ音は聞こえてくる。対策としては、減衰した波形の振幅が回復するようにアンプなどを用いて増幅することが考えられるが、オーディオアンプを設計する話に近くなるので、当面これ以上は追及しない。ブザーっぽい高い音を気にしなければ、今のところフィルタなしでもよい気がしている。今回のLCRフィルター以外の方法は、特に和音を出力するのに、デジタル出力ピンからPWMを使って波形を直接出力する方法がある。(電子工作勉強中: ハンディー踏切カンカンを作る(2/3):ArduinoのPWMで和音を出力PWMDAC_Synthライブラリ Wiki - OSDN参照) ただしPWMの周波数をマイコンレジストリで設定する必要があり、Tinkercad上では試していないができない可能性が高い。

4. まとめ

 Arduinoから圧電スピーカーを鳴らす方法について取り上げた。矩形波による駆動になるので、指定周波数よりも高い音も出力されてしまうので、ローパスフィルタによって高い音をカットすることを試みた。結果としては高い音は抑えられたが、音の出力が下がってしまうことと、ノイズ音が目立ってしまうということが課題として残った。

*1:より詳しくはこちら: 音階周波数