Arduino用キーボードのケースを作るべく、地道に試作中。

テクを参考にしようと、世界の3Dモデルデータをつらつら眺める。

あ、これ、欲しい。

Minecraft の鉱石(ore)っぽいライト。 マイコン制御でそれっぽく光らせるのは、得意。

3D データ

いきなり高い山に登る。

単純な光が漏れる穴ではなくて、薄い厚いの段差があって、かっこいい。 ただし、大きさは 25cm x 25cm くらいある。 Adventure3は、最大サイズ 15cm x 15cm x 15cm 、入りきらない。 どうせならと、20%の 5cm x 5cm くらいに縮めてプリントした。

ラフトを剥がすときに、赤線の部分で折れた。。。 20%の縮小は、強度的に無理だったか。。

上部ではうまく抜きができず、大きな穴になってるし。

マイコンと配線

自宅の在庫が豊富で、安い(500円以下)中国製の怪しい Pro Microを利用する。

ライトは、NeoPixel のLEDリングを使う。

  • PIN1 ... NeoPixel制御用
  • PIN0 ... PULLUP抵抗をいれてスイッチ(押すと発色パターンを変更)
  • PIN2 ... スイッチの確認用LED。通常ON でスイッチを押すとOFF

ProMicro は、プログラムの書き込みをするために、リセットPIN(黄色)のshort(GND)が必要。

プログラム書き込み時に、Console で、 Waiting for the new upload port... と出力されたら、すかさずリセット。

プログラム

Platform.io でさくさく。

platformio.ini

ini
[env:sparkfun_promicro16]
platform = atmelavr
board = sparkfun_promicro16
framework = arduino
upload_port = /dev/tty.usbmodemxxxxxxx
lib_deps = adafruit/Adafruit NeoPixel@^1.8.3

main.cpp

main.cpp · Gistcpp
#include <Adafruit_NeoPixel.h>

#define NEOPIXEL_PIN 1
#define NUMPIXELS 7

#define SWITCH_PIN 0
#define LED_PIN 2

#define MAX_BRIGHT 100
#define MIN_BRIGHT 5

int Current_pattern = 0;

//Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800);
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NEOPIXEL_PIN, NEO_RGBW);

void setup()
{
  Serial.begin(9600);
  pixels.begin();
  pixels.show();
  Serial.println("pixel off");

  pinMode(SWITCH_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
}

void loop()
{
  static int bright = MIN_BRIGHT;
  static int bright_offset = 2;
  static int prev_switch_value = HIGH;
  int value;
  uint32_t color = pixels.Color(bright, bright, bright);
  ;

  value = digitalRead(SWITCH_PIN); // 入力ピンを読む
  if (prev_switch_value != value)
  {
    if (value == LOW)
    {
      // SWITCH ON
      if (Current_pattern++ > 3)
      {
        // change color pattern
        Current_pattern = 0;
      }
    }
    prev_switch_value = value;
    // LED ON/OFF
    digitalWrite(LED_PIN, value);
  }

  for (int pixel_no = 0; pixel_no < NUMPIXELS; pixel_no++)
  {
    // GRB
    color = pixels.Color(0, 0, 0);
    switch (Current_pattern)
    {
    case 0:
      // red stone
      color = pixels.Color(0, bright, 0);
      break;
    case 1:
      // iron
      color = pixels.Color(bright / 4, bright / 1.2, bright / 6);
      break;
    case 2:
      // gold
      color = pixels.Color(bright / 3, bright / 1.2, 0);
      break;
    case 3:
      // emerald
      color = pixels.Color(bright, 0, 0);
      break;
    case 4:
      // diamond
      color = pixels.Color(bright / 2, bright / 5, bright / 1.2);
      break;
    }
    pixels.setPixelColor(pixel_no, color);
  }

  bright += bright_offset;
  if (bright >= MAX_BRIGHT)
  {
    // darkness
    bright_offset = -2;
  }
  if (bright <= MIN_BRIGHT)
  {
    // lightness
    bright_offset = 2;
  }

  pixels.show();
  delay(30);
}

demo

3Dプリント品質はアレだけど、コピー用紙を挟んでデモすると、いいじゃないか!

仕組みはできたので、基板の収まりとプリント精度の調整で、なんとかなりそう。