yard sale

iPhoneRobot.com

(AKA: IPHONECAPTURE.COM, TOUCHMYIPOD.COM, USEMYIPHONE.COM)

iPhoneRobot was conceived in the month leading up to original iPhone launch. I wanted to bring the iCapture functionality to the iPhone, but without one in my hands and the phrase "jail break" still meaning to "escape from prison"...

Photos

Click on the photo to see the embedded notes on Flickr.

iPhoneRobot.com
Here's an overhead view.
Slightly over size Faraday cage
Finger Detail

Nothing too advanced here, never really made it past the proof of concept phase.

Orion Parrot came along for this ride, the fact that we still speak after this project still amazes me.

Special thanks to Tony Buser for the nxc and the updated ruby-nxt library.

server.rb
#!/usr/bin/env ruby -w
require "socket"
require 'nxt_comm'
$DEBUG = true
@port = (ARGV[0] || 3001).to_i
@server = TCPServer.new('10.0.1.200', @port)
@nxt = NXTComm.new
current_x = 0
current_y = 0
motor_x = 1
motor_y = 2
motor_z = 3
puts "Ready."
while (@session = @server.accept)
  @nxt.message_write 4, "reset" # allows for cheap calibration 
  @request = @session.gets
  puts "Request: #{@request}"
  @request.chomp!
  x, y, z = @request.split(",").collect{|i| i.to_i}
  send_x = current_x.to_i - x.to_i
  send_y = current_y.to_i - y.to_i
  puts send_x / send_y
  current_x = x.to_i
  current_y = y.to_i
  puts "send motor to #{send_x}, #{send_y}, 0"
  @nxt.message_write 5, "40:#{send_x}:40:#{send_y * -1}" # -1 fixes motor's native orientation
  @session.close
end
iphone.nxc
/*
  iphone.nxc
  Tony Buser - tbuser@-----.com

  To Compile:
  nbc iphone.nxc -O=iphone.rxe

  Reads mailbox x for a string in the form of power:degrees
  x being the motor port, 1 = A, 2 = B, 3 = C

  From ruby-nxt to move Motor A 180 degrees at 30 power:
  @nxt.message_write 1, "30:180"
*/

// ugly duplicate code because nxc can't use a variable for the 
// motor output with RotateMotor to move multiple motors concurrently
task check_a() {
  string cmd;
  string pow;
  string deg;
  int pos;
  int index;
  while (true) {
    ReceiveMessage(0, true, cmd);
    if (cmd != "") {
      PlayTone(440, 500);
      index = 0;
      // parse_cmd(pow, deg, cmd);
      for (pos = 0; pos < StrLen(cmd); pos++) {
        if (StrIndex(cmd, pos) == 58) {
          index = pos;
        }
      }
      pow = SubStr(cmd, 0, index);
      deg = SubStr(cmd, index + 1, StrLen(cmd) - 1);
      TextOut(0, LCD_LINE1, "Pow: " + pow + " Deg: " + deg);
      RotateMotor(OUT_A, StrToNum(pow), StrToNum(deg));
    }
    ResetAllTachoCounts(OUT_A);
  }
}
task check_b() {
  string cmd;
  string pow;
  string deg;
  int pos;
  int index;
  while (true) {
    ReceiveMessage(1, true, cmd);
    if (cmd != "") {
      PlayTone(493, 500);
      index = 0;
      // parse_cmd(pow, deg, cmd);
      for (pos = 0; pos < StrLen(cmd); pos++) {
        if (StrIndex(cmd, pos) == 58) {
          index = pos;
        }
      }
      pow = SubStr(cmd, 0, index);
      deg = SubStr(cmd, index + 1, StrLen(cmd) - 1);
      TextOut(0, LCD_LINE2, "Pow: " + pow + " Deg: " + deg);
      RotateMotor(OUT_B, StrToNum(pow), StrToNum(deg));
    }
    ResetAllTachoCounts(OUT_B);
  }
}
task check_c() {
  string cmd;
  string pow;
  string deg;
  int pos;
  int index;
  while (true) {
    ReceiveMessage(2, true, cmd);
    if (cmd != "") {
      PlayTone(261, 500);
      index = 0;
      // parse_cmd(pow, deg, cmd);
      for (pos = 0; pos < StrLen(cmd); pos++) {
        if (StrIndex(cmd, pos) == 58) {
          index = pos;
        }
      }
      pow = SubStr(cmd, 0, index);
      deg = SubStr(cmd, index + 1, StrLen(cmd) - 1);
      TextOut(0, LCD_LINE3, "Pow: " + pow + " Deg: " + deg);
      RotateMotor(OUT_C, StrToNum(pow), StrToNum(deg));
    }
    ResetAllTachoCounts(OUT_C);
  }
}
task keep_alive() {
  while (true) {
    // keeps NXT from going to sleep
    ResetSleepTimer();
    Wait(1000);
  }
}
task main() {
  TextOut(0, LCD_LINE1, "Ready");
		// run tasks in parallel
  Precedes(check_a, check_b, check_c, keep_alive);
}