2012年11月7日

球面プロッタを応募してみた

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

7月頃に作った卓球玉に絵を描く装置(球面プロッタ)を電子工作コンテスト2012に応募してみたり。
http://elecontest.com/entrylist/043

以前の完成記事からの変更点は、回路をブレッドボードからバニラシールドに移した点、ボタンひとつでデフォルト描画パターンを単独描画(PCレス)できるようにした点の2つ。

ソースコードはこちら
pingPongBot(KumamotoNCT).ino (9299Byte)
※「熊本高専」と描画する座標データを内包

紹介動画はこちら



ちなみに動画はiMovieで作成。
普段はAfterEffectsばかり使ってるのでiMovieには慣れてなかったり...

2012年10月30日

Arduinoでピアノ階段 with GarageBand

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

前々から予告していた、ピアノ階段(a.k.a. GarageBand階段)プロジェクトが完成・一般公開できたので、その報告と技術的な詳細について。

まずは実際の動作映像から。



仕組みは以前書いた記事(これこれ)から殆ど変わっていませんが、踏み板スイッチの大型化と素材の特性に応じて若干の調整を加えています。

各段の横幅が1800mm奥行きが350mm程度と大きいこと、滑りにくいことなどを条件に素材を選び、最終的には厚さ2mm〜3mm程度のベニヤ板を使用。

1800x900mmサイズのベニヤ板から1800x250mmの板を3枚切り出し、これの片面にアルミ箔テープ(0.1mm厚)、厚手両面テープ(0.5mm厚)を貼る。

貼り付けたアルミ箔テープの片隅に、リード線の先端を扇状に広げたものを乗せ、上から短く切ったアルミ箔テープをしっかりと貼り付ける。


リード線、アルミ箔テープと貼った場所の上にガムテープを貼る。(リード線で盛り上がった部分同士が接触しないように)



これを2枚用意し、2枚のうち1枚のアルミ箔テープの上に「たこ糸」を渡す。(ベニヤ板の自重で常に接触することを防止する)

ここまで出来たら、アルミ箔を貼った面を向かい合わせにして慎重に貼り合わせる。


これを各段に設置、配線していきます。
タクトスイッチをArduinoで使う要領で、各段のスイッチをプルダウンで接続します。


プログラムはこんな感じ。
相変わらずの「動けば良い」コードなので、改良の余地は十分にあるはず。

#include <Bounce.h>

int pinDo = 13;
int pinRe = 12;
int pinMi = 11;
int pinFa = 10;
int pinSo = 9;
int pinLa = 8;
int pinTi = 7;
int pinDo2 = 6;
int pinRe2 = 5;
int state[9];

Bounce Do = Bounce( pinDo,20 );
Bounce Re = Bounce( pinRe,20 );
Bounce Mi = Bounce( pinMi,20 );
Bounce Fa = Bounce( pinFa,20 );
Bounce So = Bounce( pinSo,20 );
Bounce La = Bounce( pinLa,20 );
Bounce Ti = Bounce( pinTi,20 );
Bounce Do2 = Bounce( pinDo2,20 );
Bounce Re2 = Bounce( pinRe2,20 );

void setup() {
  pinMode(pinDo, INPUT);
  pinMode(pinRe, INPUT);
  pinMode(pinMi, INPUT);
  pinMode(pinFa, INPUT);
  pinMode(pinSo, INPUT);
  pinMode(pinLa, INPUT);
  pinMode(pinTi, INPUT);
  pinMode(pinDo2, INPUT);
  pinMode(pinRe2, INPUT);

  Serial.begin(31250); 
}

void loop(){

  Do.update ();
  if ((Do.read() == HIGH)&&(state[0] == 0)) {
    noteOn(144,60,127);
    state[0] = 1;
  }
  if ((Do.read() == HIGH)&&(state[0] == 1)) {
  }
  if ((Do.read() == LOW)&&(state[0] == 1)) {
    noteOn(128,60,127);
    state[0] = 0;
  }
  if ((Do.read() == LOW)&&(state[0] == 0)) {
  }

  Re.update ();
  if ((Re.read() == HIGH)&&(state[1] == 0)) {
    noteOn(144,62,127);
    state[1] = 1;
  }
  if ((Re.read() == HIGH)&&(state[1] == 1)) {
  }
  if ((Re.read() == LOW)&&(state[1] == 1)) {
    noteOn(128,62,127);
    state[1] = 0;
  }
  if ((Re.read() == LOW)&&(state[1] == 0)) {
  }

  Mi.update ();
  if ((Mi.read() == HIGH)&&(state[2] == 0)) {
    noteOn(144,64,127);
    state[2] = 1;
  }
  if ((Mi.read() == HIGH)&&(state[2] == 1)) {
  }
  if ((Mi.read() == LOW)&&(state[2] == 1)) {
    noteOn(128,64,127);
    state[2] = 0;
  }
  if ((Mi.read() == LOW)&&(state[2] == 0)) {
  }

  Fa.update ();
  if ((Fa.read() == HIGH)&&(state[3] == 0)) {
    noteOn(144,65,127);
    state[3] = 1;
  }
  if ((Fa.read() == HIGH)&&(state[3] == 1)) {
  }
  if ((Fa.read() == LOW)&&(state[3] == 1)) {
    noteOn(128,65,127);
    state[3] = 0;
  }
  if ((Fa.read() == LOW)&&(state[3] == 0)) {
  }

  So.update ();
  if ((So.read() == HIGH)&&(state[4] == 0)) {
    noteOn(144,67,127);
    state[4] = 1;
  }
  if ((So.read() == HIGH)&&(state[4] == 1)) {
  }
  if ((So.read() == LOW)&&(state[4] == 1)) {
    noteOn(128,67,127);
    state[4] = 0;
  }
  if ((So.read() == LOW)&&(state[4] == 0)) {
  }

  La.update ();
  if ((La.read() == HIGH)&&(state[5] == 0)) {
    noteOn(144,69,127);
    state[5] = 1;
  }
  if ((La.read() == HIGH)&&(state[5] == 1)) {
  }
  if ((La.read() == LOW)&&(state[5] == 1)) {
    noteOn(128,69,127);
    state[5] = 0;
  }
  if ((La.read() == LOW)&&(state[5] == 0)) {
  }

  Ti.update ();
  if ((Ti.read() == HIGH)&&(state[6] == 0)) {
    noteOn(144,71,127);
    state[6] = 1;
  }
  if ((Ti.read() == HIGH)&&(state[6] == 1)) {
  }
  if ((Ti.read() == LOW)&&(state[6] == 1)) {
    noteOn(128,71,127);
    state[6] = 0;
  }
  if ((Ti.read() == LOW)&&(state[6] == 0)) {
  }

  Do2.update ();
  if ((Do2.read() == HIGH)&&(state[7] == 0)) {
    noteOn(144,72,127);
    state[7] = 1;
  }
  if ((Do2.read() == HIGH)&&(state[7] == 1)) {
  }
  if ((Do2.read() == LOW)&&(state[7] == 1)) {
    noteOn(128,72,127);
    state[7] = 0;
  }
  if ((Do2.read() == LOW)&&(state[7] == 0)) {
  }

  Re2.update ();
  if ((Re2.read() == HIGH)&&(state[8] == 0)) {
    noteOn(144,74,127);
    state[8] = 1;
  }
  if ((Re2.read() == HIGH)&&(state[8] == 1)) {
  }
  if ((Re2.read() == LOW)&&(state[8] == 1)) {
    noteOn(128,74,127);
    state[8] = 0;
  }
  if ((Re2.read() == LOW)&&(state[8] == 0)) {
  }
}

void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

本来は、Serial MIDI ConverterでMIDI信号をMacに入力する予定でしたが、何故か鳴ってくれない(おそらくjavaのバージョンアップが原因)ので、ArduinoからMIDI-OUTを出し、それをUSB-MIDIケーブルでMacに入力。

あとはGarageBandを起動すれば、各段に応じた音が鳴ります。

2012年10月19日

Raspberry Piが届いた

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

注文していたRaspberry Piがようやく到着。
既に他のブログに掲載されているような紙箱ではなく、こんな感じのプラスチックケース入り。
教育機関などで大量購入、大量保管するときは非常に便利そう。


中は帯電防止ビニール袋に包まれたRaspberry Pi本体とクイックスタートガイド系の紙が2枚入っている。


一緒に買ったクリアケースに入れてみたところ。


クリアケースは土台と上部に分かれていて、土台に固定すると外しにくい感じ。
上部は簡単に外せる感じになっていて、普段はケース、時々GPIOで遊ぶ、なんて使い方にも優しい設計。

もう少し落ち着いたらこれで遊んでみようと思います。

2012年9月10日

Li-po Riderとかソーラーとか

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

9/8〜9/10まで秋葉原のワシントンホテルに滞在、電子パーツ屋さん等で色々買い物してました。

千石電商でLi-po Rider(950円)と1Wソーラーパネル(560円)とJST-XHのケーブル付きコネクタ(メス50円*2、オスメスセット80円)を購入。

aitendoでNokia3300-LCD(500円*2)とLi-poの310mAh(690円)と820mAh(850円)を購入。
このLi-poに千石電商で購入したJSTコネクタ付きのケーブルをハンダ付けで接続。


千石電商で買ったLi-po Rider、ビニールの外側には下記の様に「V1.0の(中略)コネクタはJST型(XHP)2Pです。」とあるが...


実際に入っているのはV1.1で、コネクタがJST-XH(2.5mmピッチ)からJST-PH(2mmピッチ)に変更された最新版。


以下は横に並べて撮った写真。


左のコネクタがJST-PH(2mmピッチ)で、右のコネクタ2つがJST-XH(2.5mmピッチ)。
千石電商に騙される形で買ってしまった訳ですが... せっかく買ってきたので手を加えてみる。


JST-XHコネクタ(ケーブル付き)をJST-PHコネクタの足部分に直接ハンダ付け。
XHもPHも接続できるLi-po Rider V1.1(改)が完成。


無事、充電開始されました。


ソーラーパネルからも充電できることを確認、逆にLi-poから5V出力でArduino UNO等へ給電できることも確認。

色々と遊べる幅が広がりそうな予感。

2012年8月31日

HTC EVO WiMAXにCyanogenMod9(Unofficial)をインストールする

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

HTC EVO 3D ISW12HTに機種変更してから、充電と放電をひたすら繰り返すだけのEVO WiMAXがあまりにも可哀想なので、とりあえず常用できそうなCyanogenMod9 Nightlyを入れた時のメモ。

大雑把な手順は、S-OFF→CWM→CM9という感じ。
今回は、全く非公式的な手段をやったことがなく、ファームウェアも最新のEVO WiMAXにインストールする場合(要するに最も手順が多い場合)の手順を書きます。

1. PCにドライバをインストール
32bit、64bitそれぞれ向けのドライバをインストールする。
HTC Syncをインストールすればドライバが自動的に適用されるが、HTC Syncを使わない場合はドライバ単体をインストールした方が良い。
HTC_Driver.zipやHTC_Driver_64.zipで検索すると出てくるはず。

2. ファームウェアのダウングレード
RUUを使って初期まで戻し、2.19.970.1までアップデートする。
(この手法を使えばS-OFFの端末をS-ONさせることも可能。修理に出す際に捗る。)
ここに詳しい手順が載ってるので参照されたし。
本来、表にでるはずのないRUUが何故かダウンロードできたりするところもある。

3. S-OFFからCWM導入まで
Revolutionaryを利用する。
ここに詳しい手順が載ってるので参照されたし。

4. CyanogenMod9を焼く
この辺を読みつつ、ここから新しめのイメージをダウンロードする。
ダウンロードしたzipは解凍しないでEVO WiMAXのSDカード直下に入れる。
ついでにCyanogenMod 9向けのGAppsをここからダウンロードして、同様にSDカード直下に入れる。
EVO WiMAXの電源を切り、ボリュームボタンの下を押しながら電源ON。
BOOTLOADERからRECOVERYを選択するとCWMが起動するので、install zip from sdcardを選択、choose zip from sdcardを選択、ダウンロードしてきたイメージのzipを選択。
画面の表示に従って適当にインストールを進め、同様にGAppsもインストール。

少々時間のかかる再起動を経て、ようこそ画面が表示されるので、言語で日本語(ただしCJKフォント)を選択する。


あとは、画面表示の指示に従って設定していけばOKです。


ここまで来て、何も分からない人がやってるとは思っていませんが一応警告
この状態の端末は、USBつないでadb shellやるとroot権限で弄れたりする。
メインの端末として利用している場合は、くれぐれも置き忘れたり置きっぱなしで席を離れたりしないように。
パターンロックやらパスコードやら設定していても無駄ですので。
あと、できればGMailやらWalletの決済情報やらが詰まったアカウントでやらないことをお勧めする。
分かってる人は分かっているなりにセキュリティ施すと思うので、くれぐれも自己責任で。