このところM5ATOMLite側からNodeREDサーバーに「報告」するばかりで、逆方向のアクションがありません。そこでATOMLiteにPassive Buzzerを取り付けてみました。サーバーからブザーを鳴らせば「注意喚起」(何の?)が出来ると。今回はPWM駆動でブザーを鳴らすところまで。
※「MicroPython的午睡」投稿順 Indexはこちら
(今回実験に使用したMicroPythonスクリプト全文を末尾に掲載しました。実験は、M5Stack社のESP32搭載小型デバイス、M5ATOMLiteにMicroPython ESP32用genericポートを搭載して行っています。)
「遊休」Passive BuzzerボードをM5ATOMLiteに取り付け
本シリーズ第23回で、ラズパイPicoにPassive Buzzerを取り付けていたのです。そのときにPassive Buzzerを駆動するための小ボードをこさえてありました。とっくの昔にラズパイPicoから取り外して「遊休」状態にあったものを今回発掘してATOMLiteに取り付けました。既に、BMP280、DHT11、CdSセルといろいろ接続されていますが、まだ、使っていない端子が残っています。今回は、
G19端子
をPassive Buzzerに割り当てることにいたしました。取り付けた様子が冒頭のアイキャッチ画像にございます。左下の緑色のボードの右上に載っている黒い丸がPassive Buzzerであります。
全体回路を掲載するとうるさくなりすぎるのでPassive Buzzer周りを切り取ったものが以下です。
3.3V駆動では十分な音量にならないので5Vで駆動とし、外部のNch MOSFETで電流を引いています。
Passive Buzzerの駆動波形はPWM生成
Passive Buzzerは、自ら鳴ったりしないので、「音として鳴る」波形を加えてやらないとなりません。ONにすれば勝手に鳴るActive Buzzerもありますが今回は使ってません(両タイプの比較はこちら。)
何といってもお手軽な波形生成はPWM(パルス幅変調)駆動です。MicroPython(ESP32 generic)上でのPWM制御については以下のページの「PWM (パルス幅変調)」に説明があります。
見ると、以前にやってみているラズパイPicoとは、微妙に異なっていますが「似たようなもん」です。問題ない(何が。)
ESP32の場合、どの端子でもPWM出力が可能、PWMに使うタイマ数等の制約から同時に使える周波数は8種が上限のようです。端子数の限られたATOMLiteの場合は十分だね。
作製したブザーを鳴らすためのスクリプトは、後でNode-REDとの通信のための上位スクリプトから呼び出すことを考えて、例の如くATOMLite上のローカルファイルシステム内のlibディレクトリに LiteBUZ.py というお名前でストアしてあります(末尾のもの。)
これで上位スクリプトからも呼び出しOKの筈(ホントか。)
動作確認
作製したスクリプトを単独で起動すれば、以下の動作を行いました。
-
- 440Hz、デューティ50%のPWM駆動
- 約5秒鳴って約5秒停止を繰り返す
鳴ることは確認できたので、次回はNodeREDとの接続だね。
MicroPython的午睡(55) ATOMLite、NodeREDにCdSセル結果報告 へ戻る
MicroPython的午睡(57) ATOMLite、NodeREDからブザーを制御 へ進む
実験に使用したMicroPythonスクリプト全文 (LiteBUZ.py)
from machine import Pin, PWM import time class LiteBUZ: """Passive Buzzer Driver (Pin19) """ def __init__(self): self.buzzer = None self.pin = Pin(19) self.freq = 440 self.duty = 512 # Range: 0-1023 self.stat = 0 # 0=OFF, 1=ON def start(self): self.buzzer = PWM(self.pin, freq=self.freq, duty=self.duty) self.stat = 1 def stop(self): if self.buzzer is not None: self.buzzer.deinit() self.stat = 0 self.buzzer = None def main(): buz = LiteBUZ() while True: buz.start() time.sleep(5) buz.stop() time.sleep(5) if __name__ == "__main__": main()