
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"...
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);
}