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

Rednet.send problem

Started by Anywen, 28 May 2015 - 08:39 AM
Anywen #1
Posted 28 May 2015 - 10:39 AM
Hi,

I try to make a conversation between my computer and some turtles. So, the computer will broadcast world coordinates and turtles will ask for authorization to go mining there (avoiding many turtles to go to the same place).

But for some reason, the confirmation message won't send to the turtle. I checked the senderID and the protocol used and same for receive and everything is correct…

Here's the computer code (I removed the mining algorithm to help focus on the rednet problem) :


rednet.open("top")

PROTOCOL = "MiningNetwork"

--# Mining position algorithm

while #list_position > 0 do

	--# Get world coordinate
	tempTable = list_position[#list_position]
	x = tempTable[1]
	y = tempTable[2]
	z = tempTable[3]

	--# Broadcast x and z world coordinates
	rednet.broadcast("x:"..string.format("%5d",x).."z:"..string.format("%5d",z),PROTOCOL)

	--# Receive a message asking for authorization
	local senderID,message,PROTOCOLReceive = rednet.receive(5)

	--# Verify the message
	if message:sub(3,7)==x and message:sub(16,22)=="will go"then
		rednet.send(senderID, "Ok", PROTOCOL)
		table.remove(list_position)
	end

end

And the mining turtle rednet part :


local Mining = false
rednet.open("right")
while Mining == false do

	--# Wait to receive a message from the server
	local senderID, message, protocol = rednet.receive()

	if message:sub(1,2) == "x:" then

		--# Ask for authorization
		rednet.send(senderID, "x:"..message:sub(3,7).."Z:"..message:sub(10,14).." will go", protocol)

		--# Wait for authorization
		local senderIDConfirm, messageConfirm, protocolConfirm = rednet.receive(20)
		if messageConfirm == "Ok" then
			shell.run("goto",message:sub(3,7),y,message:sub(10,14))
			Mining = true
		end	

	end
end
HPWebcamAble #2
Posted 29 May 2015 - 01:03 AM
From the computer code:

while #list_position > 0 do

Did you define list_position?

must be in the part you cut out.

Why don't you include that part anyway, just in case?
Edited on 28 May 2015 - 11:04 PM
Anywen #3
Posted 29 May 2015 - 07:41 AM
I thought it would make the read easier.

Anyway, here's link to the code without cut :

Server : http://pastebin.com/aHn6sMNC

Client : http://pastebin.com/Tg0Bzf8K
Bomb Bloke #4
Posted 29 May 2015 - 08:23 AM
Line 69 on the server will error if the turtle hasn't sent a message back to it - you can't call :sub() on nil, and message will be nil if nothing was received.

Sending both your X and Z co-ords as a single string is making things a lot harder than they need to be - especially the way you're doing it. Just send the tables, eg:

Server
while #list_position > 0 do

	--# Get world coordinate
	tempTable = list_position[#list_position]
	tempTable[4] = "go to"

	--# Broadcast x and z world coordinates
	rednet.broadcast(tempTable,PROTOCOL)

	--# Receive a message asking for authorization
	senderID,message = rednet.receive(PROTOCOL, 5)

	if type(message) == "table" and message[1] == tempTable[1] and message[3] == tempTable[3] and message[4] =="will go" then
		rednet.send(senderID, "Ok", PROTOCOL)
		table.remove(list_position)
	end
	
	sleep(1)  -- Will discard the messages from non-accepted turtles who asked for authorisation for this list position.

end

Client
local PROTOCOL = "MiningNetwork"
while Mining == false do

	--# Wait to receive a message from the server
	local senderID, message = rednet.receive(PROTOCOL)

	if type(message) == "table" and message[4] == "go to" then
		message[4] = "will go"

		--# Ask for authorization
		rednet.send(senderID, message, PROTOCOL)

		--# Wait for authorization
		local senderIDConfirm, messageConfirm = rednet.receive(PROTOCOL,5)
		if messageConfirm == "Ok" then
			shell.run("goto",message[1],y,message[3])
			Mining = true
		end    

	end
end
Anywen #5
Posted 29 May 2015 - 08:44 AM
I didn't think sending anything else than string would be possible, thank you.

So yeah, at line 69 I knew that problem and knew how to resolve it with a test but the fact that the server won't send that confirmation message was making me hopeless…
Bomb Bloke #6
Posted 29 May 2015 - 08:50 AM
How have you checked that the turtle is not receiving a message? Have you put in a print statement or something?

Assuming you're still having trouble with that, what's the distance between the turtle and the server? Wireless rednet has limited range!

Try placing a computer with a wireless modem as high as you can, then rigging it to run the repeat script on startup. That may help matters if distance is the problem.
Anywen #7
Posted 29 May 2015 - 09:12 AM
Yeah I checked with a print statement, and the server receive the ask for permission from the turtle, enter the if statement but doesn't send anything (the send instruction return false).

The distance isn't a problem, I run this on a private server with unlimited range (1'000'000'000 blocks).

I will try your code on monday and post the result.


Thanks.
Anywen #8
Posted 01 June 2015 - 08:10 AM
Line 69 on the server will error if the turtle hasn't sent a message back to it - you can't call :sub() on nil, and message will be nil if nothing was received.

Sending both your X and Z co-ords as a single string is making things a lot harder than they need to be - especially the way you're doing it. Just send the tables, eg:

Server
while #list_position > 0 do

	--# Get world coordinate
	tempTable = list_position[#list_position]
	tempTable[4] = "go to"

	--# Broadcast x and z world coordinates
	rednet.broadcast(tempTable,PROTOCOL)

	--# Receive a message asking for authorization
	senderID,message = rednet.receive(PROTOCOL, 5)

	if type(message) == "table" and message[1] == tempTable[1] and message[3] == tempTable[3] and message[4] =="will go" then
		rednet.send(senderID, "Ok", PROTOCOL)
		table.remove(list_position)
	end
	
	sleep(1)  -- Will discard the messages from non-accepted turtles who asked for authorisation for this list position.

end

Client
local PROTOCOL = "MiningNetwork"
while Mining == false do

	--# Wait to receive a message from the server
	local senderID, message = rednet.receive(PROTOCOL)

	if type(message) == "table" and message[4] == "go to" then
		message[4] = "will go"

		--# Ask for authorization
		rednet.send(senderID, message, PROTOCOL)

		--# Wait for authorization
		local senderIDConfirm, messageConfirm = rednet.receive(PROTOCOL,5)
		if messageConfirm == "Ok" then
			shell.run("goto",message[1],y,message[3])
			Mining = true
		end	

	end
end

Ok so sending tables resolved the issue, thanks again !