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

[LUA] Help with loops

Started by Gibbo3771, 26 March 2013 - 12:20 AM
Gibbo3771 #1
Posted 26 March 2013 - 01:20 AM
Hi,

I am very new to ComputerCraft and have just started using it about 3 days ago, I have watched all of direwolf20's videos over and over and have a decent understanding of it.

So I will describe what I want my code to do,

First I want it to check for a redstone signal, if that redstone signal comes back as true it will display that the quarry is on via the monitor and then actually turn it on.
if it is false, then display on the monitor that it is off and then turn it off.

Ok I surprisingly having that bit working, the main problem with it is that I am using an if statement and as soon as it is done it jumps out of the program, ending it basically. So I know I need a loop.

However if I put a loop in, how would I make it jump in and out of that loop to be constantly checking for changes in the lever? I want the program to do more things(check fuel level, keep an eye out for backlogs etc etc) so want to add more code below, I was thinking a loop within a loop but still, how would I break out of the loop that checks for the power status? I tried a while loop and well, it just didn't recheck anything.



Spoilerfunction startMonitor()
monitor = peripheral.wrap("back")
monitor.clear()
monitor.setCursorPos(5,1)
monitor.write("Quarry Control System")
monitor.setCursorPos(1,3)
monitor.write("Quarry Power : ")


local lever = rs.getInput("left")


startMonitor()

if lever == true then
rs.setBundledOutput("bottom", colors.red)
monitor.setCursorPos(20,3)
monitor.write("On")
elseif lever == false then
rs.setBundledOutput("bottom", 0)
monitor.setCursorPos(20,3)
monitor.write("Off")
end
Gibbo3771 #2
Posted 26 March 2013 - 01:23 AM
Ok sorry to be a pain but just brainstorming a lot and asking a quick question.

It seems it would be a complete waste of time to be constantly checking if it already knows it is on. I do not need the program to do anything UNLESS it is on.

So I think I should perma loop in that part of the code if it is false, if it is true then break from the loop and continue with the rest of the code….I think I just answered my own question…lol
LordIkol #3
Posted 26 March 2013 - 01:32 AM
Hi gibbo,

Just modified your Code a little can not test at the moment but i think it should work :)/>
you can set the sleep in the both inner loops to the amount you want to check for input and output
Greets Loki


function startMonitor()
monitor = peripheral.wrap("back")
monitor.clear()
monitor.setCursorPos(5,1)
monitor.write("Quarry Control System")
monitor.setCursorPos(1,3)
monitor.write("Quarry Power : ")
end


local lever = rs.getInput("left")

startMonitor()

while true do
while lever == true do
rs.setBundledOutput("bottom", colors.red)
monitor.setCursorPos(20,3)
monitor.write("On")
sleep(0.1)
end
while lever == false do
rs.setBundledOutput("bottom", 0)
monitor.setCursorPos(20,3)
monitor.write("Off")
sleep(0.1)
end
sleep(0.5)
end
theoriginalbit #4
Posted 26 March 2013 - 01:40 AM
direwolf20 really isn't the best person to learn from. The best method of learning is with the PIL to learn lua and the computercraft wiki for computercraft related

here is some impoved code. if you have any questions just ask

monitor = peripheral.wrap("back")
term.redirect(monitor)

term.clear()
term.setCursorPos(5,1)
write("Quarry Control System")
term.setCursorPos(1,3)
write("Quarry Power : ")
end

function checkLever()
  active = rs.getInput('left')
  term.setCursorPos(20,3)
  rs.setBundledOutput("bottom", active and colors.red or 0)
  write( active and 'On ' or 'Off')
end

while true do
  os.pullEvent('redstone') -- this will need to be removed later if you are not waiting only for redstone.
  checkLever()
end

term.restore()

EDIT: Damn editor!
Edited on 26 March 2013 - 12:48 AM
Gibbo3771 #5
Posted 26 March 2013 - 01:48 AM
direwolf20 really isn't the best person to learn from. The best method of learning is with the PIL to learn lua and the computercraft wiki for computercraft related

here is some impoved code. if you have any questions just ask

monitor = peripheral.wrap("back")
term.redirect(monitor)

term.clear()
term.setCursorPos(5,1)
write("Quarry Control System")
term.setCursorPos(1,3)
write("Quarry Power : ")
end

startMonitor()

while true do
  os.pullEvent('redstone')
  active = rs.getInput('left')
  term.setCursorPos(20,3)
  rs.setBundledOutput("bottom", active and colors.red or 0)
  write( active and 'On ' or 'Off')
end

EDIT: Damn editor!

Cheers to both of you, I can see this coding is a little bit more advanced than me, I understand it but had zero idea how or if i could do that.

I see you are rediverting term to the monitor, how would I return this back to normal if I wanted to use term later in the code?

Also having a little bit of a brainfu with loops, seriously struggling to get them :P/>

Why does both your codes have "while true do", like…whats true? I don't get this lol.
theoriginalbit #6
Posted 26 March 2013 - 01:49 AM
check my edit. I made a change to the code after reading your OP again.
Gibbo3771 #7
Posted 26 March 2013 - 01:58 AM
check my edit. I made a change to the code after reading your OP again.

OK just one question related to this bit:


rs.setBundledOutput("bottom", active and colors.red or 0)
write( active and 'On ' or 'Off')

So it sets the bottom output to whatever the variable of active is and then turns on the color red or turns all off, how does it know that turn red on when true and then declare 0 when false?

Also write on or off, fair enough but why is that variable in there?

Sorry if these questions are stupid :s
theoriginalbit #8
Posted 26 March 2013 - 02:00 AM
ok so active is the variable that I used to check if the lever is active or not. now this is a boolean. those statements what they do is this
<condition> and <if true> or <if false>

so what it does is return whichever value is required based on if active is true or false.
LordIkol #9
Posted 26 March 2013 - 02:01 AM
Hi Bit,

When i see your codes i always feel like a total Noob :D/>
just for my understanding what you do here

rs.setBundledOutput("bottom", active and colors.red or 0)

from what i see its like: when i have a boolean variable i can use it like

"Booleanvariable" and "do stht when its true" or "do sth when its False"

is this correct? (hope i explained it correct)

@Gibbo:

You can get back to normal by using term.restore() if i remember correctly.
"While true do" starts an infinite Loop we use it cause we want the Programm to execude the code over and over
without this loop your programm would just end after first successful change of State

Greets
Loki

EDIT: Lol i see i was right about the boolean Stuff. But late for posting :)/>
theoriginalbit #10
Posted 26 March 2013 - 02:08 AM
Hi Bit,

When i see your codes i always feel like a total Noob :D/>
Haha. its ok, everyone starts somewhere. :)/> take a look at the code for my latest 2 projects CCPresenter and CCKeyboard :)/>
Gibbo3771 #11
Posted 26 March 2013 - 02:13 AM
Well it works, but I see what you mean that I would need to remove the pull event, since the program gets stuck there until something changes, guess i'll mess about with it a for a bit :D/>
theoriginalbit #12
Posted 26 March 2013 - 02:16 AM
yeh the os.pullEvent('redstone') will wait there for a redstone change… it helps reduce lag as the computer isn't running unnecessarily.
Gibbo3771 #13
Posted 26 March 2013 - 02:20 AM
yeh the os.pullEvent('redstone') will wait there for a redstone change… it helps reduce lag as the computer isn't running unnecessarily.

Yeah took that out and tried an if statement, basically if the lever is false just check again, if it is true then continue on with the rest of the code but damn…..THE LAG…infinite loop ftw lol
theoriginalbit #14
Posted 26 March 2013 - 02:24 AM
Yeah took that out and tried an if statement, basically if the lever is false just check again, if it is true then continue on with the rest of the code but damn…..THE LAG…infinite loop ftw lol
You would probably also find that after ~10 seconds it would error too.

you can make it


local event, param1, param2, param3, param4, param5 = os.pullEvent()
if event == 'redstone' then
  -- do stuff
end
this way is good when you want to look for multiple events like 'redstone' or 'timer' or 'mouse_click'
Gibbo3771 #15
Posted 26 March 2013 - 02:31 AM
hmmm, I didn't quite do something like that, I done this.

Spoilerwhile true do
if lever == false then
checkLever()
sleep(1)
end
end

Then I would put an else statement? and the rest of the code would go in there?

Also how the hell do you get that little green box around your code.
Gibbo3771 #16
Posted 26 March 2013 - 02:33 AM
hmmm, I didn't quite do something like that, I done this.

Spoilerwhile true do
if lever == false then
checkLever()
sleep(1)
end
end

Then I would put an else statement? and the rest of the code would go in there?

Also how the hell do you get that little green box around your code.

EDIT: obviously I made a variable called lever at the top, with the condition being rs.getInput
theoriginalbit #17
Posted 26 March 2013 - 02:35 AM
instead of == false you can use the not keyword.


if not lever then

and yes an else would do

[code][/code]
Gibbo3771 #18
Posted 26 March 2013 - 02:38 AM
instead of == false you can use the not keyword.


if not lever then

and yes an else would do

[code][/code]

ahhhh, nice. Yet my wife said you learn nothing from reading forums :D/>
theoriginalbit #19
Posted 26 March 2013 - 02:40 AM
ahhhh, nice. Yet my wife said you learn nothing from reading forums :D/>
Well you can tell her she was wrong. you can learn a lot from forums :D/>
Sometimes you can learn some really bad habits and bad info and stuff from some people on forums… this forum is no exception…
Gibbo3771 #20
Posted 26 March 2013 - 02:46 AM
ahhhh, nice. Yet my wife said you learn nothing from reading forums :D/>
Well you can tell her she was wrong. you can learn a lot from forums :D/>
Sometimes you can learn some really bad habits and bad info and stuff from some people on forums… this forum is no exception…

Try the eve forums, or even better TheWarZ :P/>

OK, I appreciate everyones help. I am going to try and continue coding the rest of the stuff in.
Gibbo3771 #21
Posted 26 March 2013 - 03:24 AM
Wow I am just not doing good with this at all lol.

So been messing around with trying to implement code after the if statement, however when I implement new code and reboot the machine, the computer is just constantly looping via the checkLever function. It does not continue with the code with a change of state.

Now if I reboot the machine with the state to on, the code will execute. But if I change the state of the redstone signal it does not go back into checking the checkLever function again.

Seems I can't get out of the loop once it has started, adding a break in there just messes with it completely and terminates the program.
theoriginalbit #22
Posted 26 March 2013 - 03:31 AM
seems like you are doing something wrong. post your code.
Gibbo3771 #23
Posted 26 March 2013 - 03:36 AM
seems like you are doing something wrong. post your code.

I think I fixed it…lol. Every…time…I post…

Anyway here is what I got, I haven't moved far :P/> lol



monitor = peripheral.wrap("back")
term.redirect(monitor)

term.clear()
term.setCursorPos(5,1)
write("Quarry Control System")
term.setCursorPos(2,3)
write("Quarry Power : ")
term.setCursorPos(2,4)
write("Fuel Level   : ")

function checkLever()
  lever = rs.getInput('left') --variable  
  term.setCursorPos(20,3)
  rs.setBundledOutput("bottom", lever and colors.red or 0)
  write( lever and 'On ' or 'Off')
end


while true do
  if not lever then
	checkLever()
	sleep(0.5)
  elseif lever == true then
	sleep(1)
	write("test") -- just testing here, I will be putting the rest of the code in here
  end
end

term.restore()

So now when I have it set to off, it just loops the function until it changes to on, then it starts to print test all over the screen. Which is good, then when I hit off, continues to write test, which is bad :P/>. I'll keep messing with it.
Gibbo3771 #24
Posted 26 March 2013 - 03:38 AM
seems like you are doing something wrong. post your code.

I think I fixed it…lol. Every…time…I post…

Anyway here is what I got, I haven't moved far :P/> lol



monitor = peripheral.wrap("back")
term.redirect(monitor)

term.clear()
term.setCursorPos(5,1)
write("Quarry Control System")
term.setCursorPos(2,3)
write("Quarry Power : ")
term.setCursorPos(2,4)
write("Fuel Level   : ")

function checkLever()
  lever = rs.getInput('left') --variable  
  term.setCursorPos(20,3)
  rs.setBundledOutput("bottom", lever and colors.red or 0)
  write( lever and 'On ' or 'Off')
end


while true do
  if not lever then
	checkLever()
	sleep(0.5)
  elseif lever == true then
	sleep(1)
	write("test") -- just testing here, I will be putting the rest of the code in here
  end
end

term.restore()

So now when I have it set to off, it just loops the function until it changes to on, then it starts to print test all over the screen. Which is good, then when I hit off, continues to write test, which is bad :P/>. I'll keep messing with it.

Fixed that, just let it loop back into the function again.
Gibbo3771 #25
Posted 26 March 2013 - 04:18 AM
can't seem to figure out what is up with this part of my code, seems like the rs.getBundledIutput part just isent getting the state.

I am using a wireless redstone thing and constriction pipes on my engines, which send a signal when they are out/low on fuel or something along those lines, atm I am just using a lever to simulate it.

No matter the state, it just says "out" if I write it one way and "OK" if I write it another way.



function checkFuel()
fuel = rs.getBundledInput("bottom", colors.black)
term.setCursorPos(20,4)
-- if fuel == true then
-- write("OK")
-- else                      ---- if I use it this way, it just displays out all the time
-- write("Out")
-- end
write( fuel and "OK" or "Out" )
sleep(0.5)
checkLever()
end

So basically i get the state, if it is true then display ok(will reverse later), if it is false display "out" then sleep for half a second then jump back to check the lever status and keep looping back and forth updating the screen every second on the fuel and lever status.
theoriginalbit #26
Posted 26 March 2013 - 04:27 AM
oh i see what you are doing… oops. I always read that as rs.setBundledOutput.

do this

local fuel = rs.getBundledInput('bottom') -- this gets the colors that are active in the cable
write( colors.test( fuel, colors.black ) and 'OK ' or 'Out' )

You can read more on colors api here http://computercraft.info/wiki/Colors_(API)
Gibbo3771 #27
Posted 26 March 2013 - 04:31 AM
oh i see what you are doing… oops. I always read that as rs.setBundledOutput.

do this

local fuel = rs.getBundledInput('bottom') -- this gets the colors that are active in the cable
write( colors.test( fuel, colors.black ) and 'OK ' or 'Out' )

You can read more on colors api here http://computercraft...iki/Colors_(API)

Never thought of that, yeah I was sitting looking over the wiki and I was doing tests on the cable using that but never thought about doing it like that :D/>