遅刻常連のへっぽこまるこです。
その名に恥じぬへっぽこぶりで申し訳ございません。
Obniz Advent Calendar 2018 13日目、、、でした、、、
※LEDが結構強めに光っているので閲覧にはご注意ください
##概要
obnizでgoogle-home-notifierを使ってgoogle home miniから音源を再生します。
それに連動して下唇に仕込んだサーボモータが動かして、
歌ってる感じにします。
Macでnode.jsがインストールされている前提で書きます。
##材料
- obniz
- sg90
- LED(既にランダムに光るプログラムが書き込まれてるやつ)
- ジャンパワイヤー
- 本当は抵抗もあったほうがよい
- 切ないクリスマスソングの音源
- ダンボールや生地やら両面テープやら(サンタデバイス用)
##サンタデバイス準備
サンタデバイス(?)はこちらのブログで乗せてもらったのを流用します。
##ディレクトリやらライブラリやら準備
$ mkdir santa && cd $_ //ディレクトリ作成&移動
$ npm install google-home-notifier
$ npm install obniz
$ touch face.js //メインのプログラムファイル
$ mkdir audio //音源格納用
audioフォルダには音源のkurisumasusong.mp3を置いておきます。
##音源準備
音源にはMP3に録音したものを使っています。
google-home-notifierでMP3を再生するには
ファイルのURLが必要になります。
今回は、こないだハンズオンで教えていただいたngrokとpythonを使った
ホスティングでURLを準備しました。
※santaディレクトリ配下で実行
##くそプログラム
(恥を忍んであげます・・async awaitよくわかってないです・・)
const googlehome = require('google-home-notifier');
const language = 'ja';
const Obniz = require("obniz");
const obniz = new Obniz("××××-××××");
obniz.onconnect = async function () {
var mouth = obniz.wired("ServoMotor", {signal:0, vcc:1, gnd:2});
var leftLed = obniz.wired("LED", { anode:3, cathode:4 });
var rigthLed = obniz.wired("LED", { anode:5, cathode:6 });
mouthMove = async function (maxDeg, maxDegWait, minDeg, minDegWait) {
console.log(">>> mouthMove start");
await mouth.angle(maxDeg);
await obniz.wait(maxDegWait);
await mouth.angle(minDeg);
await obniz.wait(minDegWait);
}
singMouth = async function () {
console.log(">>> singMouth start");
//init
await mouthMove(0.0, 1300, 0.0, 0);
//く
await mouthMove(40.0, 400, 0.0, 100);
//り
await mouthMove(40.0, 400, 0.0, 100);
//す
await mouthMove(40.0, 400, 0.0, 100);
//ま
await mouthMove(30.0, 80, 0.0, 100);
//す
await mouthMove(30.0, 80, 0.0, 100);
//きゃ
await mouthMove(50.0, 100, 0.0, 100);
//ろ
await mouthMove(30.0, 100, 0.0, 100);
//る
await mouthMove(30.0, 120, 0.0, 100);
//が
await mouthMove(40.0, 900, 0.0, 500);
//な
await mouthMove(40.0, 400, 0.0, 100);
//が
await mouthMove(40.0, 400, 0.0, 100);
//れ
await mouthMove(40.0, 400, 0.0, 100);
//る
await mouthMove(40.0, 400, 0.0, 100);
//こ
await mouthMove(40.0, 100, 0.0, 100);
//ろ
await mouthMove(40.0, 100, 0.0, 100);
//に
await mouthMove(40.0, 100, 0.0, 100);
//は
await mouthMove(50.0, 1300, 0.0, 500);
//き
await mouthMove(40.0, 100, 0.0, 100);
//い
await mouthMove(40.0, 100, 0.0, 100);
//と
await mouthMove(40.0, 200, 0.0, 100);
//ぼ
await mouthMove(40.0, 100, 0.0, 100);
//く
await mouthMove(40.0, 100, 0.0, 100);
//の
await mouthMove(40.0, 100, 0.0, 100);
//こ
await mouthMove(40.0, 170, 0.0, 100);
//た
await mouthMove(40.0, 170, 0.0, 100);
//え
await mouthMove(40.0, 170, 0.0, 100);
//も
await mouthMove(30.0, 1000, 0.0, 500);
//き
await mouthMove(40.0, 100, 0.0, 100);
//い
await mouthMove(40.0, 100, 0.0, 100);
//と
await mouthMove(40.0, 500, 0.0, 100);
//で
await mouthMove(40.0, 100, 0.0, 100);
//て
await mouthMove(40.0, 100, 0.0, 100);
//い
await mouthMove(40.0, 100, 0.0, 100);
//る
await mouthMove(40.0, 100, 0.0, 100);
//だ
await mouthMove(40.0, 100, 0.0, 100);
//あ
await mouthMove(40.0, 100, 0.0, 100);
//ろ
await mouthMove(40.0, 800, 5.0, 600);
//く
await mouthMove(40.0, 400, 0.0, 100);
//り
await mouthMove(40.0, 400, 0.0, 100);
//す
await mouthMove(40.0, 400, 0.0, 100);
//ま
await mouthMove(30.0, 80, 0.0, 100);
//す
await mouthMove(30.0, 80, 0.0, 100);
//きゃ
await mouthMove(50.0, 100, 0.0, 100);
//ろ
await mouthMove(30.0, 100, 0.0, 100);
//る
await mouthMove(30.0, 120, 0.0, 100);
//が
await mouthMove(40.0, 900, 0.0, 500);
//な
await mouthMove(40.0, 400, 0.0, 100);
//が
await mouthMove(40.0, 400, 0.0, 100);
//れ
await mouthMove(40.0, 400, 0.0, 100);
//る
await mouthMove(40.0, 400, 0.0, 100);
//こ
await mouthMove(40.0, 100, 0.0, 100);
//ろ
await mouthMove(40.0, 100, 0.0, 100);
//に
await mouthMove(40.0, 100, 0.0, 100);
//は
await mouthMove(50.0, 1300, 0.0, 500);
//だ
await mouthMove(40.0, 100, 0.0, 100);
//れ
await mouthMove(40.0, 100, 0.0, 100);
//を
await mouthMove(40.0, 400, 0.0, 100);
//あ
await mouthMove(40.0, 100, 0.0, 100);
//い
await mouthMove(30.0, 100, 0.0, 100);
//し
await mouthMove(30.0, 100, 0.0, 100);
//て
await mouthMove(30.0, 100, 0.0, 100);
//る
await mouthMove(30.0, 100, 0.0, 100);
//の
await mouthMove(40.0, 100, 0.0, 100);
//か
await mouthMove(30.0, 1000, 0.0, 500);
//い
await mouthMove(40.0, 100, 0.0, 100);
//ま
await mouthMove(40.0, 100, 0.0, 100);
//は
await mouthMove(40.0, 500, 0.0, 100);
//み
await mouthMove(40.0, 100, 0.0, 100);
//え
await mouthMove(40.0, 100, 0.0, 100);
//な
await mouthMove(20.0, 100, 0.0, 100);
//く
await mouthMove(20.0, 100, 0.0, 100);
//て
await mouthMove(40.0, 100, 0.0, 100);
//も
await mouthMove(40.0, 100, 0.0, 100);
//お
await mouthMove(50.0, 5000, 50.0, 0);
for (i=49; i>=0; i--){
await mouth.angle(i);
await obniz.wait(80);
}
}
google_home = async function() {
console.log(">>> google home start");
googlehome.device('Google-Home', language);
await googlehome.play('http://×××××.ngrok.io/audio/kurisumasusong.mp3', function(res) {
console.log(res);
leftLed.on();
rigthLed.on();
singMouth();
});
}
console.log(">>> obniz start");
await google_home();
}
##実行
以下のコマンドで実行します。
$node face.js
サンタが歌ってる感じになります。
###反省
サーボ音がでかいので、口パクがばれやすいのでどうにかしたいと思いました。
なんかサンタっぽさに欠けるなと思ったのですが、
おそらく直毛だからなので、クリンクリンの毛があると良いと思いました。