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

RC detector rails and computers

Started by jkwok678, 25 October 2016 - 08:21 AM
jkwok678 #1
Posted 25 October 2016 - 10:21 AM
Does anyone know how to code detector rails and see which direction a train is coming from?
Also would I need APIs?
Lupus590 #2
Posted 25 October 2016 - 03:16 PM
a pair of detector rails, with some gap between them, both have a separate redstone connection to the computer. Which redstone signal activates first tells you the direction the train is coming from.
jkwok678 #3
Posted 25 October 2016 - 06:26 PM
How would I code it? I'm trying to get the computer to wait for an input.
I tried this, but I can't get it to work. I think it's a logic error, also I can't seem to be able to output redstone signals to front and back.
The end goal is to connect it to make automatic signals

while true do
local right= rs.getInput("right")
local left= rs.getInput("left")
if right == "true" then
   print(something)
if left == "true" then
   print(something)
end
end
Edited on 25 October 2016 - 04:57 PM
KingofGamesYami #4
Posted 25 October 2016 - 06:58 PM
You don't have compare boolean values (true/false) at all to use them in an if statement (and you certainly shouldn't compare them to strings). Your code might look something like this:


while true do
  local right = rs.getInput( 'right' )
  local left = rs.getInput( "left" )
  if right then
     print( "There is a signal from the right" )
  end
  if left then
     print( "There is a signal from the left" )
  end
end
jkwok678 #5
Posted 25 October 2016 - 08:34 PM
So would it continually check for redstone signals? If not how would I make it so that it will?

I would like to connect the computers to railcraft signals, so how could I use another computer further on, to receive data from here. For example my train passes point A and the signal there goes red, then it passes point B and that turns red, and at the same time the signal at A is switched back to green, I know I can probably do this with on/off states of redstone, but how can i pass data around, do I need modems?
Edited on 25 October 2016 - 08:19 PM
Larry84 #6
Posted 25 October 2016 - 09:42 PM
If you want to pass data between computers, you do need modems, either wired or wireless.
jkwok678 #7
Posted 25 October 2016 - 11:00 PM
So would I need to use the modem API? How would I receive the data from the receiving computer and use that piece of data? how could I use this with RC signals?

If you want to pass data between computers, you do need modems, either wired or wireless.
KingofGamesYami #8
Posted 26 October 2016 - 12:45 AM
You would use the rednet API - specifically rednet.open, rednet.send and rednet.receive. I think send and receive are clear enough; open just tells the API which side the modem is attached.

I'm not sure what 'RC' signals are, I don't think they exist in computercraft. Were you perhaps asking about rednet or redstone?

So would it continually check for redstone signals? If not how would I make it so that it will?

It will, because it has an infinite loop. However, you should add

os.pullEvent("redstone")
Before the last 'end'. This way, it will only check the state of the redstone when it changes. It will also allow other computers in the world to function.
jkwok678 #9
Posted 27 October 2016 - 12:56 AM
So now that I have this, it's not fool proof, because a mine cart can run over both detectors and both outputs will happen, so how could I make sure only the first red stone signal from the detector is used. Also lets say I have another setup later on the mine cart line, with the two computers getting info with red net. How could I send a signal from the second detector back to the first to start that program again
Edited on 26 October 2016 - 10:58 PM
Lupus590 #10
Posted 27 October 2016 - 06:43 PM
how are your rails set up? if it's a single line then two trains would mean a crash (if it doesn't then reconfigure your track)

I would have the computer listening for a pair of signals to work out the direction of the train.
Edited on 27 October 2016 - 04:43 PM
jkwok678 #11
Posted 27 October 2016 - 09:03 PM
At the moment there are 4 detectors between detector 2 and 3 is a block, so a space for one train, so they won't crash into each other. What I want is for when the train passes the first detector the computer will notice the redstone current and will will switch on the redstone for front side and turn the signal to red. Then once it passes the 3rd detector, it will send a signal to the first computer telling it to turn the redstone at the front off. Does the code look OK?

So this is the code for the computer the first set of detectors

--this computerID is 202
rednet.open("back")
while true do
  local right = rs.getInput("right") -- detector 2
  local left = rs.getInput("left") -- detector 1
  local next_comp = rednet.receive(1)
  print(next_comp)
  if right then
	print("Train coming from right")

  elseif left then
	print("Train coming from left")
	rs.setOutput("front",true) --set signal to red  

elseif next_comp=="clear" then
	rs.setOutput("front",false)-- set signal to green
  end
os.pullEvent("redstone")
end

For computer at second set of detectors

--this computer ID is 183
rednet.open("back")
while true do
  local right = rs.getInput("right") -- detector 4
  local left = rs.getInput("left") -- detector 3
  if right then
	print("Train coming from right")

  elseif left then
	print("Train coming from left")
	rednet.send(202,"clear")
  end
end
os.pullEvent("redstone")
So at the moment there are 4 detectors between detector 2 and 3 is a block, so a space for one train, so they won't crash into each other. What I want is for when the train passes the first detector the computer will notice the redstone current and will will switch on the redstone for front side and turn the signal to red. Then once it passes the 3rd detector, it will send a signal to the first computer telling it to turn the redstone at the front off. I don't know why it doesn't work right now
Edited on 28 October 2016 - 09:11 AM
Larry84 #12
Posted 28 October 2016 - 05:42 PM
Because of the os.pullEvent("redstone"). It simply stops the code until redstone changes - but you want to do something also when a rednet message is recieved.
You can simply delete the parameter - it will run the code for every event it listens, but it should work fine.
Also, in the second code, that pullEvent should be before the last end, it won't work otherwise. Now, after that the while loop terminated, the computer will wait for a redstone event - you wanted instead to wait for a redstone event for restarting the while loop.
jkwok678 #13
Posted 29 October 2016 - 10:20 PM
For some reason this computer with the first code still doesn't switch the signal at the front of the computer.

This is the code for the first computer. I think it's the first computer not receiving the signal because the front redstone of the second computer lights up but the both computers are wired by a modem on the back

--ComputerID is 202
rednet.open("back")
while true do
  local right =rs.getInput("right")
  local left = rs.getInput("left")
  local next = rednet.receive()
  if left then
	rs.setOutput("front",true)
  elseif right then
	print("right")
  end  
  if next=="clear" then
	rs.setOutput("front",false)
  end
end
This is the code for the second computer

--ComputerID is 183
rednet.open("back")
while true do
  local right =rs.getInput("right")
  local left =rs.getInput("left")
  if left then
	rs.setOutput("front",true)
	rednet.send(202,"clear")
  elseif right then
	print("right")
  end
  os.pullEvent("redstone")
end
Edited on 29 October 2016 - 08:41 PM
Bomb Bloke #14
Posted 30 October 2016 - 12:29 AM
Remember that rednet.receive() returns multiple values - first the sender ID, then the message.

local sender, next = rednet.receive()
jkwok678 #15
Posted 01 November 2016 - 06:57 PM
Is there a way for example to make the if statements choose the path based on the direction of travel for example if left detector is activated and then right detector is activated it will do something?
Lupus590 #16
Posted 01 November 2016 - 10:05 PM
Is there a way for example to make the if statements choose the path based on the direction of travel for example if left detector is activated and then right detector is activated it will do something?


if left restone then
  start a timer
  exit = false
  while not exit do
	event = os.pullEvent()
	if event is timer then
	  print("one signal")
	  exit = true
	elseif event is redstone
	  if right redstone then
		print("signal pair")
		exit = true
	  end
	end
   end
end
Edited on 01 November 2016 - 09:07 PM
jkwok678 #17
Posted 02 November 2016 - 04:40 PM
I was thinking of more like this
This is kinda pseudo code

if "left detector activates and then right detector activates"
   print "cart is from left"
if "right detector activates and then left detector activates"
   print "cart is from right"
Lupus590 #18
Posted 02 November 2016 - 06:13 PM
my code does that but only for one side, you can copy-paste and edit to do right to left
jkwok678 #19
Posted 05 November 2016 - 12:19 PM
I have no idea how to incorporate the earlier code into this one of sending red stone signals forward and backwards with the new conditions.

--ComputerId is 202
rednet.open("back")
while true do
  local right =rs.getInput("right")
  local left = rs.getInput("left")
  local next = rednet.receive()
if left then
    os.startTimer(3)
    exit = false
    while not exit do
        event = os.pullEvent()
        if event == "timer" then
            exit = true
            elseif event=="redstone" then
                print("signal pair")
                rs.setOutput("front",true)
                rs.setOutput("back",true)
                rednet.send(183,"clear")
os.sleep(10)
     rs.setOutput("back",false)
rs.setOutput("front",false)
                exit = true
            end
        end
   end
if right then
  os.startTimer(3)
  exit = false
  while not exit do
        event = os.pullEvent()
        if event == "timer" then
          exit = true
        elseif event =="redstone" then
                print("signal pair")
                rs.setOutput("front",true)
                rs.setOutput("back",true)
                rednet.send(183,"blocked")
                exit = true
            end
        end
   end
end
if message=="clear" and SenderID ==183then
    rs.setOutput("front",false)
rs.setOutput("back",false)
end

Currently neither of them work properly

--ComputerId is 183
rednet.open("back")
while true do
  local right =rs.getInput("right")
  local left = rs.getInput("left")
  local next = rednet.receive()
if left restone then

    os.startTimer(3)
    exit = false
    while not exit do
	    event = os.pullEvent()
	    if event=="timer" then
		 exit = true
		 elseif event=="redstone" then
			 print("signal pair")
    rs.setOutput("front",true)
    rs.setOutput("back",true)
    rednet.send(202,"blocked")
			    exit = true
		    end
	    end
   end
if right redstone then
  os.startTimer(3)
  exit = false
  while not exit do
	    event = os.pullEvent()
	    if event="timer" then
		  exit = true
	    elseif event=="redstone" then
			 print("signal pair")
    rs.setOutput("front",true)
    rs.setOutput("back",true)
    rednet.send(202,"clear")
    os.sleep(10)
	   rs.setOutput("back",false)
    rs.setOutput("front",false)
			    exit = true
		 end
	    end
   end
end
if message=="clear" and SenderID ==202 then
    rs.setOutput("front",false)
end
Lupus590 #20
Posted 05 November 2016 - 12:39 PM
indentation should line up with scope, this makes code more readable

also error codes help


rednet.recive is like a specialized pull event

if left redstone then is not valid lua
Edited on 05 November 2016 - 11:42 AM
jkwok678 #21
Posted 05 November 2016 - 08:13 PM
This is the code fixed up a little, but right now it's a logic error, I'm trying to merge the the redstone opening and closing and the directional detector

--ComputerId is 202
rednet.open("back")
while true do
local right =rs.getInput("right")
    local left = rs.getInput("left")
    local next = rednet.receive()
if left then
	 os.startTimer(3)
	 exit = false
	 while not exit do
		 event = os.pullEvent()
		 if event == "timer" then
			 exit = true
		    elseif event=="redstone" then
			    print("signal pair")
			    rs.setOutput("front",true)
			    rs.setOutput("back",true)
			    rednet.send(183,"clear")
    os.sleep(10)
	    rs.setOutput("back",false)
    rs.setOutput("front",false)
			    exit = true
		    end
  end
    end
if right then
  os.startTimer(3)
	 exit = false
	 while not exit do
		 event = os.pullEvent()
		 if event == "timer" then
			 exit = true
		 elseif event =="redstone" then
			    print("signal pair")
			    rs.setOutput("front",true)
			    rs.setOutput("back",true)
			    rednet.send(183,"blocked")
			    exit = true
		    end
	    end
    end
if message=="clear" and SenderID ==183 then
	 rs.setOutput("front",false)
  rs.setOutput("back",false)
end
end
The code for the other computer

--ComputerId is 183
rednet.open("back")
while true do
local right =rs.getInput("right")
local left = rs.getInput("left")
local next = rednet.receive()
if left then
  os.startTimer(3)
	 exit = false
	 while not exit do
		 event = os.pullEvent()
		    if event=="timer" then
			 exit = true
   elseif event=="redstone" then   
	   rs.setOutput("front",true)
    rs.setOutput("back",true)
	   rednet.send(202,"blocked")
			    exit = true
		    end
	    end
end
if right then
    os.startTimer(3)
    exit = false
    while not exit do
   event = os.pullEvent()
		    if event="timer" then
			 exit = true
		    elseif event=="redstone" then
			 print("signal pair")
	   rs.setOutput("front",true)
	   rs.setOutput("back",true)
	   rednet.send(202,"clear")
	   os.sleep(10)
			 rs.setOutput("back",false)
	   rs.setOutput("front",false)
			    exit = true
		    end
	    end
end
if message=="clear" and SenderID ==202 then
	 rs.setOutput("front",false)
end
end
Bomb Bloke #22
Posted 05 November 2016 - 11:45 PM
What does the code currently do, and how does this actually differ from what you want it to do?
jkwok678 #23
Posted 07 November 2016 - 06:10 PM
At the moment, in the second code it first checks for an redstone input on the right and left, if it's from the left it will start a timer, if within that timer, there is another redstone input from the right then it means that the train is coming from the left, next the computer will output two redstone signal (front and back) that will turn the signals going forward and backwards to red at this point. It will also send the next computer in line blocked so that, that computer will switch the backwards signal to red, then when the train passes the second signal in front, the computer will send a signal back to the first telling it to turn off the redstone at front and back to reset signals to green.
That is basically what I want to do but it doesn't seem to work, probably a logic error and it could be the conditions for finding out the direction of the train
Edited on 07 November 2016 - 05:12 PM
Lupus590 #24
Posted 07 November 2016 - 07:40 PM
At the moment, in the second code it first checks for an redstone input on the right and left, if it's from the left it will start a timer, if within that timer, there is another redstone input from the right then it means that the train is coming from the left, next the computer will output two redstone signal (front and back) that will turn the signals going forward and backwards to red at this point. It will also send the next computer in line blocked so that, that computer will switch the backwards signal to red, then when the train passes the second signal in front, the computer will send a signal back to the first telling it to turn off the redstone at front and back to reset signals to green.
That is basically what I want to do but it doesn't seem to work, probably a logic error and it could be the conditions for finding out the direction of the train

This is really unclear, where are you saying what it currently does and where are you saying what you want it to do?

Repeating the questions separately:
  1. What does the code currently do? I.E. when it is running in game what happens?
  2. What are you wanting it to be doing? Focus on the things that it's not doing currently.
jkwok678 #25
Posted 08 November 2016 - 11:28 PM
Ok I'm getting confused as well, so I'm going to start again.
Does this code look right for just detecting the train coming from the left then Outputing redstone signals front and back if it is?


--First computer on the line ID 183
while true do
   local left=rs.getInput("left")
   local right=rs.getInput("right")
   local senderID,message,protocol=rednet.receive(1)
   if left  then
	  os.startTimer(3)
	  exit = false
	  while not exit do
		 event = os.pullEvent()
		 if event =="timer" then
			exit = true
		 elseif event is redstone
			if right redstone then
			   rs.setOutput("front",true)
			   rs.setOutput("back",true)
			   rednet.send(202,"blocked")
			   exit = true
		  end
		end
   end
end
Formatting is really annoying as CC uses 3 spaces for indentation and normal is 4, and the indentation looks a little weird on here as well
Edited on 08 November 2016 - 10:30 PM
Lupus590 #26
Posted 09 November 2016 - 09:33 AM
you need to call redstone.getInput("right")after the redstone event.

also, if right redstone then will error as it's not valid lua
jkwok678 #27
Posted 09 November 2016 - 08:29 PM
Does it look alright? The logic is that, if a train comes from either left or right redstone outputs at front and back. Then if the train is coming from left send a message to the next computer to tell it that the line is "blocked". The other will tell that same signal that the line is "clear"
The code is there because formatting is really hard on here
http://pastebin.com/QGghZWQY
Lupus590 #28
Posted 09 November 2016 - 09:12 PM
the pastebin one looks fine, not the most efficient but I think it should work.

Have you tested it and does it do what you want it to do?
jkwok678 #29
Posted 12 November 2016 - 12:17 AM
No, I haven't tested it yet but I will do soon because for it to be complete, I would need the second computer program code.on.

How could I make this more efficient? I know that the code is very long right now

By utilising functions?
Lupus590 #30
Posted 12 November 2016 - 12:50 PM
I'd get the whole system working before trying to get it more efficient.
jkwok678 #31
Posted 15 November 2016 - 06:37 PM
The code for the second computer: http://pastebin.com/3WQYSBt6
The code for the first computer: http://pastebin.com/QGghZWQY
There seems to be a logic error but I can't seem to spot it. There is no syntax error though.
Bomb Bloke #32
Posted 15 November 2016 - 09:19 PM
And you expect someone else to spot it, even if you don't explain the behavioural problem it's causing?
jkwok678 #33
Posted 17 November 2016 - 06:47 PM
I think it's the code that decides on the direction of cart because the code before worked and I only just copied the code that worked for turning on and off rs signals. So I think what I need is another way to do it, especially if there are two carts going after each other, in which the code that was shown to me wouldn't work