Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

人形の目を光らせ、呪いの人形にする

はじめに

「球体関節ってエロいよね?」
「人形に魂が入っていたとしても、動いたり喋ることはおろか意思表示の手段がないってのがいい……」
と、フェチをこじらせて球体関節人形を作るに至ってしまいました。

うちのコ(球体関節人形)

作っていくと愛着が出てくるものでして、いろいろやりたくなります。
あるとき、市販ロボットの機能で「目を光らせ、その色で感情を表現する」というのを聞き、その程度だったらうちの子にも仕込めるかな?と、家に転がっていた arduino と フルカラーLED を使いやってみることにしました。

が、実際にやってみると。
「これ、あかんヤツや」
軽いホラーになってしまい、呪われた感が……。というわけなので公開して、呪いを皆様におすそわけです。

やること

長々書いても、やることは「arduinoでLチカ」です(元も子もない
よくあるフルカラーLEDで足がR・G・Bと分かれているものは結線が面倒くさいので、マイコン内蔵RGB LEDを使っていくことにします。

必要なもの

  • 人形 : 私は自作の人形を使いましたが、眼球にLEDを仕込む余裕があれば市販のドールでもいけるのでしょうか?
  • Arduino Uno : 別にUnoである必要はありません
  • マイコン内蔵RGB LED PL9823-F5 : 今回の肝です

他にも線材やユニバーサル基板などがありますが省略します。

今回使ったRGB LED「PL9823」 の特徴としては

  • 電源以外に制御信号線だけの結線だけで他の部品が必要ない
  • PL9823の出力端子と入力端子とを数珠繋ぎに連結していくことで複数のLEDを制御できる。この場合でもマイコンとの結線は1本だけで済む(多数つなげるときはノイズ対策に他の部品が必要かも)
  • Arduino で制御する場合はライブラリが公開されている

といったことが挙げられます。
また、RGBを各256段階で指定できますので「緑が入った青」や「赤味が強い橙」などの微妙な色もできますので、このLEDを使ってスティックライトを作れば赤・ピンクから青や黄色にいつでも変えられますし、アイドルの推しが変わっても安心です みくにゃんのファンやめます

Arduino と LED の接続

今回の人形は、目の数が2つですので、LED PL9823を2つarduinoと接続します。
結線は以下のようになります。LEDをつなぐArduinoのピンは今回はDIGITAL 2を使いました。

PL9823 LED接続

arduino LED1 LED2
5V 3.VDD 3.VDD
GND 1.GND 1.GND
DIGITAL 2 4.DIN
2.DO 4.DIN

今回は2つだけですが、三只眼の人形でLED3つとか百々目鬼でもっとたくさんの場合でも、LEDのDOとDINを数珠繋ぎにしていくだけで、arduinoとの線の数は変わりません。百目の場合には電源は別にとった方がいいとは思いますが。

スケッチ

スケッチを書きはじめる前に、PL9823を使うためのライブラリを用意します。
ライブラリマネージャで「Adafruit Neopixel」を探すか、https://github.com/adafruit/Adafruit_NeoPixel から持ってきます。

スケッチは今回は以下のようになりました。

dolleye_led.ino
#include <Adafruit_NeoPixel.h>

#define LEDPIN 2
#define NUMLED 2

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMLED, LEDPIN, NEO_RGB + NEO_KHZ800);

typedef struct {
  int r;
  int g;
  int b;
} RGB;

String eyes_color[] = {"#000000", "#0000ff", "#ff0000", "#ff00ff", "#00ff00", "#00ffff", "#ffff00", "#ffffff"};
int eyes_colorCount = sizeof(eyes_color) / sizeof(eyes_color[0]);
int eyes_color_cur = 0 , eyes_color_to=1;

RGB rgb_hex2dec(String hexstr){
  RGB rgb;
  long val = strtol(&hexstr[1], NULL, 16);
  rgb.r = (int) (val >> 16 & 0xff);
  rgb.g = (int) (val >> 8 & 0xff);
  rgb.b = (int) (val & 0xff);

  return rgb;
}

boolean compareRGB(RGB a, RGB b){
  return ((a.r == b.r)&&(a.g == b.g)&&(a.b == b.b));
}

void changeLED(RGB from1, RGB to1, RGB from2, RGB to2){
  RGB s[] = {from1, from2},
      t[] = {to1, to2},
      d[2];

  for(int i=0; i<2; i++){
    d[i].r= (s[i].r < t[i].r)?1:((s[i].r > t[i].r)?-1:0);
    d[i].g= (s[i].g < t[i].g)?1:((s[i].g > t[i].g)?-1:0);
    d[i].b= (s[i].b < t[i].b)?1:((s[i].b > t[i].b)?-1:0);
  }

  while(!compareRGB(s[0],t[0]) && !compareRGB(s[1],t[1])){
    for(int i=0; i<2; i++){
      if(s[i].r != t[i].r){  s[i].r += d[i].r;  }
      if(s[i].g != t[i].g){  s[i].g += d[i].g;  }
      if(s[i].b != t[i].b){  s[i].b += d[i].b;  }
    }

    setLED(s[0], s[1]);
    delay(5);
  }
}

void setLED(RGB rgb1, RGB rgb2) {
  strip.setPixelColor(0, strip.Color(rgb1.r, rgb1.g, rgb1.b));
  strip.setPixelColor(1, strip.Color(rgb2.r, rgb2.g, rgb2.b));
  strip.show();
}

void setup() {
  strip.begin();
  strip.setBrightness(30);
  setLED(rgb_hex2dec("#000000"), rgb_hex2dec("#000000")); 
  delay(1000);

}

void loop() {
  RGB from = rgb_hex2dec(eyes_color[eyes_color_cur]);
  RGB to = rgb_hex2dec(eyes_color[eyes_color_to]);

  changeLED(from, to, from, to);
  eyes_color_cur = eyes_color_to;
  eyes_color_to = (eyes_color_to + 1) % eyes_colorCount;

  delay(3000);
}

Adafruit_Neopixel のライブラリを利用した部分を少しだけ解説をしますと

  1. インスタンスの作成。LEDの数・arduinoのピン番号・色の並び・データの転送速度指定Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMLED, LEDPIN, NEO_RGB + NEO_KHZ800);
  2. インスタンスの開始 strip.begin();
  3. 明るさ指定関数 strip.setBrightness(30);
  4. 指定したLEDに対する色をRGBで指定 strip.setPixelColor(0, strip.Color(rgb1.r, rgb1.g, rgb1.b));
  5. LED表示反映 strip.show();

となります。

スケッチを転送して実行されると、LEDの色が無点灯→青→赤→紫→緑→水色→黄色→白→無点灯→……と イロイッカイズツ の順(X1では逆順?)にじょじょに変化していきます。

人形の準備

真似して作ろうという方はほとんどいないと思いますが、人形の方のLEDを仕込む眼球についても触れておきます。
白目部分を眼球は石粉粘土(人形の体も石粉粘土です)で作ったものに、黒目にあたる部分を透明レジンで作ったものを接着し、黒目部分のみLEDの光が透過するようにしています。虹彩は透明シールをPCで作って、黒目と白目の間に貼り付けました。

人形の眼球・虹彩を透明レジンで作成

ドール用にアクリルアイ・グラスアイなどが市販されていますが、これら眼球の中でLEDを光らせると白目部分まで光ってしまいますので、やめた方がいいと思います。

人形への組み込みと動作

人形との現物合わせで目の幅にLEDが配置されるようユニバーサル基板に半田付けを行い(ここまでのLEDの動作の確認はブレッドボードで行っていました)、人形の頭部に入るよう基板をカットし、それを人形に取り付けて完成です。

人形への組み込み用LED基板

実際に動作させた様子がこちら

目光る球体関節人形 pic.twitter.com/luKkJjiJxU

— 球体関節人形 (@CursedDoll_1103) 2017年4月1日

冒頭で「これ、あかんヤツや」「軽いホラーになった」というのがわかっていただけましたでしょうか?

終わりに

今回使いましたPL9823というフルカラーLEDは「arduinoで使う分には使い勝手がいい」ということがわかっていただければ幸いです。

そういうLEDを使うと「簡単にできるから」と人形の目にLEDを仕込む、とやってみたのですが、結果は「簡単に出来るからといっても、やらない方がいいことも世の中にはある」と。でもおかしいな?ロボットだったら目のLEDが光っても普通なのに、なぜ人形だと?

しかし、人形の目を光が通るように作っておく、というのは応用範囲は広そうではあります。たとえば

  • 普通に見ている分にはなんの変哲も無い人形なのに、デジタルカメラで撮影すると目が光って写るよう赤外線LEDを仕込む
  • 赤外線LEDを仕込んでリモコンの信号を出力し、人形を置いた部屋のテレビが勝手に点いたり消えたりする

といった応用が思い浮かびます……応用範囲、狭かったですね。

なおこの人形ですが。現在私の手元では音声合成ICが内蔵され喋るようにもなっていて、ますますホラーなことになっています。

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
3
Help us understand the problem. What are the problem?