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

simple program help

Started by HugoCoin, 14 July 2014 - 03:35 PM
HugoCoin #1
Posted 14 July 2014 - 05:35 PM
I am new to computercraft and i searched for a long time but i couldn't find out how to make a program that checks for 2 signals (left and right) and then puts out from the back, repeats. i play in a modpack with no color cables. could someone explain how to do that?
i also want to make a system where turtles check for blocks above them and if its gone they send a signal to another turtle which then puts out redstone. can someone help me?
hilburn #2
Posted 15 July 2014 - 12:48 AM
Is there any particular reason why you want another computer in the middle to send the signal back? I mean.. a piece of redstone can send a "high" signal around a corner.

However if it has to be a computer, try something like this:


while true do
	os.pullEvent("redstone")
	if rs.getInput("left") or rs.getInput("right") then
		rs.setOutput("back",true)
	end
	--wasnt sure if you wanted it to pulse high or just go high while one of the inputs was high, so if you want a pulse, uncomment the next couple of lines
	--sleep(0.5) change this to change the pulse length
	--rs.setOutput("back",false)
end

However I really do highly recommend using just basic redstone for something like this
Edited on 14 July 2014 - 10:49 PM
KingofGamesYami #3
Posted 15 July 2014 - 02:46 AM
For double signals:

while true do --#infinite loop
  os.pullEvent( "redstone" )  --#wait for redstone change
  if rs.getInput( "left" ) and rs.getInput( "right" ) then  --#check the inputs
    rs.setOutput( "back", true ) --#toggle redstone
    sleep( 0.5 )
    rs.setOutput( "back", false )
  end
end
For turtle checking:

rednet.open( "left" ) --#assuming modem is on the left
while true do --#infinate loop
  if not turtle.detectUp() then --#checking for *not* block
    rednet.broadcast( "rs", "rs" ) --#send message
  else
    sleep( 1 ) --#sleep to avoid error too long without yielding.
  end
end
--and the receiving...
rednet.open( "left" ) --#assuming modem is on the left of course
while true do
  rednet.receive( "rs" ) --#wait for message
  rs.setOutput( "back", true ) --#toggle redstone
  sleep( 0.5 )
  rs.setOutput( "back", false )
end
Don't hesitate to ask any further questions.
HugoCoin #4
Posted 15 July 2014 - 09:42 AM
-snip-

i want to make it so if a block gets broken (explosion) a couple of doors close, thats why.
and there is too much redstone to use more then a couple of 1 blocks there, thats why i want to use turtles/computers.
and is there a way to copy the codes easyly? i know pastebin but i dont know how to use it like this.

-snip-

how can you make it so that it repeats? i would like it to check every 2 seconds for 2 signals and then put out one from the back (until 1 or 2 signals turn off. i tried adding a repeat to it but it needs a until. can you add a print that counts up too? that would be so i know it works.
thank you fore the codes so far ;)/>

-snip-

btw, i want the sleep on 2 seconds becaus of the lag it creates otherwise
Edited on 15 July 2014 - 07:46 AM
hilburn #5
Posted 15 July 2014 - 10:05 AM
Both my and KingofGamesYami's code will repeat forever, that is what the

while true do
   ...
end
is for, it loops for as long as true is true

We also both used

os.pullEvent("redstone")
which is a little more advanced than just a sleep loop, basically it "sleeps" the turtle until the redstone inputs change, then it checks whether the redstone inputs are the ones we care about, then either does something about it, or sleeps again. Just trust me when I say this is better for lag than sleep(2).


--#i=1 --uncomment for your debug output
while true do  --#loop forever
		os.pullEvent("redstone") --#waits for the redstone to change
		if rs.getInput("left") and rs.getInput("right") then --#if both inputs are high
				rs.setOutput("back",true) --#output high at the back
		else --#otherwise
				rs.setOutput("back",false) --#output low
		end
		--#print(i)
		--#i=i+1
end

You can uncomment the debug lines, but remember it will only actually loop through this if the redstone signals change, so maybe use a lever or a button to test it (you will get 2 loops per on-off as the event triggers on high and on low)

As for getting it into your turtle via pastebin - copy the code onto it and make a paste, you will get a heinous code looking something like "QJju77jw" - copy that
Open up your turtle and type "pastebin get <heinous code> startup" - this will copy it into the startup program which will mean the programs will run automatically if the computers restart (chunks become unloaded, server resets/crashes etc)

If you are playing single player or are a server admin it's a bit easier, go into <your Minecraft folder>\saves\<whichever save this is stored in>\computer\<computer id>\ and then save it there. Again I would recommend saving it as startup (no extension)

Also, fair enough with the explosions, normally I would suggest a Project Red AND gate or similar, but turtles are explosion proof so it does create extra robustness
HugoCoin #6
Posted 15 July 2014 - 12:03 PM
thanks, the first code works :D/> but the sending computer on the second one has an error, i called the program wireles1 the error: wireles1:3: attempt to index ? (a nil value)
does someone know what the error means?
hilburn #7
Posted 15 July 2014 - 01:59 PM
If you could post a screenshot of the exact setup and the code on the second turtle (assuming it's on one of the "checking" turtles) I'd be happy to have a go at debugging it
HugoCoin #8
Posted 15 July 2014 - 02:16 PM
this are the 3 pictures i could add.
the receiving comp looks like its working
Edited on 11 November 2014 - 03:34 PM
hilburn #9
Posted 15 July 2014 - 02:24 PM
Ah, that would be because Computers cannot do block detects, only Turtles can do that
HugoCoin #10
Posted 15 July 2014 - 02:36 PM
ohhhh, so i need to repleace the first comp with a turtle? a specific kind?

but the wireles sensor turtle has problems with this code
Edited on 15 July 2014 - 12:42 PM
hilburn #11
Posted 15 July 2014 - 02:50 PM
A wireless turtle would be able to do this, but you'll need to change the first line to rednet.open("right") as that's the side the wireless modem is on
HugoCoin #12
Posted 15 July 2014 - 03:32 PM
yay ;)/> it works.
can you help me out with one more thing?
i want to add a monitor to the program that checks for 2 signals, but the monitor is a couple blocks away, how can i do that? (i modified the code so it prints nothing or 'door open' and then after 5 sec clears the message
hilburn #13
Posted 15 July 2014 - 03:58 PM
You can attach a Wired Modem to both the computer and the monitor and connect them with a wired modem.

You then right click the modem attached to the monitor to activate it and you will get something like "Peripheral monitor_0 connected"

Into your code at the top you add in

monitor=peripheral.wrap("monitor_0") --#change this if it is a different name when you activate the modem
monitor.setTextScale(2) --# looks good on a monitor that is 2 wide, scale it back if you have something smaller
--if it's an advanced monitor you can change the background and text colours but you should look that up in the wiki

where you want to print Door Open you should put

monitor.setCursorPosition(1,2) --# change this so it looks central and nice
monitor.write("Door Open")

where you want to clear it use

monitor.clear()
HugoCoin #14
Posted 15 July 2014 - 04:28 PM
how can you make the text go away after 5 secons but let the prorgam still be checking for redstone?
i am using sleep but then it stops everything
Edited on 15 July 2014 - 02:31 PM
hilburn #15
Posted 15 July 2014 - 04:43 PM
Argh, forgot about that, bit hard to explain, so I did a rewrite of my original code to incorporate it


monitor=peripheral.wrap("monitor_0")
monitor.setTextScale(2)
while true do
	local event = os.pullEvent()
	if event == "redstone" then
		if rs.getInput("left") and rs.getInput("right") then --#if both inputs are high
            rs.setOutput("back",true) --#output high at the back
			monitor.setCursorPos(1,2)
			monitor.write("Door Open")
			os.startTimer(5)
		else --#otherwise
			rs.setOutput("back",false) --#output low
			monitor.clear() --#clears it if the the inputs go low again
		end
	elseif event=="timer" then
		monitor.clear() --#clears it after 5 seconds
	end
end

This will set the monitor to display Door Open when both signals go high
It will be cleared after 5 seconds or if both signals are no longer high, and you can just comment out those lines to change it if you don't want them in effect

The reason this works is that in addition to the "redstone" event we were using before, we are now listening for a "timer" event as well, which we set up to occur 5 seconds after the Door Open message appears. It's a little bit more complicated than the previous code as we can't filter for 2 different events (at least not simply)
Edited on 15 July 2014 - 02:43 PM
KingofGamesYami #16
Posted 15 July 2014 - 04:48 PM
That's getting a bit difficult, you may want to look at the parallel api.


local function pullRedstone()
 while true do --#infinite loop
  writing = false
  os.pullEvent( "redstone" )  --#wait for redstone change
  if rs.getInput( "left" ) and rs.getInput( "right" ) then  --#check the inputs
    os.queueEvent( "write" ) --#create an event
    rs.setOutput( "back", true ) --#toggle redstone
    sleep( 0.5 )
    rs.setOutput( "back", false )
  end
 end
end

local mon = peripheral.wrap( "monitor_0" ) --#as said before, change this accordingly
mon.setTextScale( 2 ) --#can be anything between 0.5 and 5

local function writeMon()
  while true do
    os.pullEvent( "write" ) --#pull our custom event
    mon.write( "stuff" )
    sleep( 5 )
    mon.clear()
  end
end

parallel.waitForAll( pullRedstone, writeMon )

Ninja'd by hildburn, but I have a different way of doing it.
hilburn #17
Posted 15 July 2014 - 04:58 PM
That's neat, I haven't done much parallel work in lua but I have a couple of ideas I haven't got around to doing yet where it might be very handy
HugoCoin #18
Posted 15 July 2014 - 05:49 PM
as i read it now these 2 do things exactly the same, right?
but king's code is made in 2 parts using the enter, am i right?
which one should i use?

and, how do you guys make these? out of experience and then test them?
just wondering cause to me this is very complicated
Edited on 15 July 2014 - 03:50 PM
KingofGamesYami #19
Posted 15 July 2014 - 06:05 PM
as i read it now these 2 do things exactly the same, right?
but king's code is made in 2 parts using the enter, am i right?
which one should i use?

and, how do you guys make these? out of experience and then test them?
They do more or less the same thing, not exactly the same.
In my version, I create two functions, one of which "calls" the other by sending a custom event, through the parallel api. It's a little hard to explain how this works without going into coroutines which I probably shouldn't have mentioned anyway. The program that sent the event runs in the time the other is sleeping for 5 seconds, satisfying the requirements you wanted.

In his version, he makes use of a timer event which will be fired 5 seconds after it is called, creating a similar thing but without parallel/coroutines/event creation. His version is probably more efficient, whereas mine may be more precise. I can't say for certain though.


How do I make these? Depends on what program you're talking about. This one I didn't even test, and didn't look at the CC wiki either. Longer/more complex programs I'll double check stuff on the wiki, and then post. If it's a really complicated and I haven't wrote anything similar before, I'll test it in an emulator ( gravlann.github.io ).
Edited on 15 July 2014 - 04:11 PM
hilburn #20
Posted 15 July 2014 - 06:14 PM
They don't do things exactly the same, but as far as the input and output is concerned, yes they do

Neither should induce any lag or have any issues so really which you use is up to your personal preference, result of a coin flip, eenie meenie miney moe, or however else you want to do it.

I can't speak for anyone else, but I've been coding for about 15 years now, although really only as a hobby and my LUA experience is lacking. With practice I've got better at breaking a problem down into sub-problems to the point where the computer can handle them. The next step is to look at and learn the APIs as this tells you what the computer can actually do. These vary between languages, for example I do a lot of stuff in MATLAB and if I wanted to add 1 to every item in an array in that it is very simple: Array+1, in LUA I would have to loop through every item in the array and add 1 to it individually, it's just a different way of getting the same result based on the way the language is set up. However the most important things are your control structures, your while and for loops and if conditionals, you get the hang of those and coding is your bitch (am I allowed to say bitch? whoops I did it again)

As for the code I wrote for you, It's pretty simple, a while true to loop forever, a wait for event, a conditional based on the type of event and then do stuff in different branches of the conditional

I'll test it in an emulator ( gravlann.github.io ).

Holy Ballsack of Hades, how did I not know about this?
HugoCoin #21
Posted 15 July 2014 - 06:17 PM
whats the difference?
and does it matter for what i am making?
the words that are green in te code, the explaining. does that need to be removed?
Edited on 15 July 2014 - 04:19 PM
KingofGamesYami #22
Posted 15 July 2014 - 06:22 PM
whats the difference?
and does it matter for what i am making?

The main difference is mine uses the parallel api. There is virtually no difference for what you are making, but mine is much, much longer if you include the amount of code in the parallel api… which you should not look at until you think you are a master of everything else and have read the coroutine tutorial.
hilburn #23
Posted 15 July 2014 - 06:26 PM
whats the difference?
and does it matter for what i am making?
the words that are green in te code, the explaining. does that need to be removed?

Yami answered the first two well, and as for the 3rd, no, anything that follows "–" will be ignored when you run the program
HugoCoin #24
Posted 16 July 2014 - 11:12 AM
thanks, that was what i needed.
but one more question, how do you enter on a monitor?
i have the door open and cloned directly behind each other, and sometimes the text is in the middle, sometimes completely in the left and sometimes half of the screen.
hilburn #25
Posted 16 July 2014 - 11:20 AM

monitor.clear() --#clears the monitor, do this between changing the text
monitor.setPos(x,y) --#positions the cursor, do this before writing new text (1,1) is top left corner, (1,2) is beginning of second line etc
monitor.write(text) --#write stuff
Edited on 16 July 2014 - 09:21 AM
HugoCoin #26
Posted 16 July 2014 - 12:28 PM
thank you guys :)/>
do i need to close it now?
Edited on 16 July 2014 - 10:29 AM
flaghacker #27
Posted 16 July 2014 - 12:47 PM
You can't close a topic, only a moderator can do that. To ask a moderator to close a topic, report the thread. But don't do that, topics aren't closed when the question is answered, because you or someone else might have further questions or someone might have a better answer. Topics are only closed when someone answers on a old and dead topic, that's called a "necro".
HugoCoin #28
Posted 16 July 2014 - 01:07 PM
okey
HugoCoin #29
Posted 08 January 2015 - 09:06 PM
so, i just wanted to try something.
and i wrote this to see if i could do that. And i failed :(/>
it's supposed to check for rs left, turn on a light on the top, just for checking if it works, and then write test test on a monitor.
There are no errors, but it just does nothing.
http://pastebin.com/dtB39WD8
Edited on 08 January 2015 - 08:07 PM
Lyqyd #30
Posted 08 January 2015 - 09:12 PM
Lua is case-sensitive. The event name is "redstone", not "Redstone", and the term call is setCursorPos.
HugoCoin #31
Posted 13 January 2015 - 05:01 PM
Thank you.
I managed to make something, but i cant solve this again.
the problem now is that i want the error and the "file too big" on the screen at the same time.(error first and then file too big joining it). it now deletes the error while it writes the file too big.
also i tried to make a flashing dot if there is no redstone singnal, or if it is active. (started up with redstone)
but that doesn't do anything.
http://pastebin.com/dGHsfqEX

sorry for my english if it is bad
Edited on 13 January 2015 - 04:03 PM
Bomb Bloke #32
Posted 13 January 2015 - 11:20 PM
redstone.getInput() only pays attention to the first parameter you pass to it - it returns true if that side has a redstone signal, or false if it does not. redstone.getInput("back",true) acts exactly the same as rs.getInput("back", false), and exactly the same as rs.getInput("back").

Changing the text scale on a monitor changes all text that was already on that monitor too. The only way to have multiple lines displayed with different scales at the same time is to use more than one monitor.

Your dot doesn't blink because after you clear it off the screen, you don't draw it again until another redstone event is pulled.

You could shrink your script down a fair bit if you made a function that let you condense your monitor-writing operations. A basic re-write might look like this:

Spoiler
local mon = peripheral.wrap("left")

local function monWrite(text, x, y, colour)
	if x then mon.setCursorPos(x,y) end  -- If this function was passed a cursor position, set it.
	if colour then mon.setTextColour(colour) end  -- If this function was passed a colour, set it.
	mon.write(text)
end

while true do
	mon.setTextScale(1)
	mon.clear()
	
	-- Wait for redstone to turn on, while blinking the dot:
	repeat
		monWrite(".",1,1)
		sleep(0.5)
		monWrite(" ",1,1)
		sleep(0.5)
	until rs.getInput("back")
	
	-- Now that redstone is on, do this stuff:
	monWrite("Starting up...",1,1,colours.white)
	sleep(2)
	monWrite("loading system",1,2)
	sleep(2)
	monWrite("loading programs",1,3)
	sleep(2)
	monWrite("loading your picture",1,4)
	sleep(2)
	mon.clear()
	mon.setTextScale(3)
	monWrite("ERROR",3,1,colours.red)
	sleep(1)
	mon.setTextScale(2)
	monWrite("FILE TOO BIG",2,4,colours.white)
	
	-- Wait for redstone to turn off again, while just yielding:
	while rs.getInput("back") do os.pullEvent("redstone") end
end
Edited on 13 January 2015 - 10:44 PM
HugoCoin #33
Posted 15 January 2015 - 07:06 PM
what does the "local" do?
KingofGamesYami #34
Posted 15 January 2015 - 07:24 PM
local simply defines a variable as, well, local. Rather than being global.

local variables are accessed faster than global variables, and cannot be changed by other scripts. Global variables are slower and can be changed by other scripts.


--#good practice
local var = read()
--#bad practice
var = read()
Bomb Bloke #35
Posted 15 January 2015 - 11:06 PM
See here for more details.