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

Timer Without Using Sleep()

Started by Oninuva, 31 July 2013 - 11:18 PM
Oninuva #1
Posted 01 August 2013 - 01:18 AM
Hi friends,

I am trying to create a redstone pulse output on a timer within my monitor script.

Basically I have a marquee on my monitor in my shop but people keep tampering with it. So I wish to punish them by activating my coils located under the monitor when a key is pressed.

I am using os.pullEvent() with event=="key" to activate my function which is:

rs.setOutput("left", true)
		rs.setOutput("right", true)
		sleep(4)
		rs.setOutput("left", false)
		rs.setOutput("right", false)

The problem I am having is that it stops my screen after sleep() it does not seem to continue the rest of the script. Anyway around this? That I can use the timer without pausing everything else?

text = {
"array1",
"array2",
"array3"
}

function shock()
    local timer = os.startTimer(4)
    while true do
    if event = os.pullEvent("timer")
      rs.setOutput("left", true)
    rs.setOutput("right", true)
    sleep(0)
    rs.setOutput("left", false)
    rs.setOutput("right", false)
end

mon = peripheral.wrap("top")
mon.clear()
wScreen, hScreen = mon.getSize()
function Scroll()
    for i = -#text,hScreen do
        for t = 1 #text do
            mon.setCursorPos(2, -i+1)
            mon.write(text[t])
        end
    mon.setCursorPos(2, -i)
    sleep(.3)
    mon.clear()
    end
end

while true do
    Vertical()
end



local event = os.pullEvent()
 if(event == "char") then
    shock()
end



Lyqyd #2
Posted 01 August 2013 - 01:42 AM
Split into new topic.

You should post the whole code so that we can provide more useful advice. Essentially, you will want to use os.startTimer and the subsequent timer events to deal with any time delayed actions you want to incorporate.
TheGamerOfAction #3
Posted 01 August 2013 - 05:13 AM
[This information is completely incorrect and has been removed as to prevent confusion. -L]
Lord_Spelunky #4
Posted 01 August 2013 - 09:12 AM
well you could do os.startTimer(<how long you want it to be>)
then do os.pullEvent() and it will trigger an event
Oninuva #5
Posted 01 August 2013 - 11:12 AM
Here is the code:


text = {
"array1",
"array2",
"array3"
}

function shock()
local timer = os.startTimer(4)
while true do
if event = os.pullEvent("timer")
   rs.setOutput("left", true)
rs.setOutput("right", true)
sleep(0)
rs.setOutput("left", false)
rs.setOutput("right", false)
end

mon = peripheral.wrap("top")
mon.clear()
wScreen, hScreen = mon.getSize()
function Scroll()
for i = -#text,hScreen do
  for t = 1 #text do
   mon.setCursorPos(2, -i+1)
   mon.write(text[t])
  end
mon.setCursorPos(2, -i)
sleep(.3)
mon.clear()
end
end

while true do
Vertical()
end

local event = os.pullEvent()
if(event == "char") then
shock()
end


I also added it to the first post.

I am having trouble with how to start the second part of the function which is turning off the rs output.
immibis #6
Posted 01 August 2013 - 07:48 PM
Post your original code that used sleep and didn't use timer, so we can see more clearly what the problem was with it.
MR_nesquick #7
Posted 01 August 2013 - 07:54 PM


local timer = os.startTimer(4)

while true do
local event,param1 = os.pullEvent()

if  param1 == "Q" then
	break
elseif event == "char"  then
	shock()
elseif event == "timer"  then
	--some code
	timer = os.startTimer(4)
end
end
i think this works. not tested but i think

edit: smal derp there… new code

Edit by Bubba: You redefine the timer ID within the loop as local. That won't work. It needs to modify the parent timer ID and local will create a new instance. did not know that. thanks for fixing my faults
Edited by
Symmetryc #8
Posted 02 August 2013 - 12:41 AM
 while true do local timer = os.startTimer(1) local event,param1 = os.pullEvent() if event == "char" then shock() elseif param1 == "Q" then break elseif event == "timer" then --some code end end
i think this works. not tested but i think
You might want to start a new timer only after the old timer is done, not after every single event :P/>.
Oninuva #9
Posted 03 August 2013 - 02:30 PM
Post your original code that used sleep and didn't use timer, so we can see more clearly what the problem was with it.

Well the original code without the timer was basically:


if(event=="char")
then

rs.setoutput(side, true)
sleep(4)
rs.setoutput(side,false)

What I wish to do is:

if event == char

then turn on redstone signal for 4 seconds, then turn it back off.

When I was using sleep(4) it would turn on and off but it would also pause everything that was moving on the screen (it's a marquee). How would I alter my timer so that I would turn the redstone off? Thanks!
immibis #10
Posted 03 August 2013 - 08:30 PM
Post your original code that used sleep and didn't use timer, so we can see more clearly what the problem was with it.

Well the original code without the timer was basically:


if(event=="char")
then

rs.setoutput(side, true)
sleep(4)
rs.setoutput(side,false)

What I wish to do is:

if event == char

then turn on redstone signal for 4 seconds, then turn it back off.

When I was using sleep(4) it would turn on and off but it would also pause everything that was moving on the screen (it's a marquee). How would I alter my timer so that I would turn the redstone off? Thanks!
The whole code.
Bubba #11
Posted 03 August 2013 - 09:19 PM
The whole code.

Please look at the OP's first post. And the fourth post.

@OP
I see that you are pulling the timer event with os.pullEvent("timer")

Remove that "timer" bit and you'll be able to pull all events. Then check what kind of event is returned by the pullEvent and respond accordingly.
Example:

local event, param = os.pullEvent()
if event == "timer" then
  --#Respond to the timer
elseif event == "char" then
  --#Respond to the character press
end

MR_nesquick's example should work for what you want, but don't just copy/paste. Read it and try to figure out how it works.
immibis #12
Posted 03 August 2013 - 09:38 PM
The whole code.

Please look at the OP's first post. And the fourth post.

@OP
You can use timers to do what you want. Check it out on the wiki here.
MR_nesquick provided an example, but you should give this program a shot yourself. If you can't figure it out go ahead and experiment with what MR_nesquick wrote.
The whole original code, using sleep instead of timers.
Bubba #13
Posted 03 August 2013 - 09:46 PM
The whole original code, using sleep instead of timers.

Why do you want his original code? He now has code that uses timers, and that's the code that needs fixing. His old code is irrelevant.
immibis #14
Posted 03 August 2013 - 11:13 PM
The whole original code, using sleep instead of timers.

Why do you want his original code? He now has code that uses timers, and that's the code that needs fixing. His old code is irrelevant.
Because it's better to work from working code than from not-nearly-working code (like what's in the first post)
albrat #15
Posted 04 August 2013 - 12:55 PM
There are a lot of mistakes in the OP's code. I myself do not believe that this is the entire code.

For a start that code would not event run, let alone pause while displaying a message.

* bad if statement on line 10
* un - ending function.
* no ending to the while true do loop.

also it would pause everything while it does the screen scroll.
The program also calls a function named Vertical() – this is not defined anywhere.
The function scroll is not called anywhere.
Vertical() is wrapped in a while true do loop that has no exit so the final part of the code will never execute.

End of errors I want to list so far.

on the point of the trigger of the redstone on / off… we already have a sleep(0.3) for the screen scroll… so if we take this a bit further (conditional scripting) we could count how many updates the scroll does then calculate 4 seconds. and say roughly 13 occurances gives just shy of 4 seconds….

eg.
local event = os.pullEvent()  -- this will pause the script untill an event occurs btw ...
if (event==char) then activate = true x=0 end -- if the event is the char setup our counter and our varible activate
redstone.setOutput(side , activate)
if activate then x=x+1 end
if x > 13 then x = 0 activate = false end

with that it counts the cycles past the if statment (regulated by our scrolling text sleep). if we hit our count of 13 it resets x, turns the varible activate to false, and on the next cycle sets the redstone to off.

does the job and no sleep to wait for the turning off…
Edited on 04 August 2013 - 11:43 AM
immibis #16
Posted 04 August 2013 - 07:11 PM
There are a lot of mistakes in the OP's code. I myself do not believe that this is the entire code.
That is his attempt at converting his (working) code that used sleep to use timers. I was asking for the original code that used sleep, for a better idea of what his program does and how it works.