« [iPhone][Jailbreak]iPhoneにつないだキーボードから文字を入力してみた | Main | [iPhone]iPhone 3Gにヘッドホンアンプをつないでみた »

2008.11.04

[iPhone][AVR][Jailbreak]自走式iPhoneを作ってみた

iPhoneのシリアルポートを使った工作が面白いので、今度は「自走式iPhone」を作ってみた。

Selfpropellediphone01

ハードウェア

ベースは、TAMIYAの楽しい工作シリーズNo.68「壁づたいねずみ工作基本セット」。 CPUボード&開発環境にArduino(ボードはArduino Diecimila)を利用。

Selfpropellediphone02

ArduinoのProtoShield上にモータードライバのTA7291P (PDF)を二つ設置、これでモーターを制御。 TA7291P×2の入力ピン計4本に、ArduinoのPWM出力ができるピン、5, 6, 9, 10を接続。 自走式iPhoneの重量に耐えるため、AA×4本を直列につないだ電源でモーターを駆動。

Selfpropellediphone03

そのほか、Arduinoの電源となる009P電池、そこから安定化した5Vを作るレギュレータ回路なども載ってぶら下がっている。

Selfpropellediphone04

Selfpropellediphone05

ソフトウェア

Arduinoのソフトウェアは、シリアル通信を監視して、コマンド文字が来たらそれに応答、という簡単なもの。 コマンド文字に応じて、TA7291Pの所定のピンをHレベルにする。 PWM制御できるポートを使っているので、一応0〜255までの256段階でモーターのスピードを調整できるが、トルクが無いのでなかなか調整が難しい。

#define FORWARD 1
#define BACKWARD 2
#define STOP 3
#define RIGHT 4
#define LEFT 5

int rightForward = 10;
int rightBackward = 9;
int leftForward = 6;
int leftBackward = 5;

int incomingByte = 0;
int spd = 100;
int currentVector = STOP;

void setup() {
  pinMode(rightForward, OUTPUT);
  pinMode(rightBackward, OUTPUT);
  pinMode(leftForward, OUTPUT);
  pinMode(leftBackward, OUTPUT);

  Serial.begin(9600);
  Serial.println("start");
}

void loop() {
  if(Serial.available() > 0)
  {
    incomingByte = Serial.read();
    Serial.println(incomingByte);
    switch (incomingByte) {
      case 120:
        goBackward(spd);
        break;
      case 119:
        if (spd > 0)
        {
          spd -= 10;
        }
        updateSpeed();
        //Serial.println(spd);
        break;
      case 115:
        turnLeft(spd);
        break;
      case 113:
        if (spd <= 250)
        {
          spd += 10;
        }
        updateSpeed();
        //Serial.println(spd);
        break;
      case 101:
        goForward(spd);
        break;
      case 100:
        turnRight(spd);
        break;
      case 97:
        stop();
        break;
    }
  }
}

void updateSpeed()
{
  switch (currentVector)
  {
    case LEFT:
      turnLeft(spd);
      break;
    case RIGHT:
      turnRight(spd);
      break;
    case STOP:
      stop();
      break;
    case BACKWARD:
      goBackward(spd);
      break;
    case FORWARD:
      goForward(spd);
      break;
  }
}

void goForward(int spd)
{
  stop();
  analogWrite(leftForward, spd);
  analogWrite(rightForward, spd);
  currentVector = FORWARD;
}

void goBackward(int spd)
{
  stop();
  analogWrite(leftBackward, spd);
  analogWrite(rightBackward, spd);
  currentVector = BACKWARD;
}

void turnRight(int spd)
{
  stop();
  analogWrite(leftBackward, spd);
  analogWrite(rightForward, spd);
  currentVector = RIGHT;
}

void turnLeft(int spd)
{
  stop();
  analogWrite(leftForward, spd);
  analogWrite(rightBackward, spd);
  currentVector = LEFT;
}

void stop()
{
  analogWrite(rightForward, 0);
  analogWrite(rightBackward, 0);
  analogWrite(leftForward, 0);
  analogWrite(leftBackward, 0);
  currentVector = STOP;
}

iPhone上で動かすソフトウェアは、適当なポートでListenし、送られてきた文字をシリアルポートにフォワードするというもの。 この働きで、iPhoneが無線モジュールとして機能することになる。これはRubyで書いた。

#!/usr/bin/env ruby

require "socket"
require "serialport"

class Arduino

  def initialize(serialport = "/dev/tty.iap", serverport = 12345)

    if (not File.exist?(serialport))
      raise "ERROR: Specified device does not exist."
    end
    @sp = SerialPort.new(serialport, 9600, 8, 1, SerialPort::NONE)

    @gs = TCPServer.open(serverport)
    while true
      @socks = [@gs]
      @addr = @gs.addr
      @addr.shift
      printf("server is on %s\n", @addr.join(":"))
      run()
    end
  end
  def run()
    while true
      nsock = select(@socks)
      next if nsock == nil
      for s in nsock[0]
        if s == @gs
          @socks.push(s.accept)
          print(s, " is accepted\n")
        else
          if s.eof?
            print(s, " is gone\n")
            s.close
            @socks.delete(s)
          else
            str = s.gets
            if str.chomp == "end"
              s.close
              return
            end
            @sp.puts(str)
          end
        end
      end
    end
  end
end

arduino = Arduino.new("/dev/tty.iap", 12345)

クライアントは特に書いてないので、telnetから操作した。

$ telnet 192.168.0.5 12345

なかなか面白い遊びであった。

|

« [iPhone][Jailbreak]iPhoneにつないだキーボードから文字を入力してみた | Main | [iPhone]iPhone 3Gにヘッドホンアンプをつないでみた »

Comments

すげ!!!!
感激!!!!

Posted by: titan | 2008.11.04 at 10:12 PM

コメントありがとうございます。
少しでも笑っていただければ、私としては満足です。

Posted by: moyashi | 2008.11.05 at 03:46 PM

 すごっ! いですねgood
 着ぐるみ着せたくなります( ^ω^ )

 ブログで紹介したいので画像転載させてもらっていいでしょうか?

Posted by: ひらぱー | 2008.11.06 at 12:58 PM

ひらぱーさんどうもです。
たびたびお世話になっております。
画像転載構いませんよ。
よろしくお願いします。

Posted by: moyashi | 2008.11.06 at 03:22 PM

簡単ですが紹介をさせていただきました!
とりあえず、
クリケにひげでもつけましょうか┐( ̄ヘ ̄)┌ フゥゥ~

Posted by: ひらぱー | 2008.11.06 at 04:59 PM

Endgadgetに掲載されましたね。
おめでとうございます。
http://www.engadget.com/2008/11/06/iphone-robot-is-ambulatory-still-wants-physical-keyboard/

世界は次なるアソビゴコロに注目してます(^^)

Posted by: Jack Oatmon | 2008.11.06 at 09:58 PM

チョロリンしっぽに心を奪われました(^_^)

Posted by: milo | 2008.11.07 at 08:09 AM

>> ひらぱーさん
どうせバカやるなら、デコレーションもハデにやりたいところですね。

>> Jack Oatmonさん
ありがとうございます。
次なるネタ……。だんだん辛くなってきました。

>> miloさん
案外こういう車輪ものも面白いですよ。
タミヤの基本工作セット系のパーツを買い込んできました。
工作版ブレッドボードみたいな感じでいいですね。

Posted by: moyashi | 2008.11.10 at 05:44 PM

スピード制御ですが、トルクを一定にするのであれば
電流制御のPWMが良いでしょう。
ただし、坂道など負荷が軽くなるとスピードが速くなるので要注意ですね。

Posted by: | 2008.11.10 at 07:01 PM

Your most actual amateur resources here http://amateur.goodnanoav.com/

Posted by: phisdiple | 2009.06.01 at 08:30 AM

The comments to this entry are closed.

« [iPhone][Jailbreak]iPhoneにつないだキーボードから文字を入力してみた | Main | [iPhone]iPhone 3Gにヘッドホンアンプをつないでみた »