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

timed redstone signal

Started by Mordlin, 02 December 2012 - 03:48 PM
Mordlin #1
Posted 02 December 2012 - 04:48 PM
Hello all, and thanks in advance for any help.

The code I am trying to come put with is one that sends a signal to start my combustion engines and keeps them running for 10 mins (time before they explode), then let them cool down re-fill and start again.

what I have right now is this http://pastebin.com/MBUjUs4, the problem I have with this program is that I don't believe my engines are getting a constant redstone signal. and also I can not see what the timer is actually on. with the print(timer) it just shows the table it creates.
Kingdaro #2
Posted 02 December 2012 - 05:07 PM
Would it be easier to just do

rs.setOutput('right', true)
sleep(600)
rs.setOutput('right', false)
instead of fiddling with timers? Or is there a specific reason you're using timers?
Mordlin #3
Posted 02 December 2012 - 05:47 PM
Well I wanted to be able to stop it at any time as well as have the amount of time they have been running on a display.
Kingdaro #4
Posted 02 December 2012 - 06:02 PM
In that case, you could run a parallel.

function runEngines()
  rs.setOutput('right', true)
  sleep(600)
  rs.setOutput('right', false)
end

function stop()
  repeat
    local _, k = os.pullEvent()
  until k == keys.backspace
  rs.setOutput('right', false)
end

print "Start engines?"
local input = read()
if input == "yes" then
  parallel.waitForAny(runReactor, stop)
end

This makes it so that you can press backspace at any time during the run to stop the process. If you still prefer to use timers, this should do the same thing:


function runEngines()
  rs.setOutput('right', true)
  local timer = os.startTimer(600)
  while true do
    local event, p1 = os.pullEvent()
    if event == "timer" and p1 == timer
    or event == "key" and p1 == keys.backspace then
      rs.setOutput('right', false)
    end
  end
end

print "Start engines?"
local input = read()
if input == "yes" then
  runEngines()
end

You can do it whichever way you feel comfortable with.
Mordlin #5
Posted 02 December 2012 - 06:21 PM
Well the first way is more straight forward, and I like that one, but if i wanted to print the 10 minute timer on a display, would i have to make my own timer to run at the same time. something like

s = 00
m = 00
for s = 0,60 do
	 s == s+1
end
	 if s = 60 do
		   m == m+1
		   s=0
	 end
Kingdaro #6
Posted 02 December 2012 - 06:33 PM
Well, you could if you wanted, but you really could just do some simple(?) math within one loop.


for i=600, 0, -1 do
  term.clear()
  term.setCursorPos(1,1)

  local minutes = math.floor(i/60)
  local seconds = i%60
  if #tostring(seconds) == 1 then -- this whole bit is just so that it adds a leading zero if seconds is one digit
    seconds = 0 .. seconds
  end
  local time = minutes..':'..seconds

  print(time)
  sleep(1)
end

It would start at 600 seconds, go to 0 seconds, and print the calculated minutes and seconds, with the seconds padded with a zero if it's only one digit. "i%60" is the same as "math.fmod(i,60)" or "the remainder of dividing i by 60".
Mordlin #7
Posted 02 December 2012 - 07:35 PM
oh wow, I have a lot to learn about this, but you have been a huge help, thank you :)/>
KaoS #8
Posted 02 December 2012 - 07:51 PM
hey Kingdaro just wanted to mention you made a little typo/derp on the first code, you forgot the () on os.pullEvent in the stop function. not really worth mentioning, just thought it's better to be safe if someone want's to use it
Kingdaro #9
Posted 02 December 2012 - 08:01 PM
hey Kingdaro just wanted to mention you made a little typo/derp on the first code, you forgot the () on os.pullEvent in the stop function. not really worth mentioning, just thought it's better to be safe if someone want's to use it
You saw nothing :P/> thanks though :D/>
KaoS #10
Posted 02 December 2012 - 08:04 PM
hey Kingdaro just wanted to mention you made a little typo/derp on the first code, you forgot the () on os.pullEvent in the stop function. not really worth mentioning, just thought it's better to be safe if someone want's to use it
You saw nothing :P/> thanks though :D/>

You didn't see anything… lets go Riko… lol you just gave me a trip down memory lane, little siblings ^_^/>

no problem. you may notice that I avoided the quote :)/>
Mordlin #11
Posted 03 December 2012 - 05:13 PM
okay after putting it all together I am running into a problem, the program runs but it does not output the redstone signal. here is what it looks like.http://pastebin.com/7KXpjKbn.


also +1ed all who helped :D/>
Kingdaro #12
Posted 03 December 2012 - 05:31 PM
A couple things,


  repeat
    local_, k == os.pullevent()
  until k == keys.backspace()

The parentheses on keys.backspace shouldn't be there, and "event" in "os.pullevent" should be capitalized.

Also, the whole timer bit at the bottom, that's actually the waiting period in between redstone signal settings. So, while removing it from the bottom, you would replace it at the top in your runEngines() function.

Here's what the entire code would be.


function countdown(text, time)
  for i = time, 0, -1 do
    term.clear()
    term.setCursorPos(1,1)
    local minutes = math.floor(i/60)
    local seconds = i%60
    if #tostring(seconds) == 1 then
      seconds = 0 .. seconds
    end
    local timeStr = minutes..":"..seconds
    print(text..' : '..timeStr)
    sleep(1)
  end
end

function runEngines()
  redstone.setOutput("left", true)
  countdown('Running engines', 600)
  redstone.setOutput("left", false)
  countdown('Cooling down', 350)
end

function stop()
  repeat
    local_, k == os.pullEvent()
  until k == keys.backspace
  redstone.setOutput("left", false)
end

print "Start engines?"
local input = read()
if input == "yes" then
  parallel.waitForAny(runEngines, stop)
end

To simplify things a bit, I've added a countdown() function at the top, which basically displays the minute and seconds text, and a text before that. So while the engines are running, it'll display "Running engines : [time]" and while cooling, "Cooling down : [time]".
Mordlin #13
Posted 03 December 2012 - 06:19 PM
You are amazing, take my +1's
Kingdaro #14
Posted 03 December 2012 - 06:20 PM
When you present yourself well, you'll usually get the best help :D/>
Mordlin #15
Posted 03 December 2012 - 06:31 PM
Okay now the final part before everything is done, getting that countdown (or the whole program) on a monitor display. the display I have set up is a 2x6

would it be

function countdown(text, time)
monitor = peripheral.wrap( "top" )
monitor.setTextScale(2) -- I think 2 is large enough maybe not
  for i = time, 0, -1 do
    term.clear()
    term.setCursorPos(1,1)
    local minutes = math.floor(i/60)
    local seconds = i%60
    if #tostring(seconds) == 1 then
	  seconds = 0 .. seconds
    end
    local timeStr = minutes..":"..seconds
    print(text..' : '..timeStr)
    sleep(1)
  end
end
Bubba #16
Posted 03 December 2012 - 06:32 PM
When you present yourself well, you'll usually get the best help :D/>

Indeed. If only more people would listen to this advice :mellow:/>
Mordlin #17
Posted 03 December 2012 - 06:41 PM
Heh, well I really do appreciate the help, I have learned a lot from this program, maybe enough to finish my turtles :D/>.
Kingdaro #18
Posted 03 December 2012 - 06:42 PM
Okay now the final part before everything is done, getting that countdown (or the whole program) on a monitor display. the display I have set up is a 2x6

would it be -codesnip-

Almost. When you get a monitor, you have to draw to that monitor as well.


function countdown(text, time)
  monitor = peripheral.wrap( "top" )
  monitor.setTextScale(2) -- I think 2 is large enough maybe not
  for i = time, 0, -1 do
    monitor.clear()
    monitor.setCursorPos(1,1)
    local minutes = math.floor(i/60)
    local seconds = i%60
    if #tostring(seconds) == 1 then
	  seconds = 0 .. seconds
    end
    local timeStr = minutes..":"..seconds
    montior.write(text..' : '..timeStr)
    sleep(1)
  end
end

There's no "monitor.print", unfortunately, but for these purposes, .write works just as well. ^^
Mordlin #19
Posted 04 December 2012 - 01:46 PM
After editing some things, and some fixes. I am running into an error I can not seem to find. I am indexing a nill value on line 28 from the parallel on line 22. here is the code from lines 22-28


function runEngines2()
  redstone.setOutput("left", ture)
  countdown("running engines", 600)
  redstone.setOutput("left", false)
  countdown("Cooling down",  350)
end
function stop()
  repeat
	  local_, k = os.pullEvent()
   until k == keys.backspace
  redstone.setOutput("left", false)
end

and on a side note, I don't know if the errors are related, but the timer at the start of the code displays correctly, but doesn't seem to be counting down that code looks as such.


function countdown(text, time)
  monitor = peripheral.wrap("top")
  monitor.setTextScale(2)
  for i = time, 0, -1 do
	monitor.clear()
	monitor.setCursorPos(1,1)
	local minutes = math.floor(i/60)
	local seconds = i%60
	if #tostring(seconds) == 1 then
		  seconds = 0 .. seconds
	end
	local timeStr = minutes..":"..seconds
	monitor.write(text..":"..timeeStr)
	sleep(1)
	end
end
Mordlin #20
Posted 04 December 2012 - 06:55 PM
I got it working, and if anyone wants a code like this here is the completed version.http://pastebin.com/N656mgMn

Thanks to all who helped this be completed quickly.