masayasanのアイコン画像
masayasan 2021年02月19日作成 (2021年02月19日更新)
製作品 製作品 閲覧数 1317
masayasan 2021年02月19日作成 (2021年02月19日更新) 製作品 製作品 閲覧数 1317

【玩具】「色変わりの刀」制作

1.製作内容

某漫画に登場する持ち主によって色が変わる刀をモデルにした「色変わりの刀」を製作した。
筐体としてダイソーで販売している「光る忍者刀」を使用している。
マイコン部分はArduino互換機であるSeeeduino Xiaoを使用。

2.使用部品

・光る忍者刀(ダイソー)
・Seeeduino Xiao(Arduino互換機)
・DFplayer
・RGBフルカラーLED 5mm OSTA5131A カソードコモン(秋月電子)
・抵抗入トランジスタ RT1P137P 40V1A
・抵抗器10M、300、220Ω
・ビニル配線
・百均で販売されていた防犯ブザー内にあったトランス?(型式不明)
・5mm角プラ棒

3.電気回路図

キャプションを入力できます

4. 製作過程

①黒と銀のマスキングタープを刀身に貼付け
刀身部に黒と銀のマスキングテープを張付けました。
刀の刃部分はLEDの光が見える様に少し隙間を空けています。

②5mm角プラ棒にLED6個を巻き付け
LED(RGB)は5mm角棒にマスキングテープで巻きつけて刀身部分に入れます。
電池ホルダーは既存の柄部分を流用します。

③DFplayer
簡単な配線、コマンドで好きな音を再生できるDFplayer。
SDカードに音源を保存しておくのですが、音源を探す or 作成するのが一番苦労したかも。
ネット上にあるフリーの音源も沢山あるのですが、イメージしているものとピッタリの音は中々入手が難しいです。

④左側は圧電ブザー右側はトランス?
写真左側は圧電ブザーで右側は防犯ブザーに入っていたトランスらしきもの。
圧電ブザーの音量を大きくするために設置してあります。

⑤3.3Vでも動作可能なSeeduino Xiao
低電圧(3.3V)動作可能かつPWM対応ピンを多く持つArduino互換機のSeeeduino Xiaを選定。
トランジスタを仲介して1つのピンでLED6個制御する。

⑥皮膚抵抗を検知する為のリード線
2本のリード線を触るとマイコンに入力されている電圧が分圧されて、入力値が変化します。
皮膚の抵抗値はおよそ2~5M?
その値を元に色が決定されLEDが発色します。

⑦柄の部分
柄の部分にリード線を這わせて、握った時に皮膚抵抗を検知する様にした。

⑧傾斜スイッチ
傾斜スイッチが金属製なので、ビニルテープで巻いて絶縁しました。

5. コード

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"


SoftwareSerial mySoftwareSerial(9, 10); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

int val1 = 0; //常時 抵抗値観測
int val2 = 0; //設定抵抗値 手を離すまで値保持
int TiltSWval = 0;//傾斜回数観測
boolean TiltSWon;//TiltSWvalが一定回数ONでON
int RGB[3] = {0, 0, 0};
int SoundOn = 1;
int Soundname[4] = {1, 2, 3, 4}; //[0]:色変わり、[1]:構え、[2]:攻撃、[3]:無音

unsigned long Posingtime1 = 0;
unsigned long Posingtime2 = 0;
unsigned long Posingtime3 = 0;
#define TiltSW 0
#define redLED 1
#define greenLED 2
#define blueLED 3

//pin7 analogread pin9,10 Sirial

int color = 0;
#define white 1//kasumi
#define olive 2
#define yellow 3//kaminari
#define fuchsia 4
#define silver 5//iwa
#define apua 6
#define lime 7
#define red 8//honoo
#define gray 9//keadamono
#define blue 10//mizu
#define green 11//kaze
#define purple 12
#define maroon 13
#define navy 14
#define teal 15
#define black 16


void setup() {
  Serial.begin(9600);
  mySoftwareSerial.begin(9600);
  if (!myDFPlayer.begin(mySoftwareSerial, false)) {  //Use softwareSerial to communicate with mp3.
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while (true) {
      delay(0); // Code to compatible with ESP8266 watch dog.
    }
  }
  myDFPlayer.volume(30);  //Set volume value. From 0 to 30
  myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);
  pinMode(TiltSW, INPUT_PULLDOWN);
}

void loop() {
  readval();
  if (val1 <= 600 && val2 == 0) {
    val2 = val1;
  }
  Posingtime1 = millis();
  while (val2 != 0) {
    readval();
    color = map(val2, 200, 600, 1, 16);
    colorPG();
    analogWrite(redLED, RGB[0]);
    analogWrite(greenLED, RGB[1]);
    analogWrite(blueLED, RGB[2]);
    Posingtime1 = millis();
    Posingtime2 = 0;
    if (SoundOn == 1) {
      myDFPlayer.play(2);
      SoundOn = 2;
      Serial.print("s1");
    }
    Action();
    if (val1 > 600) {
      initialize();
      Serial.print("val1 ");
      Serial.print(val1);
      Serial.println("reflesh");
    }
  }
}

void readval() {
  for (int i = 0; i < 30 ; i ++) {
    val1 = val1 + analogRead(8);
    TiltSWval += digitalRead(TiltSW);
    delay(5);
  }
  val1 = val1 / 30;
  if (TiltSWval < 10) {
    TiltSWon = 0;
  }
  else if (TiltSWval > 20) {
    TiltSWon = 1;
  }
  TiltSWval = 0;
}

void Action() {
  while (val1 < 600 && TiltSWon == 1) {
    SoundOn = 2;
    readval();
    if (millis() - Posingtime1 > 2000) {
      Posingtime2 = millis() - Posingtime1;
    }
    analogWrite(redLED, RGB[0]);
    analogWrite(greenLED, RGB[1]);
    analogWrite(blueLED, RGB[2]);
    delay(200);
    Serial.println("");
    Serial.print("TiltOn");
    while (val1 < 600 && Posingtime2 > 5000) {
      Posingtime2 = millis() - Posingtime1;
      readval();
      analogWrite(redLED, 0);
      analogWrite(greenLED, 0);
      analogWrite(blueLED, 0);
      //delay(200);
      Serial.print("kamae");
      Serial.print("time2");
      Serial.print(Posingtime2);
      Posingtime3 = millis() - Posingtime2;
      if (TiltSWon == 1) {
        if (SoundOn == 2) {
          myDFPlayer.playFolder(1, Soundname[1]);
          SoundOn = 0;
          Serial.print(",SoundOn,");
          Serial.print(SoundOn);
        }
      }
      else if (TiltSWon == 0) {
        SoundOn = 2;
        analogWrite(redLED, RGB[0]);
        analogWrite(greenLED, RGB[1]);
        analogWrite(blueLED, RGB[2]);
        delay(200);
        Posingtime1 = millis();
        Posingtime2 = 0;
        Serial.println("atack");
        myDFPlayer.playFolder(1, Soundname[2]);
        SoundOn = 2;
        delay(3000);
      }
      if (Posingtime2 > 10000) { //5secで構えキャンセル
        Posingtime1 = millis();
        Posingtime2 = 0;
        Serial.println("cancel");
        myDFPlayer.playFolder(1, Soundname[3]);
        SoundOn = 2;
      }
    }
  }
}

void initialize() {
  val2 = 0;
  Posingtime2 = 0;
  analogWrite(redLED, 0);
  analogWrite(greenLED, 0);
  analogWrite(blueLED, 0);
  SoundOn = 1;
  myDFPlayer.pause();
}

void colorPG() {

  switch (color) {
    case olive:
      RGB[0] = 128;
      RGB[1] = 128;
      RGB[2] = 0;
      break;
    case yellow://yellow 3//kaminari
      RGB[0] = 255;
      RGB[1] = 255;
      RGB[2] = 0;
      Soundname[2] = random(9, 10);
      break;
    case fuchsia:
      RGB[0] = 255;
      RGB[1] = 0;
      RGB[2] = 255;
      break;
    case silver://silver 5//iwa
      RGB[0] = 192;
      RGB[1] = 192;
      RGB[2] = 192;
      Soundname[2] = 11;
      break;
    case apua:
      RGB[0] = 0;
      RGB[1] = 255;
      RGB[2] = 255;
      break;
    case lime:
      RGB[0] = 0;
      RGB[1] = 255;
      RGB[2] = 0;
      break;
    case red://red 8//honoo
      RGB[0] = 255;
      RGB[1] = 0;
      RGB[2] = 0;
      Soundname[2] = random(5, 6);
      break;
    case gray:
      RGB[0] = 128;
      RGB[1] = 128;
      RGB[2] = 128;
      break;
    case blue://blue 10//mizu
      RGB[0] = 0;
      RGB[1] = 0;
      RGB[2] = 255;
      Soundname[2] = 14;
      break;
    case green://green 11//kaze
      RGB[0] = 0;
      RGB[1] = 128;
      RGB[2] = 0;
      Soundname[1] = 7;
      Soundname[2] = 8;
      break;
    case purple:
      RGB[0] = 128;
      RGB[1] = 0;
      RGB[2] = 128;
      break;
    case maroon:
      RGB[0] = 128;
      RGB[1] = 0;
      RGB[2] = 0;
      break;
    case navy:
      RGB[0] = 0;
      RGB[1] = 0;
      RGB[2] = 128;
      break;
    case white:
      RGB[0] = 255;
      RGB[1] = 255;
      RGB[2] = 255;
      break;
    case teal://white 1//kasumi
      RGB[0] = 0;
      RGB[1] = 128;
      RGB[2] = 128;
      Soundname[2] = 13;
      break;
    case black:
      RGB[0] = 0;
      RGB[1] = 0;
      RGB[2] = 0;
      break;
  }
}

6.まとめ

握る人が同じでも、握り方で色が変わる

刀を握るたびに色が変わるので、子供たちはそれぞれの色に対応したごっこ遊びをしてました。
音に関しては苦労した割に地味な音ばかりだったので、無い方が良かったかも。。。

おもちゃは単純明快な方が遊びやすいし、故障も少なくて良い。
今後の制作作品に反映させていきます。

ログインしてコメントを投稿する