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

Train Detection System doesnt read

Started by Xixili, 05 February 2014 - 03:21 PM
Xixili #1
Posted 05 February 2014 - 04:21 PM
Hello coders,

Im trying to write an information panel that shows arriving/loading/departing carts.

Somehow it doesnt read the detector rails and I cant find the problem.



The code:
http://pastebin.com/G2UMSQz9

The cart of courser passes the detector rail in less then a second.
But the text needs to be shown untill it passes the next detector rail and so on.

But I cant find the problem.
Edited on 05 February 2014 - 03:35 PM
CometWolf #2
Posted 05 February 2014 - 04:26 PM
There's no loop, so your code will just run once then end. though not wrong function wise, It could be optimized a bit more with the use of events and only one redstone check aswell, and note that any redstone signals occuring during the sleep will be missed.
Edited on 05 February 2014 - 03:26 PM
Xixili #3
Posted 05 February 2014 - 04:29 PM
There's no loop, so your code will just run once then end. though not wrong function wise, It could be optimized a bit more with the use of events and only one redstone check aswell, and note that any redstone signals occuring during the sleep will be missed.
Thank you but now I need to find out how to build in the loop :(/>

http://pastebin.com/G2UMSQz9
Edited on 05 February 2014 - 03:35 PM
Xixili #4
Posted 05 February 2014 - 04:36 PM
I have added the full code
awsmazinggenius #5
Posted 05 February 2014 - 04:38 PM
To make an infinite loop, do this:

while true do
  --# Your code...
end
To quit the "infinite" loop, use the break keyword.

while true do
  --#Your code...
  if it_is_time_to_quit then
	break --#Loop ends here.
  end
end
EDIT: Added a missing code tag and damn ninja :ph34r:/>
Edited on 05 February 2014 - 03:38 PM
CometWolf #6
Posted 05 February 2014 - 04:38 PM
Almost, you just forgot to add in an end to close the loop

while true do
monitor.setTextColor(colors.orange)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 4)
monitor.write("Orange Line:")

if redstone.testBundledInput("bottom", colors.black) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("")

elseif redstone.testBundledInput("bottom", colors.yellow) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train Arriving at station")

elseif redstone.testBundledInput("bottom", colors.orange) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train is now boarding")

elseif redstone.testBundledInput("bottom", colors.blue) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train is now departing")
sleep(8)
end
end -- this one will close the while true do loop
Xixili #7
Posted 05 February 2014 - 04:48 PM
Almost, you just forgot to add in an end to close the loop

while true do
monitor.setTextColor(colors.orange)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 4)
monitor.write("Orange Line:")

if redstone.testBundledInput("bottom", colors.black) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("")

elseif redstone.testBundledInput("bottom", colors.yellow) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train Arriving at station")

elseif redstone.testBundledInput("bottom", colors.orange) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train is now boarding")

elseif redstone.testBundledInput("bottom", colors.blue) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train is now departing")
sleep(8)
end
end -- this one will close the while true do loop

I tried but now I get another error and makes the computer crash:
startup:50: Too long without yielding

and

nil: vm error:
java.lang.ArrayIndexOutOfBoundsException
Edited on 05 February 2014 - 03:49 PM
CometWolf #8
Posted 05 February 2014 - 04:59 PM
Yeah, it's cause there's no sleep in your loop, so it never yields.
A quick and dirty way would be to just throw in sleep(0) in between the 2 ends. It would work, but again this really isn't the way such a program should be done.

Here's a quick example of the way it should be handled.

while true do
  os.pullEvent"redstone" -- this will basically sleep until there is a change in the redstone connected to the computer
  local redInput = rs.getBundledInput"bottom" --gets the bottom redstone input state
  if colors.test(redInput,colors.black) then -- checks the redstone state we got earlier for the color black
	--do stuff
  elseif colors.test(redInput,colors.orange) then
	--do other stuff
  end
end
Edited on 05 February 2014 - 04:00 PM
Xixili #9
Posted 05 February 2014 - 05:15 PM
Yeah, it's cause there's no sleep in your loop, so it never yields.
A quick and dirty way would be to just throw in sleep(0) in between the 2 ends. It would work, but again this really isn't the way such a program should be done.

Here's a quick example of the way it should be handled.

while true do
  os.pullEvent"redstone" -- this will basically sleep until there is a change in the redstone connected to the computer
  local redInput = rs.getBundledInput"bottom" --gets the bottom redstone input state
  if colors.test(redInput,colors.black) then -- checks the redstone state we got earlier for the color black
	--do stuff
  elseif colors.test(redInput,colors.orange) then
	--do other stuff
  end
end


I have the code now like this:


monitor.setTextColor(colors.orange)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 4)
monitor.write("Orange Line:")
while true do
os.pullEvent"redstone"

if colors.test(redInput,colors.black) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("")

elseif colors.test(redInput,colors.yellow) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train Arriving at station")

elseif colors.test(redInput,colors.orange) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train is now boarding")

elseif colors.test(redInput,colors.blue) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train is now departing")
sleep(8)
monitor.setCursorPos(1, 5)
monitor.clearLine()
end
end

But no response at all.
CometWolf #10
Posted 05 February 2014 - 05:31 PM
You forgot this line where it actually checks the redstone input.

  local redInput = rs.getBundledInput"bottom" --gets the bottom redstone input state
Xixili #11
Posted 05 February 2014 - 05:44 PM
You forgot this line where it actually checks the redstone input.

  local redInput = rs.getBundledInput"bottom" --gets the bottom redstone input state
Its written on the 2nd line. (not posted)
Edited on 05 February 2014 - 04:44 PM
CometWolf #12
Posted 06 February 2014 - 12:10 AM
What? It needs to be under the os.pullEvent, within the loop.
Xixili #13
Posted 06 February 2014 - 10:05 AM
What? It needs to be under the os.pullEvent, within the loop.
Ah thats the problem then, I will try later tonight.
Im now at work :(/>
Xixili #14
Posted 07 February 2014 - 06:30 AM
I have 2 lines that needs to be checked maybe a 3th one in the future.
Is it possible that the computer shows the 2 lines on 1 monitor?

I got the code now like this but it seems not working very well.
When a train arrives on the red line and orange line the computer doesnt work how it supposed to do.


-- ==== Orange Line train reading

monitor.setTextColor(colors.orange)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 4)
monitor.write("Orange Line:")
monitor.setTextColor(colors.red)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 6)
monitor.write("Red Line:")

while true do
os.pullEvent"redstone"
local redInput = rs.getBundledInput"bottom"
if colors.test(redInput,colors.black) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("")

elseif colors.test(redInput,colors.yellow) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train Arriving at station")

elseif colors.test(redInput,colors.orange) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train is now boarding")

elseif colors.test(redInput,colors.blue) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("Train is departed")
sleep(7)
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 5)
monitor.clearLine()
monitor.write("No incoming trains")
end

-- ==== Red Line train reading

while true do
os.pullEvent"redstone"
local redInput = rs.getBundledInput"bottom"
if colors.test(redInput,colors.black) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 7)
monitor.clearLine()
monitor.write("")

elseif colors.test(redInput,colors.red) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 7)
monitor.clearLine()
monitor.write("Train Arriving at station")

elseif colors.test(redInput,colors.brown) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 7)
monitor.clearLine()
monitor.write("Train is now boarding")

elseif colors.test(redInput,colors.green) then
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 7)
monitor.clearLine()
monitor.write("Train is departed")
sleep(7)
monitor.setTextColor(colors.white)
monitor.setBackgroundColor(colors.black)
monitor.setCursorPos(1, 7)
monitor.clearLine()
monitor.write("No incoming trains")
end
end
end
Bomb Bloke #15
Posted 07 February 2014 - 08:36 AM
Consider looking into indentation. The main benefit is that it makes it easier to read your code - in this case it'd make it clearer to you why the "end" statements are out of place.

The basic rule is this - whenever you write a line that starts a new code block (starting with words such as "while", "if", "for", "repeat", etc), move all lines underneath a bit to the right until you reach the corresponding "closing" statement (such as "end", "else", "elseif", "until", etc).

For eg:

Spoiler
-- Explain stuff.
local function help()
  local page = 1
  prepareHelp()
  writeHelp(page)

  while true do
    myEvent = {os.pullEvent()}

    if clickedAt(35,10) or pressedKey(keys.h,keys.x,keys.q) then
      return
    elseif myEvent[1] == "monitor_resize" and mon then
      if myEvent[2] == mon.side then
        enforceScreenSize()
        prepareHelp()
        writeHelp(page)
      end
    elseif clickedAt(35,1,4) or pressedKey(keys.w,keys.up) or (myEvent[1] == "mouse_scroll" and myEvent[2] == -1) then
      page = (page==1) and 5 or (page-1)
      writeHelp(page)
    elseif clickedAt(35,16,19) or pressedKey(keys.s,keys.down) or (myEvent[1] == "mouse_scroll" and myEvent[2] == 1) then
      page = (page==5) and 1 or (page+1)
      writeHelp(page)
    elseif myEvent[1] == "terminate" then
      exitGame()
    end    
  end  
end

This makes it very, very easy to see where each block starts and eventually finishes. This may sound like it's a cosmetic thing, but I mention it first because it's important - you'll find coding a lot easier if you use a visual aid like this to keep track of your program flow.

In your case, you've got a "while" loop with an "if" statement and another "while" loop inside it (containing another "if" statement inside the latter). Because both of your "while" loops are rigged to never end, once the one inside the first begins, the first loop will never gets to repeat.

You need two merge the loops, and just have one with all required "if" statements inside it.