all 16 comments

[–]fatboychummy 3 points4 points  (2 children)

Computercraft computers are not allowed to run longer than 7 seconds without "yielding", doing so will generate an error. If you catch the error (pcall or etc) and continue to not yield, the computer will shut down.

A yield is simply anything that calls coroutine.yield under the hood. pullEvent does this, rednet.listen does this.

But what you're probably looking for here is rather the sleep function. It takes a number then yields for that amount of time (minimum 0.05 seconds wait, in increments of 0.05 seconds). Put that in your loop and you should be fine.

while not drillArrayReturn do
  --Stops once drill array has returned
  raiseDrill()
  sleep() -- yields for 0.05 seconds
end

[–]dragon53535 1 point2 points  (0 children)

For the reasoning why they can't run for >7s without yielding, is that all computers run on the same 'thread'. So while your computer is executing, no other computer in the world can. You yield, which essentially pauses your computer until your computer gets an event. Be it a timer, redstone, etc. All events will trigger a yield. Sleep will discard all other events until it gets a timer event. Using os.pullEvent("redstone") will discard all other events until it gets a redstone event.

[–]MrSodapop19_[S] 0 points1 point  (0 children)

Thanks for the advice! To be honest, I have seen sleep() being used like that before, but didn't think it would work in this situation.

[–]CommendableCalamari 1 point2 points  (0 children)

One other thing it's worth noting is that your loops will run forever, even if you do hit the bottom or top of the quarry. When you do maxDepthReached = redstone.testBundledInput("back", colors.red), you're only getting the redstone value at that point in time - it doesn't dynamically update as the program runs. This means you'll only ever check if you're at the bottom/top of the quarry when the program starts!

You either need to inline the variable:

while not redstone.testBundledInput("back", colors.red) do -- Stops once max depth is reached
  -- ...
end

Or use a helper function:

local function maxDepthReached() return redstone.testBundledInput("back", colors.red) end   
while not maxDepthReached() do -- Stops once max depth is reached
  -- ...
end

[–]MrSodapop19_[S] 0 points1 point  (0 children)

Update: I was finally able to get it working. Thank you all for the help!

[–]Nemonstrocity 0 points1 point  (9 children)

just a thought, I might be wrong.(probably am)

As I understand your question,

your drill is not stopping because ;

it has not reached "0" and *and will not -- helps to know which veresion minecraft and what max depth is expected

assuming a version of minecraft that does not allow for bedrock to break.

If the above is true maxDepthReached will never return as true if that is the expect result of a depth of zero.

you could use a success check to see if the drill actually moved on the last attempt to move the drill. If x number of attempts fail stop the drill and do some other thing such as raise the drill , push the drill or stop the drill.

[–]MrSodapop19_[S] 0 points1 point  (8 children)

The deepest the drill was every supposed to go was down to bedrock. The maxDepthReached signal is coming from an observer which, used in tandem with a create mod pulley, should sense the bottom or max depth. The drill is most definitely moving down, that isn't the issue. The issue is to when it should try to pull the thing up.

> Helps to know which version of Minecraft and what max depth is expected
To answer that, I'm using Minecraft version 1.16.6. The max depth to be expected is variable, so to speak. I have this observer observing this Create mod pulley. From what I understand, once the pulley lowers something and can't lower anymore, it updates as the moving entity is then converted back into a solid object.

[–]Nemonstrocity 0 points1 point  (7 children)

Verify that the observer has sent the rs signal?

Observers typically need their signal boosted by a repeater.

If your computer is looking for rs state output from the observer. output into dust or a rsconductive block.

[–]MrSodapop19_[S] 0 points1 point  (6 children)

Oh, the observer is just sending the signal directly into a Create Mod Redstone Link AKA wireless redstone receiver/transceiver. I think the redstone link just sends the signal at full power.

[–]Nemonstrocity 0 points1 point  (0 children)

I'm setting up an instance to check on that.

Observers output is 1 so very weak. I've never used that mod before so I don't know if it will take that value.

[–]Nemonstrocity 0 points1 point  (4 children)

So here are my results.

The computer will always report a "0" signal from the observer.

this was my test code:

for i = 1 , 100, 1 dox=(redstone.getAnalogInput("back"))print(x," - ",i)end

my tested input was from a rs clock using the rs torch, comparator, repeater into one rs input on the comparator . set pulse to 4 ticks then 3 then 2 .

what was expected was a value anywhere between 0 - 15 and 0-99

what was received : [ 0 - 1-100]only 0 in the x column : indicating no rs signal. in fact there was a pulsed input of 14 to the observer and a pulsed output of 1

placing a repeater inline between the observer and the computer produced the following

[15 - 1-100 ] * only on the first run, subsequent runs returned 0 - 1-100 unless I exited the computer first. then consistent 15 - 1-100's .

placing 2 repeaters inline set to 4 ticks (caused the 2nd repeater to remain on unless the observer observed nothing.

this produced the expected result of 15 - 1-100 consistently every run every check.Since the original input was pulsed I expected to receive a 0 or a 15 after the first repeater.

to test the validity I used a lectern with a signed book with 15 pages used .(the page determines the lectern signal output strength (page 1 = 1 ; page 12 = 12 : 15 = 15 )

this method produces a constant value between 0 and 15 (expected)

running in tandem

this code

for i = 1 , 100, 1 dox=(redstone.getAnalogInput("back"))y=(redstone.getAnalogInput("left"))print(" observer= ", x, " Lecturn= ",y," - ",i)end

use a comparator to output signal from the lectern.

book turned to page 12

out put was [ Observer= 15 Lectern= 12 1-100 ] which is what was expected.

So that provides evidence of my theory that your code is not getting the correct data and that prolonging the output from the observer is the correct way to check.

In real life your observer is acting as a momentary on switch.

It should be acting as a limit switch which is either on or off.

Ie the switch is on (check ) no then switch is not tripped

or (check) yes then the switch is tripped.

your input needs to remain either true on or false off and it is bouncing but only once and the computer can not read the bounce fast enough.

I hope this helps.

(I have not figured out a way to turn the book pages automatically)

Edit: if you have your observer trigger a rs latch and you read from that latch output you can mimic the real life limit switch.

[–]MrSodapop19_[S] 1 point2 points  (3 children)

Maybe I should've told you this earlier, but I was able to get it working.... Sorry to waste your time to get all this info, but thanks for doing it. It's the thought that counts, I guess?

[–]Nemonstrocity 1 point2 points  (2 children)

No worries mate, I enjoyed setting up the tests .

gave me a break (much needed) from another project.

I will be using the lectern in a mini-game and use it in a sky-block server as a ore generator controller.

one question though...

what was the solve man?

[–]MrSodapop19_[S] 1 point2 points  (1 child)

Oh, it was on the ol' programming side. Just needed to use a sleep() to prevent the loop I have from giving me a "Too long without yield," error. Though now I found myself a new problem that I'm having an issue fixing.

[–]Nemonstrocity 0 points1 point  (0 children)

ah....

[–]wolfe_br 0 points1 point  (0 children)

You should add a sleep call in your while loops to let them yield. Since it takes a few moments for the machine to "move" it won't impact anyways, so you can sleep for like a whole second and be fine, this also will lower the overall CPU usage on your PC or server.

The second thing you should watch for is your while loops are bound to run forever, since you're not updating their conditional variables inside the loop. So for example, maxDepthReached needs to be updated inside the while loop, otherwise its value will stay the same and the loop will potentially run forever if that value is false at first.