9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LINEでメッセージを送ると メロディを奏でるBOT【IoT連携】【LINE BOT】

Last updated at Posted at 2020-04-10

LINEでメッセージを送ると メロディを奏でるBOTを作成してみました。

BOTの名前は音符(ONPU)とPUSHをもじって、
"ON-PUSH"にしました。
image.png

現時点ではバッテリーが備わっていない点、Wi-Fi環境下でないと起動できない点はありますが、よくスマホ等のモノを家でどこに置いたか分からなくなることがあるので、これで好きな曲で探すことができます。

今回は、『きらきら星』の曲を鳴らしています。

##環境

  • Windows 10
  • Node.js 12.16.1

##必要なもの
obniz Boardの購入が必要です。
image.png

スピーカーの購入が必要です。
(30円で購入できました)
image.png

##事前準備
obniz公式サイトを参考にWi-Fi設定、簡易プログラムのテストをします
なお、今回使用していませんが、obnizにはノンコーディングでも設計・動作可能な機能があります。

obnizにspeakerを差し込みます。(このspeakerには+-はないので差し込むのみ)
image.png

##BOTの動き
obnizとspeakerは音の周波数を指定することでその音階を鳴らすことができるので、
音階の周波数を参考に『きらきら星』の音符に対応する周波数をコーディングしています。
そのままコーディングすると音がつながって聞こえるため、stop命令で音の区切りを入れています。

画像
image.png

実際の動き(音あり)

##コード

'use strict';

// obniz呼び出し
const Obniz = require('obniz');
const obniz = new Obniz("hogehoge1");  // Obniz_ID に自分のIDを入れます

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios');
const PORT = process.env.PORT || 3000;

const config = {
    channelAccessToken: 'hogehoge2',
    channelSecret: 'hogehoge3'
};

const app = express();

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

// obniz接続
obniz.onconnect = async function () {
  obniz.display.clear();
  obniz.display.print("obniz meets LINE Bot!");
}

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  let mes = ''
  if(event.message.text === '音を鳴らして!'){
    mes = '少々お待ちください'; //待ってねってメッセージだけ先に処理
    getAskObnizSpeaker(event.source.userId); //スクレイピング処理が終わったらプッシュメッセージ
  }else{
    mes = event.message.text;
  }

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: mes
  });
}

const getAskObnizSpeaker = async (userId) => {
 // スピーカーを呼び出す
 const speaker = obniz.wired("Speaker", {signal:0, gnd:1});
 console.log("Speaker")
 await client.pushMessage(userId, {
  type: 'text',
  text: "音を鳴らしています",
});

 // 音階とhzの参考サイト https://tomari.org/main/java/oto.html
 await speaker.play(523.251); // C5 ド
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(523.251); // C5 ド
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(880.000); // C5 ラ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(880.000); // C5 ラ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(1600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(698.456); // C5 ファ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(698.456); // C5 ファ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(659.255); // C5 ミ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(659.255); // C5 ミ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(587.330); // C5 レ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(587.330); // C5 レ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(523.251); // C5 ド
 await obniz.wait(1600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(698.456); // C5 ファ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(698.456); // C5 ファ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(659.255); // C5 ミ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(659.255); // C5 ミ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(587.330); // C5 レ
 await obniz.wait(1600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(698.456); // C5 ファ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(698.456); // C5 ファ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(659.255); // C5 ミ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(659.255); // C5 ミ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(587.330); // C5 レ
 await obniz.wait(1600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(523.251); // C5 ド
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(523.251); // C5 ド
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(880.000); // C5 ラ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(880.000); // C5 ラ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(783.991); // C5 ソ
 await obniz.wait(1600);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(698.456); // C5 ファ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(698.456); // C5 ファ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(659.255); // C5 ミ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(659.255); // C5 ミ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(587.330); // C5 レ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(587.330); // C5 レ
 await obniz.wait(800);
 await speaker.stop();
 await obniz.wait(100);
 await speaker.play(523.251); // C5 ド
 await obniz.wait(1600);
 speaker.stop();
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);

以下の部分はご自身のObniz_IDとLINE BOTの情報で更新します。
※Obniz_IDは、Wi-Fi接続が完了するとobniz画面に表示されるものです。

var obniz = new Obniz("hogehoge1"); // Obniz_ID に自分のIDを入れます
const config = {
channelAccessToken: 'hogehoge2',
channelSecret: 'hogehoge3'

##終わりに
・自身で音の調整をしながら設定するのは単純に楽しかったです。
・最近は画像認識技術も向上しているので、紙ベースの楽譜(五線譜と音符)を自動で読み取り、音階から周波数の値に変換して、自動で奏でるサービスがあれば面白そうだなと思いました。

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?