15 posts
Posted 03 August 2012 - 09:40 PM
I'm trying to make a program that controls a 7-segment counter. Now the counter part works, but I have lots of trouble with some fancy features like quitting the program or forcing the counter to restart. I tried to put an os.pullEvent() in the loop the counter also uses for changing and displaying the current number. That didn't really work.
I don't have the original code anymore, but i wrote another little test program to just figure out the best way to do it. I didn't found any.
os.pullEvent = os.pullEventRaw
function clear()
term.clear()
term.setCursorPos(1,1)
end
clear()
local i = 0
print("Press [q] to exit")
while true do
print(i)
i = i + 1
event, param1 = os.pullEvent()
if event == "char" and param1 == "q" or param1 == "Q" then
break
else
end
sleep(1)
end
clear()
print "You stopped the program"
Now what code should do, but doesn't, is printing numbers, with a 1 second delay, counting up until q is pressed. Then it should print "you stopped the program". I'm sure this is a very simple question, but I'm still a newbie to Lua, so please help me…
1111 posts
Location
Portland OR
Posted 03 August 2012 - 10:01 PM
The best thing to do would be to try and use the parallel API.
The code would look something like this.
local function timer()
-- put your timer code here
end
local function stop()
--exit code here
end
while true do
parallel.waitForAny( timer, stop)
end
Hope this helps. I'll play with it some and try to get you a better example.
2217 posts
Location
3232235883
Posted 03 August 2012 - 10:04 PM
-snip-
1604 posts
Posted 03 August 2012 - 10:06 PM
The problem is that os.pullEvent will wait until there's an event (a key press, rednet message, etc.). You can use a timer instead of sleep to draw the counter:
local function clear()
term.clear()
term.setCursorPos(1, 1)
end
local i = 0
local timer = os.startTimer(1)
clear()
print("Press [q] to exit")
while true do
local evt, arg = os.pullEvent()
if evt == "timer" then
if arg == timer then
i = i + 1
print(i)
end
elseif evt == "char" then
if arg == "q" or arg == "Q" then
break
end
end
end
clear()
print("You stopped the program")
if event == "char" and param1 == "q" or param1 == "Q" then
break
else
param1 isnt a string, its a number that represents the key that your pressing
you can use the keys api to easialy find the number or you can use this guide:
http://www.minecraft.../wiki/Key_codes
That's for "key" events, not "char".
1111 posts
Location
Portland OR
Posted 03 August 2012 - 10:10 PM
Yea don't try and use the parallel, it does not work for this. MysticT's way is the best solution for your issue.
15 posts
Posted 05 August 2012 - 09:54 AM
I tested MysticT's code (I only edited the name of some of the variables), and it still doesn't work right. When I start the program, it says "Press [q] to continue" and after one second, "1" appears. Then it stops counting. But I can quit the program by pressing "q".
1111 posts
Location
Portland OR
Posted 05 August 2012 - 11:01 AM
Move this line into the while true loop. The timer is only getting started once.
local timer = os.startTimer(1)
Edited on 05 August 2012 - 09:03 AM
15 posts
Posted 05 August 2012 - 11:16 AM
How do I implement a restart function in this?
I already edited the code, but if I press "r" it stops counting, but doesn't stop the program, and I can quit again with "q":
local function clear()
term.clear()
term.setCursorPos(1, 1)
end
local i = 0
clear()
print("Press [q] to exit, [r] to restart")
while true do
local timer = os.startTimer(1)
local event, param1 = os.pullEvent()
if event == "timer" then
if param1 == timer then
i = i + 1
print(i)
end
elseif event == "char" then
if param1 == "q" or param1 == "Q" then
break
end
elseif event == "char" then
if param1 == "r" or param1 == "R" then
i = 0
end
end
end
print("You stopped the program")
1111 posts
Location
Portland OR
Posted 05 August 2012 - 11:51 AM
You can get that to work by removing the verification if statement "if param1 == timer" and just do the math and print. However I would advise against it your clock will become out of time and the ticks will be much less then 1 second. The timer that was running will keep running even though you press R so you will end up with more then 1 timer running at a time.
If you do it, maybe add a short sleep to allow the first timer to complete. That may keep it semi accurate.
15 posts
Posted 05 August 2012 - 01:20 PM
isn't there another way to do it? The problem is that the counter must run at exactly 1 second delay.
1604 posts
Posted 05 August 2012 - 04:14 PM
I forgot to restart the timer, this should work:
local function clear()
term.clear()
term.setCursorPos(1, 1)
end
local i = 0
local timer = os.startTimer(1)
clear()
print("Press [q] to exit")
while true do
local evt, arg = os.pullEvent()
if evt == "timer" then
if arg == timer then
i = i + 1
print(i)
timer = os.startTimer(1)
end
elseif evt == "char" then
local c = string.lower(arg)
if arg == "q" then
break
elseif arg == "r" then
i = 0
end
end
end
clear()
print("You stopped the program")
I also added the reset function.
15 posts
Posted 05 August 2012 - 06:58 PM
This code doesn't work too. Only if I press a random key, it counts. "q" And "r" just don't work (they act like all other keys). I tried cut the first timer and replaced the second with the first, but then it doesn't count, but I cab terminate it with "q". I can't see if "r" works.
1604 posts
Posted 05 August 2012 - 09:23 PM
Derp. I forgot to change the ifs to use the lowercase variable. Change this part:
local c = string.lower(arg)
if arg == "q" then
break
elseif arg == "r" then
i = 0
end
To this:
local c = string.lower(arg)
if c == "q" then
break
elseif c == "r" then
i = 0
end
It should work (although it should work like it was before, just not if you press Q or R instead of q and r).
1111 posts
Location
Portland OR
Posted 05 August 2012 - 10:49 PM
Yeah its still not going to work right. For 1 the code to restart the timer is inside the if event == timer statement. Therefor it needs a timer to go off before it will start one and if you press a key there is no timer running.
Try adding another os.startTimer(1) in the elseif c == "r" statement and see if that will do the trick.
1604 posts
Posted 05 August 2012 - 10:55 PM
Yeah its still not going to work right. For 1 the code to restart the timer is inside the if event == timer statement. Therefor it needs a timer to go off before it will start one and if you press a key there is no timer running.
Try adding another os.startTimer(1) in the elseif c == "r" statement and see if that will do the trick.
Actually the timer is started in this line:
local timer = os.startTimer(1)
And then restarted every time it triggers:
if evt == "timer" then
if arg == timer then
i = i + 1
print(i)
timer = os.startTimer(1) -- restarts the timer
end
end
I forgot to restart it when reseting the counter (when you press r). Just add the line:
timer = os.startTimer(1)
after:
elseif c == "r" then
i = 0
15 posts
Posted 06 August 2012 - 07:13 PM
Thanks, it finally works! I'll post the final code later, so that it is clear for everyone who had the same problem. (I also optimized a few things)
Edit:
This is the code:
os.pullEvent = os.pullEventRaw
local function clear()
term.clear()
term.setCursorPos(1, 1)
end
local i = 0
local timer = os.startTimer(1)
clear()
print("Press [q] to exit, [r] to restart")
while true do
local evt, arg = os.pullEvent()
if evt == "timer" then
if arg == timer then
i = i + 1
print(i)
timer = os.startTimer(1)
end
elseif evt == "char" then
local c = string.lower(arg)
if c == "q" then
break
elseif c == "r" then
clear()
print("Press [q] to exit, [r] to restart")
i = 0
timer = os.startTimer(1)
end
end
end
clear()
print("You stopped the program")
Also, I'm wondering why I can't put "local" in front of this first line ("os.pullEvent = os.pullEventRaw") it gives this error:
bios:206: [string "test2"]:1: unexpected symbol