M5Stackで
静かに音を鳴らす
3つの方法

Shinya Ishikawa

@meganetaaan

https://github.com/meganetaaan/m5stack-avatar

  • 二児の父
  • SIerでR&Dをしている
  • 普段はWeb(主にフロント)の人
  • Arduino歴3ヶ月

インタラクティブに
音が鳴る
→こどもよろこぶ

テルミン風楽器作ってみた

https://github.com/meganetaaan/m5stack-theremin

  • M5Stack + 超音波センサー
  • 手を近づけると高い音

こどもが寝たあとで

こっそり練習して
曲を披露しよう!

鳴り響く爆音

寝る子も泣き出すM5Stack

静音化するしかない

方法①:原始的解決策

←ガムテープ

結果:意外と◯

方法②:ハード的制御

M5Stackの音量を抵抗1つで調節する | N.Yamazaki's blog

http://blog-yama.a-quest.com/?eid=970193

結果:未検証

抵抗落としそう&こどもが食べそうで怖い…

方法③:ソフト的制御

ソフト的制御?

// 現在 M5.Speaker.playMusic()でのみ有効
// https://github.com/m5stack/M5Stack/blob/master/src/utility/Speaker.cpp

M5.Speaker.setVolume(1);

候補a) Speaker.setVolume ... Speaker.toneには効かない

候補b) MQTTを使う

Wait, what?

MQTT??

MQTT!

MQTT

Broker

MQTT

Client

(Sub)

MQTT

Client

(Pub)

frequency: 440.0

  • M5Stackの代わりにPCで音を出す
    • PC側で音量調節するなりヘッドホン挿すなりできる
  • Speaker.toneの代わりに周波数の情報をMQTTで飛ばす

MQTT Broker

Client

(Pub)

Broker

Client

(Sub)

const mosca = require('mosca')
const ascoltatore = {
  //using ascoltatore
  type: 'mongo',
  url: 'mongodb://localhost:27017/mqtt',
  pubsubCollection: 'ascoltatori',
  mongo: {}
}

const settings = {
  port: 1883,
  backend: ascoltatore,
  http: {
    port: 8080,
    bundle: true,
    static: './public'
  }
}

const server = new mosca.Server(settings)
$ npm init -y
$ npm install -S mosca
  • Moscaを使用
    • Node.js製
      MQTTブローカー
  • ほぼデフォルト設定

https://github.com/mcollina/mosca

MQTTClient(Pub)

Client

(Pub)

Broker

Client

(Sub)

#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <M5Stack.h>
#include "const.h"

WiFiClient httpsClient;
PubSubClient mqttClient(httpsClient);
boolean isPub = true;

void setup()
{
  M5.begin();
  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);
  M5.Speaker.setVolume(1);
  M5.Speaker.update();
  setupWifi();
}

// 中略

void loop()
{
  M5.update();
  updateEcho();
  Duration = pulseIn(echoPin, HIGH);  //センサからの入力
  if (Duration > 0)
  {
    Distance = getDistance(Duration); // 反応時間から距離を計算
    float f = getNote(Distance);      // 距離から音程を計算
    if (isPub)
    {
        publishFreq(f);
    }
    else
    {
        M5.Speaker.tone(f);
    }
  }
  delay(125);
}
  • 超音波センサーから
    距離を取得
  • MQTTで飛ばす

※https://www.1ft-seabass.jp/memo/2018/05/10/​m5stack-meets-nodered-with-mqtt/

MQTTClient(Sub)

const mosca = require('mosca')
const ascoltatore = {
  //using ascoltatore
  type: 'mongo',
  url: 'mongodb://localhost:27017/mqtt',
  pubsubCollection: 'ascoltatori',
  mongo: {}
}

const settings = {
  port: 1883,
  backend: ascoltatore,
  http: {
    port: 8080,
    bundle: true,
    static: './public'
  }
}

const server = new mosca.Server(settings)
  • M5Stackからの
    メッセージを受けて
    音を出す
  • Web Audio APIを利用 

Client

(Pub)

Broker

Client

(Sub)

https://www.html5rocks.com/ja/tutorials/webaudio/intro/

DEMO

所感

  • MQTT、思っていたより簡単に始められる
  • 非インターネット環境でも、サーバ使って
    PC、スマホに処理を移譲するの良さそう
    • M5Cloud、M5GOのWiFi設定
    • M5Stackを入力デバイスとして使う