MicroPython的午睡(56) ATOMLite、パッシブ・ブザー接続

Joseph Halfmoon

このところ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周りを切り取ったものが以下です。

PassiveBuzzerSchematic
3.3V駆動では十分な音量にならないので5Vで駆動とし、外部のNch MOSFETで電流を引いています。

Passive Buzzerの駆動波形はPWM生成

Passive Buzzerは、自ら鳴ったりしないので、「音として鳴る」波形を加えてやらないとなりません。ONにすれば勝手に鳴るActive Buzzerもありますが今回は使ってません(両タイプの比較はこちら。)

何といってもお手軽な波形生成はPWM(パルス幅変調)駆動です。MicroPython(ESP32 generic)上でのPWM制御については以下のページの「PWM (パルス幅変調)」に説明があります。

ESP32 用クイックリファレンス

見ると、以前にやってみているラズパイ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()