チラシのうら

レゴとか、工作とか。

8pinoで圧電スピーカーを鳴らす その2

前回の投稿で

せっかくスピーカーが2つあるわけですし、8pinoのポートもまだ空きがあるので、2つ同時出力や和音が出来ないか、トライしてみます。

なんて気軽に発言してしまったことを、大変後悔しております。 まさか、土日の自由時間の大半を食い潰すとは、夢にも思いませんでした…

今回の目的

さて、今回は、8pinoと2つの圧電スピーカーを使って、「カエルの合唱」とか「静かな湖畔」あたりを1人輪唱させたいです。

まずは、結線。

前回の奴にスピーカーを一個追加するだけです。 f:id:tetunori_lego:20150525065042j:plain

前例探し

意外にも、どれだけ検索しても、2つのブザーを使って何かやってるものは見当たりませんでした。
自分でソリューションを考えださなくてはいけません。

アプローチ1 → 失敗

前の投稿 で使ったTrinketToneを改造して、2つのピンに対して波形の出力が出来ないか試しました。

ATTiny85のデータシート
を合わせて見ると、TrinketToneはPin番号1(正確にはOC1A)固定の実装になっているので、他のPin(今回はOC1B)の方でも同じようにできるかやってみました。

結果

  • 別のPinからでも、TrinketToneが動く様になった!
  • 2つ同時に鳴らそうとすると、何も音が出てこなくなる…

というのも、良く良くみると、TrinketToneのロジックは、Pin番号と関係ないレジスタ、TCCRを使っており、この人が双方からアクセスされることで、不整合が起きていると思われます。(予想)

時間的にも、精神的にも深手を負ってしまったので、このアプローチは諦めます…

アプローチ2 → 失敗

Trinketのサンプルコードにあるように、GPIO H/Lを自力でパタパタさせて音を出す方法(例↓)を工夫できないか?

void loop() {
   digitalWrite(speakerPin, HIGH);
   delayMicroseconds(1000);
   digitalWrite(speakerPin, LOW);
   delayMicroseconds(1000);
}

具体的には、数usec(欲しい和音の周波数の最大公約数的な数)のdelayを入れて、各PinをH/Lにするべきか否かを判定する

結果

ぶつぶつとノイズしかでてこない。

1usecで起きた時の処理時間あるから、出力波形乱れるのかなぁ。 もう、デバッグする気力はありません…

アプローチ3 → 成功?

arduinoのPWM

pulse width modulation : Pinから、指定した通りの波形を出力し続けてくれる機能。LEDの明るさを可変にする時とかに使う。と研修で習った。

を使って圧電スピーカー鳴らしている人がいました。
これを改変出来ないだろうか?

まずは原理確認するために、上記で実装されている踏切音コードを8pino向けにポーティングしてみます。

んー、なんか、参照先の動画に比べて、音がおかしい気がするけど、出来た。音が鳴ってはいる。

PWMを使う方式で、深堀してみます。

午前の部、終わり

失敗が続くと、かなり体力を使います。 夕方から、予定があるので、それまでにアウトプット出したい…