2011-03-27

【ミクパ】ネギサイリウム(Ver.2)の作成【Arduino】 その3 ~回路設計・組立・プログラミング~

では、前回の記事の続き。

組み立て

回路図は大雑把にこんな感じ。
▲手書きでテキトーサーセンw ちなみに、LEDは内部で青と緑のカソードが繋がってるアノードコモン型。

なお、抵抗値は以下のような計算で求める。
  1. カラーLEDのRGBの各々に流す電圧Vfを決める。
    ここでは、R:2.0v, G:3.5v, B:3.5v (一般的数値。赤LEDは、緑、青に比べて少ない電気で光る)
  2. 流す最大電流Ifを決める。
    ここでは、100mA (ちなみに、このLEDは150mAまでOK)
  3. R = ( 3.6 - Vf ) / If で得られるRが抵抗値。よって、Rr,Rg,Rbをそれぞれ赤LED、緑LED、青LEDとすると、
    Rr = ( 3.6 - 2.0 ) / 0.1 = 16Ω
    Rg = Rb = ( 3.6 - 3.5 ) / 0.1 = 1Ω
今回は、電源が3.6vと少ないので、抵抗もかなり小さい。
本来、このLEDを使う場合は12vが最適なのだが、あまり電源を大きくすると

  • 電池のスペースで軽量化が難しくなる。
  • 熱対策が必要になる。

といった問題が起こる。
なので、このへんは妥協することにした。

回路設計が終わったところで、本格的に組み立て。

▲こんな感じで位置調整等考えながら、どうすればうまく収納できるか考える。筒の底になってる白いスイッチは、たまたま見つけて買ってきたやつなんだけど、まさかパイプにちょうどハマるとは思わなかった。これは奇跡。

▲パーツをいろいろいじりつつ、なんとかうまく収まりました。

▲スイッチの細部。プッシュスイッチは穴あけして足を接続した後、グルーガンで取れないように固定。中心部分は抵抗が入ってる。

▲プッシュスイッチの裏側。リード線がぐちゃぐちゃw ここのリード線は中身を取り出すときのことを考えて長めにしてあるんだよね。

▲Arduino、トランジスタアレイが入ってる部分。周りをVer.1で使ってたプラスチックを使ってうまくハマるように調整してる。

▲Arduinoの裏側。ここもリード線だらけw 白はすべてLEDの配線(赤黒だと目立つので白にしました)。LED1本につき5本、全部で10本分引き込んでる。でも、途中で足りなくなって補強するハメになった・・・かっこわるい。

▲電池部分、あと左側からLED部分。分かりやすいようにLEDを点灯させた状態。ネジはLEDを固定させるためのネジ。一応ライブで振ることを考えると、ちゃんと固定しないとね。


▲もちろん、電池は交換可能なように、簡単に開くことができる。2つのパイプの直径がギリギリのサイズなので、ここはネジ止めしなくても大丈夫だった。

▲取り出してみたところのスイッチ部分。白のスイッチはハンダ付けしてから取付け可能だったけど、プッシュスイッチは足が小さいから取付け後にハンダ付け、かなりきつかった。

▲電池ケース。そのままだとうまく入らなかったので、カッターでギリギリまで削った。こういう調整がすごく大変。

▲Arduinoの拡大。こいつの裏に基板をつけて配線をしている。


▲Arduinoの裏側。配線、ぐちゃぐちゃひどいw この基板の裏にトランジスタアレイ、さらにその上にArduinoを取り付けたんだけど、実は、その配置を間違えてしまっていたせいで、かなり無理のある配線になってしまいますた\(^o^)/

▲最初、このピンヘッダが邪魔で入らなかったので、写真のようにL字型に変更した。このピンにUSB接続する回路をくっつけてプログラムを流し込む。なので、こうやってピンヘッダを残しておけば、あとでいくらでもプログラミングが変更が可能になる。


プログラミング

ここまでくれば、あとは、動作内容を決めるプログラミングを行い、Arduinoに実行データを送ればおk。
まあ、プログラミングといっても、

  • 初期化時で、LEDのピンとプッシュスイッチのピン番号定義。
  • ループで、スイッチ処理と決まったモードにしたがってLEDのRGB値を変更して出力。

というぐらいしかしてない。
以下がArduinoIDEでプログラミングしたコード。

// LEDのピン
const int LED_R_PIN  =  9;
const int LED_G_PIN  = 10;
const int LED_B_PIN  = 11;
const int LED2_R_PIN =  3;
const int LED2_G_PIN =  5;
const int LED2_B_PIN =  6;
// スイッチピン
const int SW_PIN     =  7;
// 状態の数
const int STATE_NUM  =  8;

// スイッチ管理
int swValOld = 0;
int swVal    = 0;
int state = 0;
int count = 0;

// 光らせる値を入れる変数
int rVal = 0;
int gVal = 0;
int bVal = 0;

int rVal2 = 0;
int gVal2 = 0;
int bVal2 = 0;

void setup()
{
  // LEDに接続するピンを出力にセット
  pinMode(LED_R_PIN, OUTPUT);
  pinMode(LED_G_PIN, OUTPUT);
  pinMode(LED_B_PIN, OUTPUT);
  pinMode(LED2_R_PIN, OUTPUT);
  pinMode(LED2_G_PIN, OUTPUT);
  pinMode(LED2_B_PIN, OUTPUT);
  // スイッチのピンを入力にセット
  pinMode(SW_PIN, INPUT);
}

void loop()
{
  // スイッチの値取得
  swVal = digitalRead( SW_PIN );

  // スイッチ判定(立ち上がりのみ検出)
  if( swVal == HIGH && swValOld == LOW ) {
    state++;
    if( state >= STATE_NUM ) state = 0;
    delay(100); // チャタリング防止。値はテキトー
  }
  // 値更新
  swValOld = swVal;

  switch(state) {
  case 0: // 最初は消灯
  default:
    rVal = rVal2 = 0;
    gVal = gVal2 = 0;
    bVal = bVal2 = 0;
    break;
  case 1:  // ミクさん
    rVal = rVal2 = 20;
    gVal = gVal2 = 255;
    bVal = bVal2 = 100;
    break;
  case 2:  // リンちゃん・レンきゅん
    rVal = 130;
    gVal = 255;
    bVal = 20;
    rVal2 = 140;
    gVal2 = 255;
    bVal2 = 20;
    break;
  case 3:  // ルカ様
    rVal  = 230;
    gVal  = 220;
    bVal  = 220;
    rVal2 = 250;
    gVal2 = 220;
    bVal2 = 220;
    break;
  case 4:  // ミク・リン
    rVal2 = 20;
    gVal2 = 255;
    bVal2 = 100;
    rVal  = 140;
    gVal  = 255;
    bVal  = 20;
    break;
  case 5:  // ねぎとろ
    rVal2 = 20;
    gVal2 = 255;
    bVal2 = 100;
    rVal  = 255;
    gVal  = 220;
    bVal  = 220;
    break;
  case 6:  // めいこねーさん出ないかな・・・
    rVal = rVal2 = 255;
    gVal = gVal2= 10;
    bVal = bVal2= 10;
    break;
  case 7:  // カイトにーさんも出ないのかな・・・
    rVal = rVal2= 0;
    gVal = gVal2= 10;
    bVal = bVal2= 255;
    break;
  }

  // 出力
  analogWrite( LED_R_PIN, rVal );
  analogWrite( LED_G_PIN, gVal );
  analogWrite( LED_B_PIN, bVal );
  analogWrite( LED2_R_PIN, rVal2 );
  analogWrite( LED2_G_PIN, gVal2 );
  analogWrite( LED2_B_PIN, bVal2 );
}

ちなみに、各LEDの値は実際にLEDを光らせてトライアンドエラーをしながら決めている。
しかも、今回は、接触の問題なのか、LED1とLED2で同じ値を入れても色合いが違っていたため各々で微調整をかけている。

とまあ、以上のような感じで、ネギサイリウムVer.2ができたわけです。

全体を通して感想。

  • 正直、一番難しいところは外装の組み立て。回路を如何に小さく収めるか
  • 家にある工具、個人で手に入る材料でどうやってそれっぽいものをつくるか
  • 普段から100円ショップとかで使えそうな材料を探しておくべき

こんなところかな。


最後に、一つ。

愛があれば何でもつくれるんだよ!


2011-03-22

【ミクパ】ネギサイリウム(Ver.2)の作成【Arduino】 その2 ~部品選定~

前回記事の続き。
まずはハードウェア、部品をそろえる。

外見

Ver.1からLED、回路を全て取り外して、外見のみ流用することにした。
さらに、回路を収めるスペースとして、外見に合う筒(プラスチック製パイプ)を購入。

▲写真のは長いパイプを切断した様子。カッターで切れなかったので、半田ごてを使って溶かして切りますた。溶かしたときの匂いがヤバかった。体にイクナイ。




マイコン

マイコンは、PICでもなんでもよかったのだが、ゆとりらしくArduinoを使うことにした。
Arduinoはマイコンだけでなく、入出力部分まで作られた基板であり、Processing/Wiring言語を使用することができる。(マイコン自体はAVRらしい)

Arduinoはいくつか種類があるが、ここは携帯性を考えて、「Arduino Pro Mini 328 3.3V 8MHz」を選択。

▲こんな感じ。100円玉と見比べてもかなり小さい。



電子回路部品

まず、電源は、Arduinoが3.3V必要であること、大きさも小さく抑えたいことから、
バックアップリチウム電池 1/2AA 3.6Vを使用。
同種の電池ケースも購入。
▲一番右が普通に売ってる単三電池。



サイリウムの要、カラーLEDについては、いろいろ悩んだ挙句、大電力発光ダイオード、EP-204K-150G1R1B1-CAを採用。
このカラーLEDは電源12Vで150mAまでの電流を流すことができる、高出力型のLED。
1個500円・・・高いなぁ(;´∀`)
(ちなみに、一般的な砲弾型の形をしたLEDは1個10円とかで売ってます)

▲手前が普通のLED。奥のが今回使うLED、導線は自分でつけてる。


▲裏側。右がアノード、左がカソード。アノードコモン型なので、カソード側の3本がそれぞれRGBに対応する。ちなみに、真ん中の金属プレートは放熱用。



しかし、実際に12V、150mAなんかで流したら、LEDや抵抗が発熱するので放熱が必要になる。
まあ、ネギサイリウムにそんな機構を設ける余裕はないし、そもそもそ電源も用意できないので、
上記で決めた電池3.6Vで、とりあえず、テキトーに100mA程度流すことを考える。


LEDが決まったところで、必要そうなものとして、トランジスタアレイを用意。

▲こんなの。


トランジスタは、ある端子に電流を流すことで、他の2端子間に電圧を生じさせる電子部品。
まあ、つまり、電気的なスイッチ、みたいな役割を持つ。
トランジスタアレイは、そのトランジスタのアレイ(配列)ってこと。
今回は7個トランジスタが入ってるものを使い、具体的には以下のようなイメージで組み込む。

Arduino →[出力]→ トランジスタ → LEDの回路 →[電流]→ LED

こんなイメージ。


あとは、サイリウムの筒に収めるために、小さい基板を買っておく。
こんな小さいのもあるのね。



あとはスイッチとかネジとか買って、もろもろ材料をそろえた。


次の記事で、回路の組立と、プログラミング。

【ミクパ】ネギサイリウム(Ver.2)の作成【Arduino】 その1 ~動機と結果~

2011/03/09、ミクパでミクさんたちを応援するために、ネギサイリウムを自作することにした。
今回の自作ネギサイリウムは、前回のミクの日感謝祭で作ったネギサイリウムVer.1を改良する。

Ver.1

まずは、Ver.1の動作を動画で紹介↓
 

Ver.1のスペック:
・回路:市販のLEDサイリウム回路からLEDの配線だけ引っこ抜いて使用
・電源:ボタン電池(1.5V) x 3 (元のサイリウム回路のまま)
・LED:角型LED(白) x 10、角型LED(緑) x 10 を左右交互配置

Ver.1の問題点:
・光量が足りない
・光の強さがまばらで綺麗さに欠ける
・色の変更ができない(リン・ルカが出てきた場合に対応できない)


Ver.2

Ver.2では、主にこの2点の問題を解決することを目標とした。

では、まず先に、完成したVer.2を動画で紹介↓


Ver.2のスペック:
・回路:マイコン(正確にはArduino mini)使用、ボタン等含め全て自分で揃えた
・電源:電池(1/2AA, 3.6V) x 1
・LED:パワー型カラーLED x 2 を下部、上部に1ずつ配置

Ver.1における問題点のうち、「色の変更ができない」ついては、主電源とは別にプッシュスイッチを設け、それを押すたびに、

消灯 → 緑 → 黄 → ピンク → 緑/黄 → 緑/ピンク → 赤 → 青 → 消灯、以下繰り返し

という挙動をするようにプログラミングすることで解決した。
ちなみに、「緑/黄」「緑/ピンク」については、それぞれ、ミクリンのデュエット、ねぎとろデュエットがあることを予測しての準備である(ここ重要)
「赤」「青」については、単純に発色が良いこととは別に、KEIKO、KAITOも出てきてほしいという個人的な願いを込めて実装した(・・・願い届かず(´;ω;`)

「光量が足りない」「光の強さがまばらで綺麗さに欠ける」については、動画では確認しずらいが、Ver.1に比べると改善がみられる。
LEDを減らした代わりに、大電流を流すことができるパワー型を採用し、筒の方向と同じ向きに光らせることで、ある程度平均的に光らせることに成功した。
だが、未だ光の強さが足りず部分的に光量が足りないし、欲を言えば全体的にももう少し光量がほしい。
結果としてまだ検討の余地が残る結果となったが、これは次回への課題としたい。

では、このネギサイリウムVer.2の制作について、具体的な解説をしていきたいと思う。
・・・が、長くなりそうな気がするので、次の記事で。

2011-03-21

【水彩】縞パンちらり、キャッ、ミクさん


縞パンちらり、キャッ、ミクさん powered by ピアプロ
はじめて水彩でミクさん描いてみた。
ミクさんはぁはぁ。
自分で描いたミクさんペロペロしたいけど、絵の具は体に良くない成分が入ってるので良い子はやめましょう。ぐぬぬ。

2011-01-23

Arduino Pro mini でフィジカルしてみる

今回はArduinoでフィジカルしてみよう的な。
前にもちょろっとやったけど、それとは違うやつで。もうちょっと簡単に。

使ったハードウェアはこれ。
> Arduino - ArduinoBoardProMini
http://www.arduino.cc/en/Main/ArduinoBoardProMini
中でも、こいつの場合は
・3.3V 8MHz
・5V   16MHz
の2つあるわけだが、ここでは前者を選択した。
携帯することを考えるとバッテリーは少ないほうがいい。

Arduino mini小さすぎワロタwピンヘッダ、はんだ付けちゃんとできるか不安になってきた… on Twitpic
▲買ってみたら、思った以上に小さくてびっくり。

なお、Arduino Pro miniの場合、単体ではプログラムを書き込む手段がないので、別売で以下のようなUSBによるシリアル通信用の機器もセットで買う必要がある。
3.3v, 5vで製品が違うので注意。
http://www.sparkfun.com/products/9873


まずやること。ハンダ付け。
見ての通り、買ってきたArduinoには足が無いので自分でピンヘッダをハンダ付けする。





赤いのがシリアル通信用。これを接続した時に上にくるようにハンダ付けしないと、ブレッドボードにさしたときに困りるので注意。

次にやること。環境整備。
まずは通信ドライバー。
> VCP Drivers
http://www.ftdichip.com/Drivers/VCP.htm

Windowsの64bitで、2.08.08を選択。

さらにコーディング、プログラムのアップロードを行うソフトArduino IDEが必要。
> Arduino - Software
http://arduino.cc/en/Main/Software

ここから、Windows版のArduino IDE、バージョン0022をDL。



ブレッドボードで回路制作とプログラミング。
Arduinoの本とかではよくスケッチとかっていってるみたい。



回路はこんな感じ。
Resetボタンから向かって右側のVCCとGNDはそれぞれ電源の3.3V、GNDにつなげること。ここがArduinoの電源供給端子。
左側のGNDはシリアル通信用なので今回は関係ない。

構成は、以下のような感じ。
・7番ピン:スイッチ
・10-12番ピン:LED
で、以下のようなコーディング。
コーディングはArduino IDEで。

USB接続機器をPCに接続後、Arduino IDE起動。
まず行う設定は、以下の2つ。
・[Tools]-[Board] → Arduino Pro or Pro Mini (3.3v,8MHz)  w/ATmega328
 使用するArduinoを選択しておく。これがあっていないとハードにあった適切なコンパイルが
 されないので注意。
・[Tools]-[Poot] → COM6
 PCの環境によって違う。Windowsではたいてい5,6あたり。
 そもそも、USB接続機器が認識できてないとCOM1しか表示されてないはずなので、
 USB接続機器のほうがうまくいっているか確認すること。

使うのはArduinoIDE。見た目はほとんどC言語と同じ。
// スイッチで3パターンに変化するLEDx3の点灯
#define LED1 12
#define LED2 11
#define LED3 10

#define SW1  07

boolean sw1ValOld = 0;
boolean sw1Val = 0;

int state = 3;
int count = 0;
int init_port = B00000010;

void setup()
{
  //こっちだとプログラムが重くなる
  //pinMode(LED1, OUTPUT);
  //pinMode(LED2, OUTPUT);
  //pinMode(LED3, OUTPUT);
  DDRB = DDRB | B00011100;
  pinMode(SW1, INPUT);
}

void loop()
{
  static int portb;
  sw1Val = digitalRead(SW1);
  
  // スイッチ判定(立ち上がりのみおk)
  if( sw1Val == HIGH && sw1ValOld == LOW) {
    state++;
    if( state >= 3 ) state = 0;
    delay(100); // チャタリング防止。値はテキトー
  }
  // 値更新
  sw1ValOld = sw1Val;
  
  switch(state) {
  case 0: 
    //こっちだとプログラムが重くなる
    //digitalWrite(LED1, HIGH);    
    //digitalWrite(LED2, HIGH);
    //digitalWrite(LED3, HIGH);
    PORTB = B00011100;
    delay(1000);
    PORTB = B00000000;
    //こっちだとプログラムが重くなる
    //digitalWrite(LED1, LOW);    
    //digitalWrite(LED2, LOW);
    //digitalWrite(LED3, LOW);
    delay(1000);
    break;
    
  case 1: // 全部点滅早く
    //こっちだとプログラムが重くなる
    //digitalWrite(LED1, HIGH);    
    //digitalWrite(LED2, HIGH);
    //digitalWrite(LED3, HIGH);
    PORTB = B00011100;
    delay(500);
    //こっちだとプログラムが重くなる
    //digitalWrite(LED1, LOW);    
    //digitalWrite(LED2, LOW);
    //digitalWrite(LED3, LOW);
    PORTB = B00000000;
    delay(500);
    break;
    
  case 2: // 1つずつずれる
    count++;
    if(count >= 3) {
      count = 0;
      portb = init_port;
    }
    //ビットシフト使う場合はこっちでやったほうが楽
    portb = portb << 1;
    PORTB = portb;
    delay(1000);
  }
}
Arduinoは、上記で使われているsetup関数でセットアップ、その後loop関数を繰り返し実行する。
そのため、必要な初期化はsetupに、それ以外の処理の実態は全てloop関数内に書くことになる。

pinModeでピンに出力、入力をセット。
しかし、何度も使う場合は上記のように直接ポートに01を立てる方法の方が容量も負荷も小さくなることもある。

digitalReadでデジタル信号の受け取り、digitalWriteでデジタル信号の出力。
こちらも同様に、直接ポートをいじったほうがプログラム容量が小さくなる場合がある。

以下はコンパイル時に確認できるプログラムサイズ。

▲びふぉあ


▲あふたぁ

多少ではあるが、改善が見られる。
マイコンの場合は、あまり容量の大きなプログラムは乗らないので、少しでも少なくすむようにすべきである。


▲Arduino IDEのインタフェース。三角形でVerify(コンパイル)。右から2つ目の→でUpload。

コンパイルが通ったら、UploadボダンでArduinoにプログラムアップロードする。

実験結果。



プログラムでは、7番ピンにさしたスイッチを押すたびにLEDの点灯ルールが変わるようにswitch case文を使って条件分岐を書いている。
スイッチは押すたびに1000msで点滅→500msで点滅→1つずつ点灯と点灯ルールが変更になる。


思った以上に簡単だった。
むしろ、アセンブリとかH8とか少しでもかんだことある人だったらヌルイぐらいである。
ポートの処理ですらAPIにやらせようとするわけで、かなりブラックボックスにしちゃったかんじ。

さて、これで何作るかねー。

2011-01-04