RaspberryPi Zero W で PWM audio

はじめに

以前カムロボを PWM で無理やり R2D2 っぽく喋らせるということをやってみたが,これは単純な PWM 出力をそのままスピーカーへ出力していた.

今回はもう少しまともな音声を再生できるように PWM audio を設定してみる.

調査

御託はすっ飛ばしてとにかく設定方法を教えてくれという人は次のセクションに飛んでどうぞ.

RPI Model B 系の音声出力方法は HDMI か 3.5mm ジャックのアナログ出力の 2 択だったが,RPI Zero では 3.5mm ジャックが実装されていない.RPI Zeroで音声を再生する方法はいくつかあるが,簡単な順で選択肢は概ねこんなところ.

  1. HDMI 接続先から音声出力する
  2. USB で DAC を使う
  3. HAT で DAC を使う
  4. ノイズ除去フィルタを用意して,PWM Audio を設定する

HDMI 出力は一番簡単な音声出力方法.RPI をデスクトップ PC のように利用する場合は,ディスプレイから音声出力すればいい.しかし,小型の LCD や OLED などの HDMI 接続以外の表示器を使う場合はこの手段は使えない.

USB DAC は通常の USB デバイスとして扱えるので,これも比較的簡単に音声出力を実現できる.ただし,RPI Zero では microUSB ポートが 1 つしかない.昨今流通している USB DAC は Type-A か Type-C なので microUSB に合わせてアダプターが必要になる.他の用途で USB を利用する場合はハブも必要になってくる.せっかくコンパクトなRPI Zeroの周りがごちゃごちゃするのは頂けない.ちなみにアダプターはめちゃくちゃ小さくて安価なこれがおすすめ.

https://amzn.to/3h45cnE

HAT DAC は RaspberryPi.com でもいくつか紹介されているが,RPI Zero ザイズの HAT は Codec Zero として紹介されている./boot/config.txt の設定変更や制御ソフトの導入の手間はあるが,比較的簡単に 3.5mm ジャックを追加できる.ただし,他の HAT も使用したい場合は配線が面倒なことになるかもしれない.Amazon で HAT DAC 買うならこんなところか.1000 円前後と値段的には USB DAC と同じくらい.

Amazon.co.jp

そして問題の PWM Audio.よく参照されている Adafruit のページでは,2 種類の方法が紹介されている.1 つは DTO(Device Tree Overlay) で PWM 出力ピンを設定する方法.もう 1 つは wiringPi を使って手動で PWM 出力ピンを設定する方法.wiringPi の方は試してないが,DTO の方はこの説明の通り /boot/config.txt を設定しても音声出力デバイスとしてに認識されなかった.これに関しては後述の解決策が見つかったので良いとして,このまま GPIO の出力をスピーカーにつなぐとノイズだらけで大変なことになる.自前でフィルタ回路も用意する必要がある.必要に応じてアンプも用意する必要がある.

Adding Basic Audio Ouput to Raspberry Pi Zero
To keep the Raspberry Pi Zero as low cost and small as possible, the Pi foundation didn't include a 3.5mm audio jack. Th...
https://amzn.to/3WAFCa3

PWM audio 設定

環境は次の通り.

$ cat /etc/os-release 
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
$ uname -r
5.15.61+
$ cat  /sys/firmware/devicetree/base/model 
Raspberry Pi Zero W Rev 1.1

config.txt 設定

config.txt の末尾に次の行を追加して再起動する.

dtoverlay=audremap,pins_12_13

ちなみに設定内容は次の通り.Adafruit の説明では pwm-2chan を設定するよう記載されている.pwm-2chan を設定するとたしかに GPIO の PWM 出力ピンとして設定されるが,音声出力デバイスとして alsa が認識できない.

Name:   audremap
Info:   Switches PWM sound output to GPIOs on the 40-pin header
Load:   dtoverlay=audremap,<param>=<val>
Params: swap_lr                 Reverse the channel allocation, which will also
                                swap the audio jack outputs (default off)
        enable_jack             Don't switch off the audio jack output
                                (default off)
        pins_12_13              Select GPIOs 12 & 13 (default)
        pins_18_19              Select GPIOs 18 & 19

Name:   pwm-2chan
Info:   Configures both PWM channels
        Legal pin,function combinations for each channel:
          PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0)            52,5(Alt1)
          PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1)
        N.B.:
          1) Pin 18 is the only one available on all platforms, and
             it is the one used by the I2S audio interface.
             Pins 12 and 13 might be better choices on an A+, B+ or Pi2.
          2) The onboard analogue audio output uses both PWM channels.
          3) So be careful mixing audio and PWM.
          4) Currently the clock must have been enabled and configured
             by other means.
Load:   dtoverlay=pwm-2chan,<param>=<val>
Params: pin                     Output pin (default 18) - see table
        pin2                    Output pin for other channel (default 19)
        func                    Pin function (default 2 = Alt5) - see above
        func2                   Function for pin2 (default 2 = Alt5)
        clock                   PWM clock frequency (informational)

再起動後は出力デバイスとして認識されるので,~/.asoundrc で出力先として設定する.

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 2: vc4hdmi [vc4-hdmi], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
$ cat .asoundrc
pcm.!default {
  type asym
  playback.pcm {
    type plug
    slave.pcm "output"
  }
  capture.pcm {
    type plug
    slave.pcm "input"
  }
}

pcm.output {
  type hw
  card 0  # 出力先に card 0 を指定
}

ctl.!default {
  type hw
  card 0
}

この状態でスピーカーに接続すれば,一応音声が出力できるがノイズがひどい.試したい方はこちらをどうぞ.

# どちらでもどうぞ
$ aplay /usr/share/sounds/alsa/Front_Center.wav
$ speaker-test -t sine -p 32

音鳴らした後はチュルチュル音が鳴り止まなくてつらい.

フィルタ回路作成

このままだとノイズがひどいので次のページを参考に RC フィルタを作る.

Introducing the Raspberry Pi Zero
Wow a new Pi - so exciting! The Pi Zero is the smallest, most affordable Pi ever. Wonder what's new & different? Let's c...

必要なものは次の通り.L か R の片方だけでいいなら部品数は半分で済む.

  • 抵抗 150Ω 2個
  • 抵抗 270Ω 2個
  • コンデンサ 33nF 2個
  • コンデンサ 10uF 2個

実態配線図は次の通り.

フィルタの効果はこんな感じ.よく聞けばまだ完全にノイズは消えてないが,実用レベルで問題なし.

おわりに

思いの外簡単に実装できた.Adafruit のページを見て挫折していた人は参考にどうぞ.

抵抗 2 つとコンデンサ 2 つ程度ならまだカムロボの頭に入りそう.

References

コメント

タイトルとURLをコピーしました