読者です 読者をやめる 読者になる 読者になる

クッション付き貼箱の作り方

ガジェットが入っているようなクッション付きの貼箱を作ってみたくて、趣味で作ってみました。

f:id:shigeodayo:20160225014156j:plain

Twitterで公開していると、以下の様なリプライを頂いたので、作り方を簡単にまとめてみたいと思います。

用意するもの

  • スチレンボード
    • 今回は、生協に売ってた2-3mmくらいのやつを使用
    • もっと厚くて重いほうが高級感でるかも
  • ブロック型のウレタンフォーム
    • ブロックをちぎっておおまかのサイズでガジェットを収納できるようにするもの
    • 想定する箱のサイズを基準に、Amazonで購入 www.amazon.co.jp
  • クッションシート x 2
    • ブロック型ウレタンフォームだと見栄えが悪いため、上から貼る
    • 上蓋の裏側にも貼った
    • 想定する箱のサイズを基準に、Amazonで売ってたウレタンのものを購入 www.amazon.co.jp

使用した機材

  • プリンタ
    • スチレンボードの上に貼る用紙(貼り紙)をイラレでデザインしてプリンタで印刷
    • 今回は、箱のサイズが大きかったために、大判プロッターを使用した
  • レーザーカッター
    • クッションシートを綺麗に切るために使用

箱の作り方

箱の作り方は、おおむね以下のサイトを参考に、アレンジを加えています。 このサイトの知識を前提に進めるため、必ず目を通してください。 貼箱の作り方 | 紙箱、貼箱 パックス・エム

張り紙の作成

外側がスチレンボードだと情けないので、上から紙を張ります。 イラレで切り取り線と、その他装飾をデザインして、大判プロッターで印刷した用紙を張り紙として使用しました。 うちに置いてある大判プロッターで使用している紙はわりと手触りの良い紙だったのすが、紙にこだわるともっと高級感が出せると思います。 箱のサイズによっては家庭用のプリンタでも可能だと思います。

f:id:shigeodayo:20160225022359j:plain f:id:shigeodayo:20160225022430j:plain

張り紙の形は、先ほど紹介したサイトのを真似しています。 貼箱の作り方 | 紙箱、貼箱 パックス・エム

箱の組み立て

スチレンボードを切って箱を作り、その上から大判プロッターで印刷した貼紙を貼り合わせます。

だいたいの手順は以下のとおりです。

  1. 箱のサイズを決めて、スチレンボードをカッターで切る
  2. 折る部分を浅くカッターで切る(切断してしまわないように注意) f:id:shigeodayo:20160209001545j:plain
  3. 大判プロッターで印刷した用紙にスプレーのりを塗布する
  4. 底面と用紙を貼り合わせる(位置合わせを慎重に)
  5. 紙を綺麗に折り曲げて、側面を貼り合わせる
  6. できあがり

クッションの作り方

最初は、レーザーカッターで厚いウレタンフォームを切ればできるじゃんと思ってました。 でも、レーザーカッターで切断できるサイズ(たぶん10mm以下)を越えていることに気づきました。 そこで、手でちぎれるブロック型のウレタンフォームで大体の収納部分を作成し、綺麗に見えるようにレーザーカッターで切断したクッションシートを上から貼り合わせることを思いつきました(デジタル・アナログ変換)。

だいたいの手順は以下のとおりです。

  1. ブロック型のウレタンフォームを、箱のサイズに合わせる
  2. ガジェットのサイズに合わせて、ブロックをちぎる f:id:shigeodayo:20160209221023j:plain
  3. クッションシートをガジェットのサイズに合わせてレーザーカッターで切断
    • ガジェットのサイズちょうどに切断できるように、今回は以下の手順を試みた
    • ウレタンフォームを詰めた箱にガジェットを収め、その写真を真上から撮影 f:id:shigeodayo:20160210000736j:plain
    • イラレに写真を取り込んで、ガジェットのパスを作成
    • 紙に印刷してパスをハサミで切る
    • 紙を箱とガジェットにかざしてみて、パスの微調整を繰り返す
  4. ウレタンフォームの上に、クッションシートを両面テープで貼り付ける
  5. ブロックをちぎった凸凹面が汚いので、ちぎったブロックの部分を覆うために、レーザーカッターでクッションシートを切断 f:id:shigeodayo:20160225025837j:plain
  6. 上蓋のサイズに合うようにクッションシートをレーザーカッターで切断
  7. 切断したシートを上蓋にも両面テープで貼り付ける f:id:shigeodayo:20160225023631j:plain
  8. 完成 f:id:shigeodayo:20160214203520j:plain

最後に

ざっくばらんに書いたので、わかりにくい記述があったら教えてください。

文章書くのをめんどくさがって、工作のノウハウをいつもまとめないので、今度からちゃんとしようと思いました。

DJI Phantom controller hack

DJI PhantomをPCから操作するためにコントローラをhackする。

なお、hackは自己責任で。

コントローラの分解

Phantomのコントローラの裏側のネジを外すと、中身はこんな感じ。

f:id:shigeodayo:20140501235945j:plain

Phantomのコントローラでは、ポテンションメータを使って、操作レバーがどの方向にどれだけ倒されたか検知している。

上下方向に動く操作レバーに付いているポテンションメータ(コントローラ右側)

f:id:shigeodayo:20140501235849j:plain

左右方向に動く操作レバーに付いているポテンションメータ(コントローラ右側)

f:id:shigeodayo:20140501235926j:plain

つまり、操作レバーを倒したときにポテンションメータに加わっている電圧をあらかじめ測定しておき、PCから制御できるマイコンボードを使ってそれと同じだけの電圧をコントローラの制御基板に加えることで、PCからPhantomを操作できるようになるはず。 (電圧制御ではなく、デジタルポテンショメータに置き換える方法もある。)

電圧の確認

ということで、操作レバーを動かした時の電圧をテスタを使って測定する。

まず、テスタで導通チェックすると、2つのポテンションメータにつながっているコードの中で茶・黒のコードがGNDとつながっているみたい。

そして、コントローラの電源を入れた状態で、右側操作レバーを上下左右に倒したときの電圧変化を測定した。 測定値は以下の通り。個体によってばらつきがあるかも。

[上下方向]

橙-赤:1.42V(下)- 1.68V(中)- 1.97V(上)

橙-茶:3.35V(固定)

赤-茶:1.93V(下)- 1.66V(中)- 1.38V(上)

[左右方向]

黄-白:1.45V(左)- 1.72V(中)- 1.99V(右)

黄-黒:3.35V(固定)

白-黒:1.90V(左)- 1.62V(中)- 1.36V(右)

どうやら、橙・黄には固定の電圧がかかっていて、赤・白のコードに加える電圧を制御すれば良いみたい。

回路とプログラムの作成

そして、測定した電圧と同じだけの電圧をマイコンボードからPhantomの制御基板に直接加える。今回はArduino Unoを使用した。

ArduinoanalogWrite関数を用いることで0-5Vの任意の電圧を作り出すことができる。しかし、この出力はPWM信号であるため、平滑化回路を挟み、アナログ電圧に変換する必要がある(PWM信号のままではうまくいかなかった)。

こちらのサイトを参考に、抵抗(5.1KΩ)、コンデンサ(10uF)、LM358を用いて平滑化のための回路を作成した。

配線は以下の通り。

茶 -> GND

赤 <- 平滑化回路 <- Arduino 5番ピン

橙 <- 3.3V (Arduino)

黒 -> GND

白 <- 平滑化回路 <- Arduino 6番ピン

黄 <- 3.3V (Arduino)

最終的にはこんな感じに配線。コントローラの電源としてAC電源から5Vを入力。

f:id:shigeodayo:20140501220122j:plain

Arduinoのコードは以下の通り。 2・3行目に計測した電圧値を記述してある。

PCの1キーを押すと右側操作レバーが右上に、2キーで初期状態、3キーで左下に倒したのと同じ状態になる。

const int analogOut[] = {5, 6}; // ver, hori

int verValues[] = {1.38 * 100, 1.66 * 100, 1.93 * 100}; // up to down
int horValues[] = {1.36 * 100, 1.62 * 100, 1.90 * 100}; // right to left

int value[] = {0, 0}; // ver, hori, 0-255


void setup() {
  for (int i = 0; i < sizeof(analogOut) / sizeof(analogOut[0]); i++ ){
    pinMode(analogOut[i], OUTPUT);
  }

  value[0] = map(verValues[1], 0, 5 * 100, 0, 255);
  value[1] = map(horValues[1], 0, 5 * 100, 0, 255);


  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i < sizeof(analogOut) / sizeof(analogOut[0]); i++) {
    analogWrite(analogOut[i], value[i]);
  }
}

void serialEvent() {
  if (Serial.available() > 0) {
    int key = Serial.read();

    switch (key) {
    case '1': // u-d: 1.38v, l-r: 1.36v
      value[0] = map(verValues[0], 0, 5 * 100, 0, 255);
      value[1] = map(horValues[0], 0, 5 * 100, 0, 255);
      break;
    case '2': // u-d: 1.66v, l-r: 1.62v
      value[0] = map(verValues[1], 0, 5 * 100, 0, 255);
      value[1] = map(horValues[1], 0, 5 * 100, 0, 255);
      break;
    case '3': // u-d: 1.93v, l-r: 1.90
      value[0] = map(verValues[2], 0, 5 * 100, 0, 255);
      value[1] = map(horValues[2], 0, 5 * 100, 0, 255);
      break;
    case '0':
      value[0] = 0;
      value[1] = 0;
      break;
    case 'q':
      verValues[1] += 1;
      value[0] = map(verValues[1], 0, 5 * 100, 0, 255);
      Serial.println(verValues[1], DEC);
      break;
    case 'w':
      verValues[1] -= 1;
      value[0] = map(verValues[1], 0, 5 * 100, 0, 255);
      Serial.println(verValues[1], DEC);
      break;
    case 'e':
      horValues[1] += 1;
      value[1] = map(horValues[1], 0, 5 * 100, 0, 255);
      Serial.println(horValues[1], DEC);
      break;
    case 'r':
      horValues[2] -= 1;
      value[1] = map(horValues[1], 0, 5 * 100, 0, 255);
      Serial.println(horValues[1], DEC);
      break;
    }
    for (int i = 0; i < sizeof(value) / sizeof(value[0]); i++) {
      Serial.print("value[");
      Serial.print(i);
      Serial.print("] = ");
      Serial.println(value[i], DEC);
    }
    Serial.println("-------------------");
  }
}

動作確認

Phantomは左右の操作レバーを内側に倒すと離陸・緊急着陸する。 右側操作レバーはPCから、左側操作レバーは手で操作し、離着陸のテストを行ってみた。

以下、動作映像。

注意

Phantomとコントローラの電源を入れた際に、Phantomのランプがパパパッっと連続して3回赤く光る状態が続く場合がある。操作レバーを倒している状態で電源を入れたときにこうなるみたい。 そのときは、操作レバーを動かしていない(初期状態)ときの電圧値と、プログラムに記述されている電圧値が一致しているか確認する。

追記(2014/5/3)

両方の操作レバーをPCから制御するコードは以下の通り。

const int LEFT_LEVER_OUT[] = {3, 9}; // ver, hori
const int RIGHT_LEVER_OUT[] = {10, 11}; // ver, hori

const int MAX_VALUE = 5 * 100;

int leftVerValues[] = {1.41 * 100, 1.69 * 100, 1.96 * 100}; // up to down
int leftHorValues[] = {1.38 * 100, 1.65 * 100, 1.92 * 100}; // right to left
int rightVerValues[] = {1.38 * 100, 1.66 * 100, 1.93 * 100}; // up to down
int rightHorValues[] = {1.36 * 100, 1.62 * 100, 1.90 * 100}; // right to left

int leftValues[] = {0, 0}; // ver, hori, 0-255
int rightValues[] = {0, 0}; // ver, hori, 0-255

boolean isFlying = false;

void setup() {
  for (int i = 0; i < sizeof(LEFT_LEVER_OUT) / sizeof(LEFT_LEVER_OUT[0]); i++) {
    pinMode(LEFT_LEVER_OUT[i], OUTPUT);
  }
  for (int i = 0; i < sizeof(RIGHT_LEVER_OUT) / sizeof(RIGHT_LEVER_OUT[0]); i++) {
    pinMode(RIGHT_LEVER_OUT[i], OUTPUT);
  }

  setLeverValue(leftVerValues[1], leftHorValues[1], leftValues);
  setLeverValue(rightVerValues[1], rightHorValues[1], rightValues);

  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i < sizeof(LEFT_LEVER_OUT) / sizeof(LEFT_LEVER_OUT[0]); i++) {
    analogWrite(LEFT_LEVER_OUT[i], leftValues[i]);
  }
  for (int i = 0; i < sizeof(RIGHT_LEVER_OUT) / sizeof(RIGHT_LEVER_OUT[0]); i++) {
    analogWrite(RIGHT_LEVER_OUT[i], rightValues[i]);
  }
}

void serialEvent() {
  if (Serial.available() > 0) {
    int key = Serial.read();

    switch (key) {
    case '0': // initial state
      setLeverValue(leftVerValues[1], leftHorValues[1], leftValues);
      setLeverValue(rightVerValues[1], rightHorValues[1], rightValues);
      break;
    case' ': // take off / landing
      setLeverValue(leftVerValues[0], leftHorValues[0], leftValues);
      setLeverValue(rightVerValues[2], rightHorValues[2], rightValues);
      isFlying = !isFlying;
      break;      
    }
    
    for (int i = 0; i < sizeof(leftValues) / sizeof(leftValues[0]); i++) {
      Serial.print("leftValues[");
      Serial.print(i);
      Serial.print("] = ");
      Serial.println(leftValues[i], DEC);
    }
    for (int i = 0; i < sizeof(rightValues) / sizeof(rightValues[0]); i++) {
      Serial.print("rightValues[");
      Serial.print(i);
      Serial.print("] = ");
      Serial.println(rightValues[i], DEC);
    }
    Serial.println("-------------------");
  }
}

void setLeverValue(int verValue, int horValue, int leverValues[]) {
  leverValues[0] = map(verValue, 0, MAX_VALUE, 0, 255);
  leverValues[1] = map(horValue, 0, MAX_VALUE, 0, 255);
}