RaspberryPizeroぬいぐるみの作り方

  • 11
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

ぬいぐるみが動いて話し相手になって欲しかった

作りたいもの

  • ぬいぐるみが動いてほしい
  • ぬいぐるみがしゃべって欲しい
  • ぬいぐるみとおしゃべりしたい
  • もふもふしたい

今回はぬいぐるみにPraspberryPizeroを入れて動いてしゃべらせる+スマートフォンとBluetoothで通信することでしゃべる内容を送信する

材料

  • RaspberryPizero
  • Bluetoothドングル
  • MiniHDMIから音声出力端子付きVGA変換ケーブル
  • スピーカー
  • サーボモーター
  • 段ボールの切れ端
  • ぬいぐるみに詰めるもの(モフモフさせるため)
  • Androidスマートフォン

作り方

ぬいぐるみ編(ハード)

  • スピーカー
    • スピーカーはあらかじめ内臓電池を抜いてRaspberryPizeroから給電で動作するように改造
    • 音声は音声出力端子付きVGAケーブルにオーディオケーブルを接続して再生
  • サーボモーター
    • RaspberryPizeroはPWMに対応しているピンが2本しかないため別途モジュールを接続しない場合はモーターは2つが限界
    • 13,18ピンにサーボモーターの信号線を接続
    • サーボモータは全身の動き用と手を動かす用に利用

DSC_0799.JPG

  • 組み合わせる
    • ぬいぐるみに入るようにセロテープと段ボールでまとめる

DSC_0792.JPG
DSC_0793.JPG

  • ぬいぐるみに詰める
    • ぬいぐるみに適度なモフモフ感を出すために隙間に詰め物を入れる(今回は電子部品を買ったときについてきたビニール袋詰めた)

DSC_0789.JPG

ぬいぐるみ編(ソフト)

  • RaspberryPizeroの設定
  • OSはRaspbian
  • 以下の記事を参考にBluetoothのシリアル通信を設定

    rfcomm-server.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <bluetooth/bluetooth.h>
    #include <bluetooth/rfcomm.h>
    int main(int argc, char **argv)
    {
    char synth_buf[2048]={ 0 };
    struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
    char buf[2048] = { 0 };
    int s, client, bytes_read;
    socklen_t opt = sizeof(rem_addr);
    
    // allocate socket
    s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
    
    // bind socket to port 1 of the first available
    // local bluetooth adapter
    loc_addr.rc_family = AF_BLUETOOTH;
    loc_addr.rc_bdaddr = *BDADDR_ANY;
    loc_addr.rc_channel = (uint8_t) 1;
    bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
    
    // put socket into listening mode
    listen(s, 1);
    
    // accept one connection
    client = accept(s, (struct sockaddr *)&rem_addr, &opt);
    
    ba2str( &rem_addr.rc_bdaddr, buf );
    fprintf(stderr, "accepted connection from %s\n", buf);
    
        while(1) {
            memset(buf, 0, sizeof(buf));
            // read data from the client
            bytes_read = read(client, buf, sizeof(buf));
            if(strcmp(buf,"exit")==0) {
                sprintf(synth_buf,"sh /home/pi/Program/Control.sh ばいばーい,0");
                system(synth_buf);
                break;
            }
            if( bytes_read > 0 ) {
                printf("received [%s]\n", buf);
                sprintf(synth_buf,"sh /home/pi/Program/Control.sh %s",buf);
                system(synth_buf);
            }
        }
    
    // close connection
    close(client);
    close(s);
    return 0;
    }
    
  • WiringPiでサーボモーターの制御

    • WiringPiのインストール方法は割愛
    servo.c
    #include <iostream>
    #include <stdlib.h>
    #include <wiringPi.h>
    int main(int argc,char **argv)
    {
    if (wiringPiSetupGpio() == -1) {
    std::cout << "cannot setup gpio." << std::endl;
    return 1;
    }
    pinMode(13, PWM_OUTPUT);
    pinMode(18, PWM_OUTPUT);
    pwmSetMode(PWM_MODE_MS);
    pwmSetClock(400);
    pwmSetRange(1024);
    int num,servo;
    servo = atoi((const char*)argv[1]);
    num = atoi((const char*)argv[2]);
    if(servo==0)pwmWrite(13, num);
    else pwmWrite(18, num);
    return 0;
    }
    
    g++ <.cファイル> -o <出力ファイル> -lwiringPi
    
  • 音声合成Open JTalkの制御

    • Open JTalkのインストール方法は割愛
    synth.sh
    TMP=/tmp/test.wav
    echo "$1" | open_jtalk -m /home/pi/Program/Voice/rou.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow $TMP && \
    aplay --quiet $TMP
    rm -f $TMP
    
    • ディスプレイを接続していないとHDMI出力してくれない場合(音声が出力されない)
    • /boot/config.txtのhdmi_driver=2をコメントアウト
    sudo vim /boot/config.txt
    
  • Bluetoothシリアル通信プログラムrfcomm-serverを起動時実行プログラムとして登録

    • /etc/rc.localのexit 0の手前に実行プログラムを記述
    • Bluetoothシリアル通信からサーボモータと音声合成プログラムを実行するスクリプトを作成
Control.sh
TEXT=`echo $1 | cut -d"," -f1`
COMMAND=`echo $1 | cut -d"," -f2`
echo "text $TEXT"
sh /home/pi/Program/Voice/synth.sh $TEXT
echo "command $COMMAND"
# 手を振る
if [ $COMMAND -eq 0 ]
then
sudo /home/pi/Program/Servo/servo 1 70
sleep 1s
sudo /home/pi/Program/Servo/servo 1 110
sleep 1s
sudo /home/pi/Program/Servo/servo 1 70
sleep 1s
sudo /home/pi/Program/Servo/servo 1 110
# お辞儀
elif [ $COMMAND -eq 1 ]
then
sudo /home/pi/Program/Servo/servo 0 110
sleep 1s
sudo /home/pi/Program/Servo/servo 0 80
sleep 2s
sudo /home/pi/Program/Servo/servo 0 110
# ノーマル
else
sudo /home/pi/Program/Servo/servo 0 110
sleep 1s
sudo /home/pi/Program/Servo/servo 1 110
fi

Androidアプリ編

実行

  • RaspberryPizeroを起動しAndroidからBluetoothChatアプリを実行
  • BluetotthでRaspberryPizeroと接続しテキストボックスにしゃべらせたい文章を入力

RaspberryPizeroぬいぐるみがしゃべって動いたら成功

しゃべるRaspberryPiぬいぐるみ
その1 pic.twitter.com/pN7W6FVVPY

— アキヒロ (@akihiro01051) 2016年9月12日

  • メインのサーボモータが全体を動かす

メインのサーボで上下に動く pic.twitter.com/QtYCKbBRWH

— アキヒロ (@akihiro01051) 2016年9月19日
  • サブのサーボモータが腕を動かす

サブのサーボで手が動く pic.twitter.com/P5B2MxSFbS

— アキヒロ (@akihiro01051) 2016年9月19日

今後の課題

  • もろい(スピーカーが接触不良で鳴らない時がある)
  • もろい(段ボールとセロテープだからすぐはがれる)
  • モフモフしない(ビニール袋の感触がする)