Jump to content




Rednet Controlled Mining Turtle (Cobble Generator)


  • You cannot reply to this topic
10 replies to this topic

#1 Matplotlib

  • Members
  • 6 posts

Posted 18 September 2013 - 07:36 AM

I've a problem with activating (here, desactivating) a turtle using rednet... I have a total of 4 programs.
The 3 firsts in the main computer (id 46) :
--startup program
rednet.open("back")
term.clear()
term.setCursorPos(1 ,1)
print("Controle de la Generation de Cobble (on / off)")
--on program
rednet.send(45,"on")
term.clear()
term.setCursorPos(1, 1)
print("Controle de la Generation de Cobble (on / off)")
--off program
rednet.send(45,"off")
term.clear()
term.setCursorPos(1, 1)
print("Controle de la Generation de Cobble (on / off)")

Then, in the Turtle (id 45), I've written this :
--startup program
rednet.open("right")
local id, message, dist = rednet.receive()
while true do
  if message == "on" then
	if turtle.detect() then
	turtle.dig()
	  if message == "off" then
		break
	  end
  end
  elseif message == "off" then
	break
  end
end
os.reboot()

My problem is that the turtle starts mining perfectly well, but it's impossible to stop it (except manually of course)

#2 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 18 September 2013 - 09:44 AM

Split into new topic.

Once you start the while loop, you aren't actually checking for any new rednet messages, so the value of the "message" variable will never change.

#3 kreezxil

  • Members
  • 128 posts
  • LocationBowie, TX

Posted 18 September 2013 - 09:28 PM

Move these two lines around where you have now
local id, message, dist = rednet.receive()
while true do
to
while true do
local id, message, dist = rednet.receive()
I'm willing to bet that solves your current problem.

#4 Matplotlib

  • Members
  • 6 posts

Posted 19 September 2013 - 02:22 PM

Okay, so I tried what you both told me, so Lyqyd, it's still not working with the while loop like this :
local id, message, dist = rednet.receive()
while message == "on" then
  --code
end

Then, Kiddie, the turtle now doesn't turn on ; it means that it kind of don't receive the message...

Edit : Don't worry, if nothing works fine, I'll implement a manual system inside of the turtle itself !

#5 kreezxil

  • Members
  • 128 posts
  • LocationBowie, TX

Posted 19 September 2013 - 06:39 PM

View PostNervaL928, on 19 September 2013 - 02:22 PM, said:

Okay, so I tried what you both told me, so Lyqyd, it's still not working with the while loop like this :
local id, message, dist = rednet.receive()
while message == "on" then
  --code
end

Then, Kiddie, the turtle now doesn't turn on ; it means that it kind of don't receive the message...

Edit : Don't worry, if nothing works fine, I'll implement a manual system inside of the turtle itself !

How is this what I and Lyqyd told you to try, your example of what you said you have done looks no different than your original code that is broken. You need this loop
--startup program
rednet.open("right")
while true do
    --[[ having the following here will initialize the variables each time through the loop including the first time, which is what you want. ]]
    local id, message, dist = rednet.receive()
    if message == "on" then
        if turtle.detect() then
            turtle.dig()
            --[[ why is the following here? message is already "on" therefore the following is an unecessary if block ]]
            if message == "off" then
                break
            end
            --[[ end of wtf code ]]
       end
    elseif message == "off" then
        break
    end
end
os.reboot()


#6 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 19 September 2013 - 09:39 PM

Or really, since cobble generation is very simple, we can ignore the return value from the dig (and the detect!) and just base it on a short delay:

rednet.open("right")
local cobble = false
os.startTimer(0)

while true do
  event = {os.pullEvent()}
  if event[1] == "rednet_message" then
    if event[2] == "on" then
	  cobble = true
    elseif event[2] == "off" then
	  cobble = false
    end
  elseif event[1] == "timer" then
    if cobble then
	  turtle.native.dig()
    end
    os.startTimer(0.8)
  end
end


#7 immibis

    Lua God

  • Members
  • 1,033 posts
  • LocationWellington, New Zealand

Posted 20 September 2013 - 03:09 AM

View PostLyqyd, on 19 September 2013 - 09:39 PM, said:

Or really, since cobble generation is very simple, we can ignore the return value from the dig (and the detect!) and just base it on a short delay:

rednet.open("right")
local cobble = false
local timer = os.startTimer(0) -- edit here

while true do
  event = {os.pullEvent()}
  if event[1] == "rednet_message" then
    if event[2] == "on" then
	  cobble = true
    elseif event[2] == "off" then
	  cobble = false
    end
  elseif event[1] == "timer" and event[2] == timer then -- and here
    if cobble then
	  turtle.native.dig()
    end
    timer = os.startTimer(0.8) -- and here
  end
end

Fixed, in case another program (or even CraftOS) is running other timers at the same time.

#8 kreezxil

  • Members
  • 128 posts
  • LocationBowie, TX

Posted 20 September 2013 - 06:00 AM

View Postimmibis, on 20 September 2013 - 03:09 AM, said:

Spoiler

Fixed, in case another program (or even CraftOS) is running other timers at the same time.

How is capturing the return value os.startTimer(x) via a declared variable any different than not capturing the return value at all? I really want to know as I am still learn too. :huh:

#9 theoriginalbit

    Semi-Professional ComputerCrafter

  • Moderators
  • 7,332 posts
  • LocationAustralia

Posted 20 September 2013 - 06:30 AM

View Postkreezxil, on 20 September 2013 - 06:00 AM, said:

How is capturing the return value os.startTimer(x) via a declared variable any different than not capturing the return value at all? I really want to know as I am still learn too. :huh:
os.startTimer returns an id of the timer that has been created, the reason that this is a good thing to capture is because sometimes there can be multiple timers running, not just in your program, but in other things running at the same time too. When a timer finishes the return from os.pullEvent/Raw and coroutine.yields will contain the id of the timer that has finished as well, you can then compare this against what you stored earlier to see if it was your timer that finished or a different timer.

Problematic code
os.startTimer(1) --# assume another program has done this
os.startTimer(2) --# we do this one

while true do
  if event[1] == "timer" then
    break
  end
end

print("Two seconds have passed")
Well in this code, no 2 seconds haven't passed, only 1 has. Now lets fix the code
os.startTimer(1) --# again not ours, some other program
local timeout = os.startTimer(2) --# our timer

while true do
  local event = { os.pullEvent() }
  if event[1] == "timer" and event[2] == timeout then
    break
  end
end

print("2 seconds have passed")
In this example 2 seconds really have passed because we are only responding to our timer, not just any timer.

summary/tl;dr never assume you're the only one making timers, save the id returned from creating the timer and then when it finishes make sure its the one you started

#10 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 20 September 2013 - 12:44 PM

Yeah, catching that return value probably isn't a bad idea! Otherwise, one could end up with many more timers than desired. Exponentially more, if another program was exhibiting the same behavior.

#11 kreezxil

  • Members
  • 128 posts
  • LocationBowie, TX

Posted 21 September 2013 - 05:41 AM

You guys are awesome!





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users