Help us understand the problem. What is going on with this article?

耳年齢を1才単位で判定するLINE Botを作った

はじめに

年を取ると高い周波数が聞こえにくくなる耳年齢なるものがあるそうです。自分の耳年齢が知りたくなったので計測機を作りました。

作ったもの

登録した周波数に応じて、スピーカーから0.5秒ほど音が鳴り、耳年齢を1才単位で教えてくれます。(↓クリックでYouTubeに飛びます)

耳年齢を細かく教えてくれるLINE Bot

試したところ、15640Hzまで聞こえた私の耳年齢は34才と判定されました。

構成

こんなの作りました。

image.png

obnizを使い、LINE Botとスピーカーを付けたIoTデバイスを連携しました。これでLINEに投稿した値に応じた音がスピーカーから鳴ります。(nodejsのバージョンは、v12.11.0です)

IoT機器の情報は以下になります。
obnizボード
圧電スピーカー

耳年齢を算出する計算式を考える

耳年齢を1才単位で表示するため、周波数と耳年齢の対応表を探したのですが、見つからないので、作りました。単回帰分析を使い、周波数から耳年齢を算出する計算式をエクセルでサクッと作れます。

まずは、こちらのサイト から以下の情報を頂きました。

周波数 年齢
10000Hz 60代の方まで聞こえるレベル
12000Hz 50代の方まで聞こえるレベル
14000Hz 40代の方まで聞こえるレベル
15000Hz 30代の方まで聞こえるレベル
16000Hz 20代の方まで聞こえるレベル

取得した情報をエクセルに入力します。
image.png

入力した情報で散布図を描きます。
image.png

プロットされた値を右クリックし、近似曲線を追加します。
image.png

近似曲線のオプションからグラフに数式を表示するにチェックを入れると、近似曲線の数式が表示されます。これで、周波数から耳年齢を算出する数式ができました。

image.png

y= -0.0065x + 135.64
この数式で耳年齢を算出できるようになりました。この直線は単回帰分析という機械学習の手法の1つになります。

試しに耳年齢を算出してみます。

周波数 算出した耳年齢
10000 71
11000 64
14500 41
15663 34
15878 32

それっぽい耳年齢が算出できるようになりました。

スクリプト

LINE Botとobnizに連携したNodejsのスクリプトです。これは、n0bisukeさんのQiita記事を参考にしました。

linebot-speaker.js
'use strict';

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

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

// Obnizの準備
var Obniz = require("obniz");
var obniz = new Obniz("");  // Obniz ID を入力
var speaker; // 全体で使えるようにするスコープ
obniz.onconnect = async function () {
    speaker = obniz.wired("Speaker", {signal:0, gnd:1});
}

const app = express();

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);

    //ここのif分はdeveloper consoleの"接続確認"用なので削除して問題ないです。
    if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){
        res.send('Hello LINE BOT!(POST)');
        console.log('疎通確認用');
        return; 
    }

    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

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

  var hz = Number(event.message.text);
  speaker.play(hz);
  obniz.wait(500);
  speaker.play(0);

  let hantei = Number(event.message.text);
  hantei = Math.round(-0.0065 * hantei + 135.64); //耳年齢を算出
  let retnMsg = event.message.text;

  retnMsg += "Hz(ヘルツ)が聞こえたら、耳年齢は" + hantei + "才以下です";

  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: retnMsg //実際に返信の言葉を入れる箇所
  });
}

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

余談

  • 何回も聞いてると聞こえなかった16000Hzも聞こえ耳年齢が2才若返りました。耳の老化防止にも使えそうです。

  • 作成した数式は、周波数 10000Hz~16000Hzの範囲でのみ、それっぽい耳年齢を算出します。

image.png

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした