This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Festivejelly's profile picture

Instructing a turtle to run a program via rednet

Started by Festivejelly, 04 April 2012 - 01:50 AM
Festivejelly #1
Posted 04 April 2012 - 03:50 AM
So ive been trawling through the forums all night trying to figure this out. Its currently 3.36am and I have work at 9 :)/>/>

So im hoping somone can help.

I have a program with arguements on my turtle called boremaster <argument>

So as an example if i run up to my turtle and type boremaster 20 it digs a tunnel 3x3 for 20 blocks forward.

Now the plan is to send commands to this turtle via rednet from my comfy datacentre. But alas ive yet to be able to call custom programs via rednet.

Ive tried the following:

[Computer]
command = 'print ("Hello world")'
rednet.open("right")
rednet.broadcast(command)
id, mess = rednet.receive()
print (mess)

[Turtle]
rednet.open("right")
id, mess = rednet.receive()
a = loadstring(mess)
a() – i know that will run it
print (a()) – print it?
rednet.broadcast(a()) – should send results..
Which was helpfully on the forums already. I can get my turtle to print no problem but when I do somthing like:

[Computer]
command = 'boremaster 20'
rednet.open("right")
rednet.send(45,command)

[Turtle]
rednet.open("right")
id, mess = rednet.receive(40)
a = loadstring(mess)
a() – i know that will run it


I get the error: attempt to call nil

Ive no idea whats going on here. Could someone please give me some advice on what to do with this?

Thanks

PS here is the boremaster code: (feel free to use it, I know its not fantastic but im trying to learn)

Spoiler

--Boremaster5000 coded by Nicholas John aka Festivejelly feel free to steal my code but gimmie credit yo.
local tArgs = { ... }
if #tArgs ~= 1 then
print( "Usage: tunnel <length>" )
return
end
-- Mine in a quarry pattern until we hit something we can't dig
local intTunnelLength = tonumber( tArgs[1] )
if intTunnelLength < 1 then
print( "Tunnel length must be positive" )
return
end
intDistanceTravelled=0
--Functions
local function beginMining(str)
for i = 1, intTunnelLength do
  --Dig out the centre column
  turtle.dig()
  sleep(0.6)
  while turtle.detect() do
  turtle.dig()
  sleep(0.6)
  end
  turtle.forward()
  turtle.digUp()
  sleep(0.6)
  while turtle.detectUp() do
  turtle.digUp()
  sleep(0.6)
  end
  turtle.up()
  turtle.digUp()
  sleep(0.6)
  while turtle.detectUp() do
  turtle.digUp()
  sleep(0.6)
  end
  turtle.up()
  --dig out the left column
  turtle.turnLeft()
  turtle.dig()
  sleep(0.6)
  while turtle.detect() do
  turtle.dig()
  sleep(0.6)
  end
  turtle.down()
  turtle.dig()
  turtle.down()
  turtle.dig()
  turtle.forward()
  turtle.back()
  --dig out the right column
  turtle.turnRight()
  turtle.turnRight()
  turtle.forward()
  turtle.dig()
  sleep(0.6)
  while turtle.detect() do
  turtle.dig()
  sleep(0.6)
  end
  turtle.up()
  turtle.dig()
  sleep(0.6)
  while turtle.detect() do
  turtle.dig()
  sleep(0.6)
  end
  turtle.up()
  turtle.dig()
  sleep(0.6)
  while turtle.detect() do
  turtle.dig()
  sleep(0.6)
  end
  turtle.down()
  turtle.down()
  turtle.forward()
  turtle.back()
  turtle.turnLeft()
  intDistanceTravelled=intDistanceTravelled+1
end
end
local function backToStart()
if intDistanceTravelled == 0 then
print(newline)
write("Error No blocks to mine")
print(newline)
else
for j = 1, intDistanceTravelled do
  turtle.back()
end
end
print(newline)
write("Mission completed")
print(newline)
end
beginMining()
backToStart()
cant_delete_account #2
Posted 04 April 2012 - 04:20 AM
First of all, command = 'print ("Hello world")'
needs to be: command = "print ("Hello world")"
a() will NOT run it, a = loadstring(mess) needs to be: a = tostring(mess)
print (a()) and rednet.broadcast(a()) need to be rednet.broadcast(a) and print(a)
command = 'boremaster 20' needs to be command = "boremaster 20"
and on the turtle, instead of doing a() and a = loadstring(mess) do: shell.run(mess)
And all should work.
cant_delete_account #3
Posted 04 April 2012 - 04:23 AM
And in your boremaster code, instead of doing print(newline) do write("n")
LostCauz #4
Posted 04 April 2012 - 04:51 AM
Actually, from what I can tell, you're close, just missing one thing (I haven't put this to the test but it should work):

[Computer]
command = 'shell.run("boremaster", 20)'
rednet.open("right")
rednet.send(45,command)

[Turtle]
rednet.open("right")
id, mess = rednet.receive(40)
a = loadstring(mess)
a() – i know that will run it


Simply executing "boremaster 20" works fine from the os, but when trying to run the program from within lua, you have to call it with a specific function (in this case shell.run(program, args …))

Hope this helps, let us know how it goes :)/>/>

P.S. First post in this community, nice to meet you all :D/>/>
Festivejelly #5
Posted 04 April 2012 - 09:36 AM
Ahh that makes sense thank you ill give it a try with the shell command.

I must say im enjoying this mod very much, and am quite supprised how many applications we can put it to use for.

When i get home ill give it a shot, thanks again.
Festivejelly #6
Posted 04 April 2012 - 09:38 AM
Meant to say thanks to both :)/>/>
Festivejelly #7
Posted 04 April 2012 - 12:46 PM
Also can i use this logic to do somthing if a msg is received?

If rednet.receive(5) then
Id, msg = rednet.receive(1)
End
LostCauz #8
Posted 04 April 2012 - 12:56 PM

The first rednet.receive is kinda redundent and you'll lose the first message that it picks up:


If rednet.receive(5) then –Whatever the message was, you've lost it at this point
Id, msg = rednet.receive(1) –This will pickup the next message.
End


You can just use:

Id, msg = rednet.receive(1)

since the computer will stop at that point until it receives a rednet message.
  • 0
Festivejelly #9
Posted 04 April 2012 - 02:55 PM
The problem is that after:
id, msg = rednet.receive(1)

I have logic:
rcdMsg = loadstring(msg)
rcdMsg()

Obviously i dont want that executed if it doesnt find anything. Maybe ill do a loop and pur in if to check value is not 0.
LostCauz #10
Posted 04 April 2012 - 04:07 PM
The computer stops doing anything once it hits
id, msg = rednet.receive(1)
and it will wait for a message before going any further.
If you're worried about it being sent an empty message (such as if another device does rednet.announce() which broadcasts an empty message) then you can check the contents of the message just after receiving it:

id, msg = rednet.receive(1)

if msg then
rcdMsg = loadstring(msg)
rcdMsg()
end

Edit: Just realized you were using the timeout parameter with rednet.received()… makes sense now :D/>/> The code above should still work though ;)/>/>
Edit edit: Cool, just found the code tags :)/>/>