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

Inventory Program Help

Started by SnowsongWolf, 17 July 2012 - 12:38 AM
SnowsongWolf #1
Posted 17 July 2012 - 02:38 AM
Okay, so I'm trying to write a program that will count the contents of a chest when I send a rednet message. Leaving out that part, I have this:


local time = 0
local count = 0
local timer
function getpuse()
  if rs.getInput("right") then
	while rs.getInput("right") do
	  sleep(0.1) -- wait for pulse to end
	end
	count = count + 1
	timer = os.startTimer(2)
  end
end
function tout()
  local event, param
  while time == 0 do
	event, param = os.pullEvent()
	if event == "timer" and param == timer then
	  time = 1
	end
  end
end
rs.setOutput("back", true)
while time == 0 do
  parallel.waitForAny(tout(), getpulse())
end
rs.setOutput("back", false)
rs.setOutput("front", false)
sleep(10)
rs.setOutput("front", true)
term.write(count)

The Back redstone goes to an AND gate which allows a timer pulse to drive a transposer and that hooks to an item detector which is wired to Right. Front goes to a splitter which interrupts EU flow to an energy link powering a wooden transport pipe to put the stuff back into the primary chest when it's done.

The program SHOULD be counting pulses until there's a 2 second gap but it never stops. Adding in another line inside getpulse() tells me that it's not even reading any pulses. I have a modem connected to Left which I can turn on and off so I know the input side is correctly set to Right.

Right off the bat I can see I need to start the timer before doing my while loop at the bottom or else an empty inventory will never trigger the timer event but still, why isn't my counter incrementing at all?

- Snowsong

** EDIT **
Adding in the timer = os.setTimer(2) line before the parallel process while loop results in a program I can't even terminate and I have to reboot the computer to stop it now.
MysticT #2
Posted 18 July 2012 - 12:30 AM
Some comments on the code:

local time = 0
local count = 0
local timer
function getpuse() -- should be getpulse
  if rs.getInput("right") then
	while rs.getInput("right") do
	  sleep(0.1) -- wait for pulse to end
	  -- would be better to use os.pullEvent("redstone"), so it waits for a change in redstone before checking again
	end
	count = count + 1
	timer = os.startTimer(2)
  end
end
function tout()
  local event, param
  while time == 0 do
	event, param = os.pullEvent()
	if event == "timer" and param == timer then
	  time = 1
	end
  end
end
rs.setOutput("back", true)
while time == 0 do
  parallel.waitForAny(tout(), getpulse())
end
rs.setOutput("back", false)
rs.setOutput("front", false)
sleep(10)
rs.setOutput("front", true)
term.write(count)
Also, you don't have to put the parallel call in a loop, and you definetly have to call the functions you pass to it. So it should be:

parallel.waitForAny(getpulse, tout)

Fixed code:

local count = 0
local timer

function getpulse()
  while true do
    if rs.getInput("right") then
	  while rs.getInput("right") do
	    os.pullEvent("redstone")
	end
	count = count + 1
	timer = os.startTimer(2)
  end
end

function tout()
  while true do
    local evt, param = os.pullEvent("timer")
    if param == timer then
	  break
	end
  end
end

rs.setOutput("back", true)
parallel.waitForAny(getpulse, tout)
rs.setOutput("back", false)
rs.setOutput("front", false)
sleep(10)
rs.setOutput("front", true)
write(count)
Now, it should work, but there's an eaiser way to do it.
Example:

local count = 0
local lastInput = false
local timer = os.startTimer(2)

while true do
  local evt, arg = os.pullEvent()
  if evt == "redstone" then
    local input = rs.getInput("right")
    if input ~= lastInput then -- to detect a change in the input
	  if input then -- a new pulse is on
	    count = count + 1 -- add one to the count
	    timer = nil -- stop the timer
	  else
  	  timer = os.startTimer(2) -- restart the timer when the pulse is off
	  end
	  lastInput = input -- store the new input
    end
  elseif evt == "timer" then
    if arg == timer then
	  break
    end
  end
end

print(count)
I think it's easier than messing with parallel :P/>/>
SnowsongWolf #3
Posted 18 July 2012 - 01:43 AM
That was probably a typo from me entering it in here. I don't know how to pull the code from the minecraft server and I can't seem to select, let alone copy from in-game.

I'll try the simplified code. I'm normally resourceful and lazy enough to find the easiest way myself but that WAS my first real day with lua. Thanks =D

** EDIT **

That worked absolutely perfectly, thanks! Now I just have to get it working with rednet but there's a lot of infrastructure to build first. Need the power routing center up and running before I worry about the automation facility.