2012年12月14日

Raspberry PiでSPG20-1332を回す

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

Raspberry Piで秋月電子で売っている安いステッピングモーター(コパル製 SPG20-1332)を回す。
以前、Arduinoで二相励磁駆動させたものをRaspberry Piでやってみました。



回路は以下の様な感じで。


Raspberry PiのI/Oは3.3V系なので、トランジスタアレイ(TD62004APG)を入れてレベルシフトしています。

#include <stdio.h>

int main()
{
    int i;
    
    system("echo \"7\" > /sys/class/gpio/export");
    system("echo \"8\" > /sys/class/gpio/export");
    system("echo \"9\" > /sys/class/gpio/export");
    system("echo \"10\" > /sys/class/gpio/export");
    system("echo \"out\" > /sys/class/gpio/gpio7/direction");
    system("echo \"out\" > /sys/class/gpio/gpio8/direction");
    system("echo \"out\" > /sys/class/gpio/gpio9/direction");
    system("echo \"out\" > /sys/class/gpio/gpio10/direction");
    
    for (i=0; i<360; i++) {
            system("echo \"1\" > /sys/class/gpio/gpio7/value");
            system("echo \"1\" > /sys/class/gpio/gpio8/value");
            system("echo \"0\" > /sys/class/gpio/gpio7/value");
            system("echo \"1\" > /sys/class/gpio/gpio8/value");
            system("echo \"1\" > /sys/class/gpio/gpio9/value");
            system("echo \"0\" > /sys/class/gpio/gpio8/value");
            system("echo \"1\" > /sys/class/gpio/gpio9/value");
            system("echo \"1\" > /sys/class/gpio/gpio10/value");
            system("echo \"0\" > /sys/class/gpio/gpio9/value");
            system("echo \"1\" > /sys/class/gpio/gpio10/value");
            system("echo \"1\" > /sys/class/gpio/gpio7/value");
            system("echo \"0\" > /sys/class/gpio/gpio10/value");
    }
    
    system("echo \"7\" > /sys/class/gpio/unexport");
    system("echo \"8\" > /sys/class/gpio/unexport");
    system("echo \"9\" > /sys/class/gpio/unexport");
    system("echo \"10\" > /sys/class/gpio/unexport");
}
480ステップで1回転なので、120回ループしてあげれば1回転、上記では360回ループなので3回転します。

とりあえず動かすだけなので、system関数でシェルを呼び出す感じのへたれコード。
本格的に使うならレジスタを直で叩く方が良いと思います。(速度的に雲泥の差)

追記:PythonでRPi.GPIOを利用して上記をそっくりそのまま写すならこんな感じかな?(未検証)
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(7,GPIO.OUT)
GPIO.setup(8,GPIO.OUT)
GPIO.setup(9,GPIO.OUT)
GPIO.setup(10,GPIO.OUT)
    
for i in range(0,360):
      GPIO.output(7,GPIO.HIGH)
      GPIO.output(8,GPIO.HIGH)
      GPIO.output(7,GPIO.LOW)
      GPIO.output(8,GPIO.HIGH)
      GPIO.output(9,GPIO.HIGH)
      GPIO.output(8,GPIO.LOW)
      GPIO.output(9,GPIO.HIGH)
      GPIO.output(10,GPIO.HIGH)
      GPIO.output(9,GPIO.LOW)
      GPIO.output(10,GPIO.HIGH)
      GPIO.output(7,GPIO.HIGH)
      GPIO.output(10,GPIO.LOW)

GPIO.cleanup()
ループ部分は以前の記事に近い形で書き直せるはず。(放置)

2012年12月11日

電子工作フェスティバル2012

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

卓球玉に絵を描く「ピンポン玉お絵かきロボット」が電子工作コンテスト2012で学生賞とはんだづけカフェ賞を受賞したので、12月9日開催の電子工作フェスティバル2012に参加してきました。

こういうタイプの催し物は初参加で戸惑っているところ、ブースでお隣にいらっしゃった「無限音階オルガン"nanorgan"」の方に色々とサポートしてもらい助かりました...

説明に大忙しで展示ブースから離れられず、他の方々の作品はあまり見ることが出来なかったのが残念なところ。

熊本に帰ってきたら次は12/15のハードウェア・組み込み系勉強会向けの準備で忙しい(((( ;゚Д゚)))

追記
地味にアキバblogに載ってます... (記事中程)
http://blog.livedoor.jp/geek/archives/51374038.html

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で遊ぶ、なんて使い方にも優しい設計。

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