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

Simple Countdown Timer help

Started by daveibo1, 16 April 2013 - 02:13 AM
daveibo1 #1
Posted 16 April 2013 - 04:13 AM
Very new to programming, but I've managed a few simple scrolling text monitors (for server rules etc) but we've now implemented a railroad system and there is a 45 second wait between each departure from the station. Idealy I need to write a program that displays how long is left until the next departure. When the computer recieves a redstone singal, it begins the countdown from the 45 second mark to 0 seconds which indicates to the next player that their cart is ready for departure. I've read through a fair few threads and bits of code here and there but find it very difficult deciefer a lot of the code. If anyone could offer any help in this regard it would be greatly appricated.

Cheers.
LordIkol #2
Posted 16 April 2013 - 04:25 AM
Im Typing from the phone so don't expect to much for now but i would do sth like this.

For The redstone Signal Part i can help when im back Home or you check The Wiki for os.pullevent or rs.getInput

I recommend the code that thebit posted. This method is unessecary for your case :)/>

local Countdown = 45
local Start = math.floor(os.clock())
local running = 0

while true do
running = math.floor(os.clock()) - Start
print("Next Train arrives in " ..Countdown - running .."seconds"
sleep(0.5)
end
theoriginalbit #3
Posted 16 April 2013 - 04:30 AM
Im Typing from the phone so don't expect to much for now but i would do sth like this.

local Countdown = 45
local Start = math.floor(os.clock())
local running = 0

while true do
running = math.floor(os.clock()) - Start
print("Next Train arrives in " Countdown - running .."seconds"
sleep(0.5)
end
you have a bug in the print statement… but why use os.clock() why not just do this

local count = 45
while true do
  print('Next train arrives in '..count..' seconds')
  sleep(1)
  count = count - 1
  if count < 0 then count = 45 end
end

EDIT: Also even though you are on your phone you can still type [code][/code] tags, so please use them, you should know that by now!
Edited on 16 April 2013 - 02:31 AM
LordIkol #4
Posted 16 April 2013 - 04:41 AM
Sorry Bit you Know i use them normally.
And Even on The Road i normally use my Pad.
i will edit in 30 mins.

And for The Sleep over os.clock you are right. My mind was still at my own project. Where i need to interact with The screen while counting down.

i should Sleep more :)/>
daveibo1 #5
Posted 16 April 2013 - 05:14 AM
Okay cool, so inder to print this on the monitor it would look something like this

local mon = peripheral.warp ("back")
local count = 45
while true do
  print('Next train arrives in '..count..' seconds')
  sleep(1)
  count = count - 1
  if count < 0 then count = 45 end
end 
Goof #6
Posted 16 April 2013 - 06:04 AM
well.. it would be a bit better to clear the screen and set the cursorpos again, so the monitor wouldnt be overkilled by that many pixels….
Try:


local mon = peripheral.wrap("back")
local count = 45

while true do
  mon.clear()
  mon.setCursorPos(1,1)
  mon.write('Next tran arrives in '..count..' seconds')
  count = count - 1
	if count < 0 then count = 45 end
end

btw, you wrapped it wrong:

(local mon = peripheral.warp ("back"))
should be
(local mon = peripheral.wrap("back"))

:P/>

I hope i could help!
daveibo1 #7
Posted 16 April 2013 - 06:39 AM
ok
well.. it would be a bit better to clear the screen and set the cursorpos again, so the monitor wouldnt be overkilled by that many pixels….
Try:


local mon = peripheral.wrap("back")
local count = 45

while true do
  mon.clear()
  mon.setCursorPos(1,1)
  mon.write('Next tran arrives in '..count..' seconds')
  count = count - 1
	if count < 0 then count = 45 end
end

btw, you wrapped it wrong:

(local mon = peripheral.warp ("back"))
should be
(local mon = peripheral.wrap("back"))

:P/>

I hope i could help!

okay thanks! having issues with line 5 though,
(mon.clear()) 
"too long without yeilding" plus im at a loss when it comes to trying to trigger the countdown with a redstone singal, looked at the wiki for rs.getinput but my coding knowledge is boderline laughable :(/>
remiX #8
Posted 16 April 2013 - 06:48 AM
Add a sleep(1) just before the end of the while true do loop.

It gives this error because the code needs to yield every 10 (?) seconds. This prevents over CPU usage of the server
daveibo1 #9
Posted 16 April 2013 - 07:28 AM
awesome! thanks guys got a stable ticking countdown clock. which is great, but how would i go about coding in the redstone trigger, and then once it reaches zero (after being triggered) it stays there until it receives the rs.getinput that starts the clock ticking again.
daveibo1 #10
Posted 16 April 2013 - 09:25 AM
local mon = peripheral.wrap("back")
local count = 45

if rs.getInput ("back") == true then
  mon.clear()
  mon.setCursorPos(1,1)
  mon.write('Next tran arrives in '..count..' seconds')
  sleep(1)
  count = count - 1
        if count < 0 then count = 45 end
end 

thought this might be a simple fix but alas :/
daveibo1 #11
Posted 16 April 2013 - 09:38 AM
feel free to mock my hap hazard attempts at coding :P/> not having much luck

local mon = peripheral.wrap("bottom")
local count = 45

if rs.getInput ("back") == true then
StopClock(1) end

function StopClock()
-- while true do
	 mon.clear()
	 mon.setCursorPos(1,1)
	 mon.write('Next train available in '..count..' seconds')
	 sleep(1)
	 count = count - 1
	    if count < 0 then count = 45 end
end 
Smiley43210 #12
Posted 16 April 2013 - 11:10 AM
You need to use os.pullEvent()
I just threw this together, dunno if it works.

local mon = peripheral.wrap("back")
local count = 45

function hold()
  sleep(1)
  return
end

function redPulse()
  os.pullEvent("redstone")
  return
end

function count()
  local current = count
  while true do
    mon.clear()
    mon.setCursorPos(1,1)
    mon.write('Next train arrives in '..current..' seconds')
    current = current - 1
    if current < 0 then
      mon.clear()
      mon.setCursorPos(1,1)
      mon.write('Next train is arriving...')
    end
    local e = parallel.waitForAny(hold, redPulse)
    if e == 2 then
      break
    end
  end
end

while true do
  count()
end
daveibo1 #13
Posted 16 April 2013 - 11:28 AM
I added a couple of lines and got a very crude working setup

local mon = peripheral.wrap("back")
local count = 45

input = rs.getInput ("front")

while true do
	 os.pullEvent("redstone")
	 mon.clear()
	 mon.setCursorPos(1,1)
	 mon.setTextScale(1.5)
	 mon.write("Next departure")
	 mon.write(" ")
	 mon.write(''..count..'s')
	 sleep(1)
	 count = count - 1
	    if count < 0 then count = 45 end
end

i have to use a timer to activate the os.pull line of code set to .2seconds to make the countdown timer seem likes its working in seconds. not ideal but it works, kinda, thanks for the response smiley gonna test it out now, cheers buddy
daveibo1 #14
Posted 16 April 2013 - 11:55 AM
You need to use os.pullEvent()
I just threw this together, dunno if it works.

local mon = peripheral.wrap("back")
local count = 45

function hold()
  sleep(1)
  return
end

function redPulse()
  os.pullEvent("redstone")
  return
end

function count()
  local current = count
  while true do
	mon.clear()
	mon.setCursorPos(1,1)
	mon.write('Next train arrives in '..current..' seconds')
	current = current - 1
	if current < 0 then
	  mon.clear()
	  mon.setCursorPos(1,1)
	  mon.write('Next train is arriving...')
	end
	local e = parallel.waitForAny(hold, redPulse)
	if e == 2 then
	  break
	end
  end
end

while true do
  count()
end

i pastebined the code into my mc comp and on line 19 there was an error. concatenate string error. i didnt even know what concatenate means! (thank you google define) that being said, i failed to decipher the error. i think im pretty happy with my crude set up tbh though. very intriguged to see how your coding works though smiley.

thanks
Smiley43210 #15
Posted 16 April 2013 - 02:57 PM
The way I coded it, the timer will restart whenever a redstone pulse is received. That way, if for some reason, the mine craft gets there BEFORE 45 seconds are up, it would just restart the count instead of getting stuck at 0 and waiting for the next one. I'll look at the error; I think it's because I used single quotes instead of double quotes.