🌏

デジぺ改め、じゃべるぐるみ制作 その3 測距センサーで検出時に発話(その2+赤外線測距センサー+基板化)

2024/06/27に公開

こんにちは、Ideagearの鈴木陽介です。

ドジパンダのしゃべぐるみVer.3.0ですが、3月頭に深センで制作してからだいぶ時間が経ってしまいました。

他方で、2024年7月7日(日)のHamamatsu Micro Maker Faire 2024(ハママツマイクロメイカーフェア 2024)が10日後に迫り、この祭りに向けて新作をつくる関係上、そろそろギアを上げていかなければいけません。
https://makezine.jp/event/makerfaire/hmmf2024/

ということで、まずはおさらいを兼ねて、前作の内容を改めて記事に残したいと思います。

ところで、言葉を話すぬいぐるみは、ここ1年くらいは「デジタルペット」→略して「デジぺ」と言ってきました。

ただ、デジぺはデジタルペーパーの略としてある程度認知されていそうなことと、一方で、「しゃべぐるみ」という便利なカテゴリーが世の中的に認知されつつあることを鑑みて、我々が作っているしゃべるぬいぐるみも、今後は、しゃべぐるみの一つとして、認知度向上に貢献したいと思います。

はじめに

今回のコンセプトは、あるワンオペの店長さんからの一言が後押しとなり、確定しました。

とある観光地のお店で、ドジパンダのしゃべぐるみVer.2.0(タッチスイッチとリモコンで発話)をお店の方にご紹介したところ、

店長「レジで接客中に、屋台コーナーでしゃべっていてくれると助かる。」

というようなフィードバックをいただきました。どうやら、ぬいぐるみに触ったり、リモコン押したらしゃべってくれるのはいいのですが、お客様が来たら勝手にしゃべってくれる方がありがたいという意味のようです。

確かに、一人でやりくりしている以上、レジと屋台のどっちかにしか居れないわけで、レジの方はまだしも、屋台の方は、せっかく何か食べたいと思っても、そこに誰も居ないとあきらめてそのまま通り過ぎてしまう人が多そうですね。

そして、それは、お店にとっては少なくない機会損失となります。

ということで、しゃべぐるみの中に、人が来たことを検知するセンサーを搭載し、誰か来たら、「いらっしゃいませ!」としゃべらせることにしました。

また、しゃべぐるみの最初の製品に向けてコンセプトも固まりつつあるため、今回を機に、ブレッドボードだけで無理やり動かすラフのラフのような状態から脱却し、基板化も同時に進めることにしました。

なお、今回のしゃべぐるみをつくりにあたっては、秋月電子さんで購入した下記センサーを使用しました。
シャープ測距モジュール GP2Y0A02YK
https://akizukidenshi.com/catalog/g/g103158/

上記センサーを使った単独のテストとしゃべぐるみのVer.2.0に関しては、下記を参考記事をご覧ください。

参考記事

電子工作 その21(アナログ電圧出力タイプ赤外線測距センサー:GP2Y0A02YK0Fの使い方)
https://zenn.dev/suzuky/articles/6dc6034ec8dc21

デジペ制作 その2 デジペをリモコンから遠隔発話(タッチスイッチ+音声再生モジュール+赤外線受信モジュール+赤外線リモコン)
https://zenn.dev/suzuky/articles/45a610071f1b98

基本情報

各部品やセンサーの仕様、配線、ライブラリーなどに関しては、上述の参考記事をご覧ください。

配線図及び基板データ

後日改めて公開します。

ソースコード

下記は今回使用したソースコードです。

/*
0001_あそぼー.mp3
0002_最初はー.mp3
0003_じゃんけん.mp3
0004_ぽん.mp3
0005_あいこで.mp3
0006_ぐー.mp3
0007_チョキ.mp3
0008_パー.mp3
0009_こんにちはー.mp3
0010_ドジパンダだよー.mp3
0011_ありがとう.mp3
0012_またねー.mp3
0013_ごめんなさい1.mp3
0014_ごめんなさい2.mp3
0015_いらっしゃいませ1.mp3
0016_いらっしゃいませ2.mp3
0017_いらっしゃいませ3.mp3
0018_いらっしゃいませ4.mp3
0019_いらっしゃいませ5.mp3
0020_いらっしゃいませ6.mp3
0021_少々お待ち下さい.mp3
*/
  
  //DFPlayer Mini
#include "SoftwareSerial.h"
#include "DFPlayer_Mini_Mp3.h"
SoftwareSerial mySerial(10, 11); // RX, TX

  //VS1838B(赤外線受信モジュール)
#include <IRremote.h>
int receiverPin = 4; //デジタルピン番号用の変数
IRrecv receiver(receiverPin); //操作用の変数
decode_results results; //受信した信号の格納用の変数

  //TTP223(タッチスイッチ)
const int TOUCH1 = 5; //発話用のタッチスイッチ1
const int TOUCH2 = 6; //発話用のタッチスイッチ2
const int TOUCH3 = 7; //発話用のタッチスイッチ3

//ランダム変数
int randNumber1;
int randNumber2;
int randNumber3;

//GP2Y0A02YK0F
int val = 0; // 受信するシリアルデータのために準備
float dis = 0; // 距離の計算値
float l_t = 0.7; // センサのフィルタ定数

int dly = 3000; //delay用

void setup() {

  //DFPlayer Mini
  delay(2000); //モジュール起動の待機時間
  mySerial.begin (9600);
  mp3_set_serial (mySerial); //set softwareSerial for DFPlayer-mini mp3 module
  mp3_set_volume (60);

  //TTP223
  pinMode(TOUCH1, INPUT); //発話用のタッチスイッチ1の入力
  pinMode(TOUCH2, INPUT); //発話用のタッチスイッチ2の入力
  pinMode(TOUCH3, INPUT); //発話用のタッチスイッチ3の入力

  //VS1838B
  receiver.enableIRIn(); //赤外線受信モジュールを初期化

  //ランダム変数
  Serial.begin(9600);
  randomSeed(analogRead(0));
  
}

void loop() {

//タッチで発話

  //タッチ1=じゃんけん  
  if (digitalRead(TOUCH1) == HIGH){
    //ランダム変数1 6:ぐー 7:チョキ 8:パー
    randNumber1 = random(6, 9); // 6から8の乱数を生成                           
    mp3_play (1); //0001_あそぼー.mp3
    delay(3000);          
    mp3_play (3); //0003_じゃんけん.mp3
    delay(3000);   
    mp3_play (randNumber1); //0006_ぐー.mp3 / 0007_チョキ.mp3 / 0008_パー.mp3
    delay(2000);           
  
  }  
  delay(1);

  //タッチ2=赤外線測距センサー起動  
  if (digitalRead(TOUCH2) == HIGH){
    mp3_play (21); //0021_少々お待ち下さい.mp3
    delay(5000);          

    int i = 0;    
    int state = 1;
    while(state == 1){
      if (digitalRead(TOUCH3) == HIGH){
        int state = 0;
        mp3_play (12); //0012_またねー.mp3
        delay(3000);
        break;               
      }

      //GP2Y0A02YK0F
      val = analogRead(A0);
      if(val < 82){ // AD値が小さい場合に近似式で距離が無限になってしまうので、AD値が82未満は82とする
        val = 82;
      }
      dis = l_t * dis + (1 - l_t) * 25391 * pow(val, -1.136); // 距離算出。指数移動平均で平滑化。
      Serial.print("AD: ");
      Serial.print(val);
      Serial.print(" / 距離: ");
      Serial.print(dis);
      Serial.println(" cm");

      //物体を感知した場合
      if((val > 300) && (val <= 1000)){
        //ランダム変数 15~20:いらっしゃいませ1~6
        randNumber2 = random(15, 21); // 15から20の乱数を生成
        mp3_play (randNumber2); //0015_いらっしゃいませ1.mp3~0020_いらっしゃいませ6.mp3
        delay(3000);
      }          
    
    }
    
  }  
  delay(1);

  //タッチ3=あいさつ
  if (digitalRead(TOUCH3) == HIGH){
    //ランダム変数3 9:こんにちはー 10:ドジパンダだよー
    randNumber3 = random(9, 11); // 9から10の乱数を生成
    mp3_play (randNumber3); //0009_こんにちはー.mp3 / 0010_ドジパンダだよー.mp3
    delay(1000);          
  }  
  delay(1);

//赤外線リモコンで発話
  if (receiver.decode(&results)) { //赤外線を受信して信号を格納

    //(results.value == 実際のリモコンの赤外線識別番号)
    //ONボタン(0xFF02FD)
    if (results.value == 0xFF02FD) {      
      mp3_play (11); //0011_ありがとう.mp3                  
      delay(1000);

    //OFFボタン(0xFF9867)  
    }else if (results.value == 0xFF9867) {
      mp3_play (14); //0014_ごめんなさい2.mp3               
      delay(1000);

    }  
    receiver.resume();

  }
  delay(1);

}

赤外線識別コード

上記ソースコード内には、「0xFF02FD」や「0xFF9867」という16進数の部分があります。
具体的には以下の場所です。

if (results.value == 0xFF02FD) {
}else if (results.value == 0xFF9867) {

このresults.valueに代入する8桁の英数字については、お使いのリモコンに対応する赤外線識別コードを入れてください。赤外線識別コードの確認方法については、下記をご覧ください。
https://zenn.dev/suzuky/articles/e3bc109e0aaf50#赤外線識別コードの確認方法

動作確認

ぬいぐるみへ組み込む前の動作確認です。
https://x.com/dojinosuke/status/1763990217109946372

ぬいぐるみへ組み込み後の動作状況です。
https://x.com/dojinosuke/status/1764017240704430152

まとめ

いかがでしたでしょうか?

この時は、深センの隣町の恵州でのワークショップを翌日に控え、半徹で仕上げましたが、その後数ヶ月このバージョンを使うことになりました。

それはともかく、今回で、センサーは基板とコネクタで接続され、声もついに声優さんの声になり、だいぶ製品前のプロトタイプとして完成形に近づきつつあります。

とはいえ、基板はまだ剥き出しの状態ですし、バッテリーはリチウムイオンバッテリーを使っています。タッチセンサーもピンポイントでタッチしないと反応しません。

基板を筐体に組付け、製品の初期の方はバッテリーのPSEを回避するために乾電池駆動にし、各センサーの感度もまだまだ調整しないといけません。ここからの道のりは長いですが、できる限り早く製品版を完成させたいと思います。

それではまた!

Discussion