PWM (mruby/c)

圧電ブザーを鳴らすプログラムの書き方

音は波であるため, 音を出したい時には電圧の HIGH と LOW を繰り返すことで, プログラム的に下記に示すような特定の周波数を持つ波 (矩形波) を作れば良い. HIGH と LOW の持続時間の和が波の周期に対応する.

なお, デューティー比は比率 (%) で与えるのではなく, 下図でいうところの「閾値」として与える.

なお, ESP32 のクロックは 80 MHz = 12.5 μs で動作するため, 分解能をそれよりも小さくすることはできない. 逆に言うと, タイマの解像度によって表現できる最大波長が決まる. 1 bit ならば 1 / (12.5e-6 * 2) = 40 MHz, 8 bit ならば 1 / (12.5e-6 * 256) = 312.5 kHz, 13 bit ならば 1 / (12.5e-6 * 8192) = 9765 Hz, である.

プロジェクトの準備

基本的に ESP-IDF 環境と同じなので, ESP-IDF 環境がインストールされているディレクトリ (ここでは $HOME/esp) 以下にプロジェクト用のディレクトリを作る. GitHub から j5_es_2020 ブランチを git clone する.

$ cd ~/esp

$ git clone https://github.com/gfd-dennou-club/iotex-esp32-mrubyc.git mrubyc-02-pwm

$ cd mrubyc-02-pwm

make menuconfig で “IoTeX ESP32 mrubyc Configuration から, LEDC のみチェックを入れる (課題を行うときは GPIO も必要になるが).

$ make menuconfig

書き方

コンストラクタ

PWM.new( pin )  # pin: GPIO pin number

周波数の設定

PWM.freq( num ) # num : 周波数

デューティー比の設定

PWM.duty( num ) # num : デューティー比. デフォルト 8 bit

圧電ブザー

mrblib/loops/master.rb に以下のように書く.

1 pwm0 = PWM.new( 15 )
2 
3 pwm0.freq(5000)
4 pwm0.duty(128)
  • 1 行目: インスタンスの作成. スピーカの接続されているピン (GPIO 15) を使う設定に.
    • クラスの定義は mrblib/models/pwm.rb
  • 3 行目: 周波数の設定
  • 4 行目: デューティー比の設定. 128 /256 = 50%
    • 現在はデフォルト 8 bit = 256.

コンパイルと実行を行う.

$ make

$ make flash monitor

課題

LED, スイッチ, ブザーを用いたプログラムを作成してみよ.

  • スイッチを入れたら音が鳴る
  • スイッチを入れると, ブザーで「ドレミファソラシド」が鳴る.
  • LED の点灯に合わせてブザーから曲が流れる.
  • その他