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

Help with Multitasking Redstone Input/Outputs

Started by Chloe, 03 January 2014 - 06:40 PM
Chloe #1
Posted 03 January 2014 - 07:40 PM
I am new and trying to get my Coal/Wood Factory to work with computercraft, and I want it to do multiple things at once. So far, I have only figured out how to do things by making them all in one big loop. But the problem (as I can imagine there are many) is that in some instances, it has to wait for other events to happen before other inputs/outputs can do what they need to do.

I would like help with this code in getting it more functional.

It reads the amount of contents in my chest, then it makes more wood/coal/coke as needed, up to the 6912 limit of the chest (full). I don't want the chest to fill up again until the chest has reach the last stack of 64. Then it should pulse the "makeWood" or "makeCoal" or the "makeCoke". I want it to pulse quickly, but not too fast, because I have a lamp attached to the system and I want to see it flash.

The problem I am running into right now is, once it starts to make COKE, the computer wont do anything else, and I need it to multitask read the other inputs and reacting accordingly, updating inventory amounts and pulsing the other outputs so they can do/make other items at the same time.


I have started the program… so any help you can provided is appreciated.




-- CLEAR & INITIALIZE TERMINAL SCREEN
term.clear()
term.setCursorPos(1,1)
print "Loader Control System v1.0"
term.setCursorPos(1,3)
print "System: Online"

-- CLEAR & INITIALIZE MONITOR SCREEN (TOP)
local mon = peripheral.wrap("top")
mon.clear()
mon.setTextScale(1)
mon.setCursorPos(3,1)
mon.write "Loader Control System v1.0"
mon.setCursorPos(3,3)
mon.write "System: Online"

-- SET BUNDLED CABLE TO "BOTTOM" AND INITIALIZE IN/OUTPUTS (OFF)
		rs.setBundledOutput( "bottom", 0 )

-- SET BUNDLEDCABLE TO "BOTTOM"
   local CablePort = "bottom"

-- FUNCTIONS
-- PULSE
  local function pulse(side, colors, time)
  rs.setBundledOutput(side, colors)
  sleep(time / 2)
  rs.setBundledOutput(side, 0) -- 0 means no colors, so it turns the output off
  sleep(time / 2)
				end

-- SET LOOP
while true do


-- FUNCTIONS
-- PULSE
  local function pulse(side, colors, time)
  rs.setBundledOutput(side, colors)
  sleep(time / 2)
  rs.setBundledOutput(side, 0) -- 0 means no colors, so it turns the output off
  sleep(time / 2)
		   end

-- INITIALIZE COALCOKE CHEST INVENTORY COUNTER WITH CURRENT INVENTORY COUNT
os.loadAPI("ocs/apis/sensor")
local chestCokeCount = sensor.wrap("left")

		cokecount = 0
		details = chestCokeCount.getTargetDetails("-6,0,-1")
		for i = 1, #details.Slots do
		if details.Slots[i].Size then
cokecount = cokecount + details.Slots[i].Size
		  
	end
		end


-- PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
term.setCursorPos(1,5)
print("Coalcoke Inventory:", cokecount)
-- PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
mon.setCursorPos(3,5)
		mon.write "Coalcoke Inventory:"
		mon.setCursorPos(22,5)
		mon.write(tostring(cokecount))
-- BUNDLED CABLE "INPUTS"	
local rebootSystemButton = redstone.testBundledInput(CablePort, colors.lime)
local resetCounterButton = redstone.testBundledInput(CablePort, colors.yellow)
	
-- BUNDLED CABLE "OUTPUTS"
local makeWood = redstone.testBundledInput(CablePort, colors.brown)
local makeCoal = redstone.testBundledInput(CablePort, colors.black)
local makeCoke = redstone.testBundledInput(CablePort, colors.gray)
local loadwood = redstone.testBundledInput(CablePort, colors.orange)
local loadCoal = redstone.testBundledInput(CablePort, colors.blue)
local loadCoke = redstone.testBundledInput(CablePort, colors.lightBlue)

-- EVENTS
os.pullEvent("redstone")


-- REBOOT BUTTON CODE
  if rebootSystemButton == true then

--REBOOT
  term.clear()
  mon.clear()
  os.reboot()

-- RESET BUTTON CODE
  elseif resetCounterButton == true then

-- SETS THE SAVE FILE FOR COUNTER BACK TO ZERO
  cokecount = 0

	  
-- CLEAR & INITIALIZE TERMINAL SCREEN
  term.clear()
  term.setCursorPos(1,1)
  print "Loader Control System v1.0"
  term.setCursorPos(1,3)
  print "System: Online"
-- CLEAR & INITIALIZE MONITOR SCREEN (TOP)
  local mon = peripheral.wrap("top")
  mon.clear()
  mon.setTextScale(1)
  mon.setCursorPos(3,1)
  mon.write "Loader Control System v1.0"
  mon.setCursorPos(3,3)
  mon.write "System: Online"

-- PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
  term.setCursorPos(1,5)
  print("Coalcoke Inventory:", cokecount)
-- PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
  mon.setCursorPos(3,5)
  mon.write "Coalcoke Inventory:"
  mon.setCursorPos(22,5)
  mon.write(tostring(cokecount))

-- COUNT COALCOKE

term.setCursorPos(20,5)
print(cokecount)
mon.setCursorPos(22,5)
mon.write(tostring(cokecount))

-- DUPLICATE & LOAD COKE INTO CHESTS (OUTPUT)
   elseif cokecount <= 512 then
for i = 1, 6400 do
pulse(CablePort, colors.gray, .500) -- make a .5-second pulse and make COKE on Gray wire
		sleep(0.5)

		os.loadAPI("ocs/apis/sensor")
		local chestCokeCount = sensor.wrap("left")
		--# reset chest/item count
		cokecount = 0
		--# get target details for X, Y, Z location.
		details = chestCokeCount.getTargetDetails("-6,0,-1")
		--# iterate the list of slots.
		for i = 1, #details.Slots do
				if details.Slots[i].Size then
						--# add items to count
						cokecount = cokecount + details.Slots[i].Size

term.setCursorPos(1,5)
term.clearLine()
term.setCursorPos(1,5)
		print("Coalcoke Inventory:", cokecount)
mon.setCursorPos(1,5)
mon.clearLine()
		mon.setCursorPos(3,5)
		mon.write "Coalcoke Inventory:"
		mon.setCursorPos(22,5)
		mon.write(tostring(cokecount))
	  end
end
	  end
	end
end
Edited on 03 January 2014 - 06:42 PM
CometWolf #2
Posted 03 January 2014 - 10:49 PM
I had to do some serious spaghetti cleanup, couldn't work with that code lol

-- SETTINGS
local tSettings = {
  ["cokeCheckTime"] = 5 --secs
}
-- FUNCTIONS
-- PULSE
local tTimers = {}
local tSide = {}
local function pulse(side, colors, time)
  rs.setBundledOutput(side, colors)
  table.insert(tTimers,os.startTimer(time / 2))
  table.insert(tSide,side)
end
-- CHECKS COALCOKE CHEST INVENTORY AND UPDATES COUNTER WITH CURRENT INVENTORY COUNT
local checkTimer
function updateCoke()
  cokeCount = 0
  details = chestCokeCount.getTargetDetails("-6,0,-1")
	for i = 1, #details.Slots do
	if details.Slots[i].Size then
	  cokeCount = cokeCount + details.Slots[i].Size
	end
  end
  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
  term.setCursorPos(1,5)
  term.clearLine()
  print("Coalcoke Inventory:", cokecount)
  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
  mon.setCursorPos(3,5)
  mon.clearLine()
  mon.write "Coalcoke Inventory:"
  mon.setCursorPos(22,5)
  mon.write(tostring(cokecount))
  checkTimer = os.startTimer(tSettings.cokeCheckTime))
end
-- CLEAR &amp; INITIALIZE TERMINAL
term.clear()
term.setCursorPos(1,1)
print "Loader Control System v1.0"
term.setCursorPos(1,3)
print "System: Online"
-- CLEAR &amp; INITIALIZE MONITOR SCREEN (TOP)
local mon = peripheral.wrap("top")
mon.clear()
mon.setTextScale(1)
mon.setCursorPos(3,1)
mon.write "Loader Control System v1.0"
mon.setCursorPos(3,3)
mon.write "System: Online"
-- SET BUNDLED CABLE TO "BOTTOM" AND INITIALIZE IN/OUTPUTS (OFF)
local cablePort = "bottom"
rs.setBundledOutput( cablePort, 0 )
-- SENSOR SETUP
os.loadAPI("ocs/apis/sensor")
local chestCokeCount = sensor.wrap("left")
-- PROGRAM BEGINS
local cokeCount = 0
updateCoke()
-- SET LOOP
while true do
  -- EVENTS
  local tEvent = {os.pullEvent()}
  if tEvent[1] == "redstone" then
	-- REDSTONE
	-- BUNDLED CABLE "INPUTS"	  
	local rebootSystemButton = redstone.testBundledInput(cablePort, colors.lime)
	local resetCounterButton = redstone.testBundledInput(cablePort, colors.yellow
	-- REBOOT BUTTON CODE
	if rebootSystemButton == true then
	  --REBOOT
	  mon.clear()
	  os.reboot()
	-- RESET BUTTON CODE
	elseif resetCounterButton == true then
	  -- SETS THE VARIABLE FOR COUNTER BACK TO ZERO
	  cokecount = 0
	  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
	  term.setCursorPos(1,5)
	  term.clearLine()
	  print("Coalcoke Inventory:", cokecount)
	  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
	  mon.setCursorPos(3,5)
	  term.clearLine()
	  mon.write "Coalcoke Inventory:"
	  mon.setCursorPos(22,5)
	  mon.write(tostring(cokecount))
   -- DUPLICATE &amp; LOAD COKE INTO CHESTS (OUTPUT)
  elseif tEvent[1] == "timer" then
	-- TIMERS
	if tEvent[2] == checkTimer then
	  updateCoke()
	  if cokecount <= 512 then
		for i = 1, 6400 do
		pulse(CablePort, colors.gray, .500) -- make a .5-second pulse and make COKE on Gray wire
	  end
	elseif #tTimers > 0 then
	  for i=1,#tTimers do
		if tEvent[2] == tTimers[i] then
		  rs.setBundledOutput(tSide[i],0)
		  table.remove(tTimers,i)
		  table.remove(tSide,i)
		  break
		end
	  end
	end
  end
end
I haven't tested this, but it should do the trick, just configure the check timer however you like.
What i've done is, instead of sleep, i use os.startTimer(). Then i use the os.pullEvent() to pull all events, not just redstone. When a timer event fires, besides the recheck timer, it will set the redstone side saved in tSide with the same number as the timer has in the tTimer table, to 0.
Edited on 03 January 2014 - 11:43 PM
Chloe #3
Posted 04 January 2014 - 09:21 AM
Thanks for the help. I really appreciate it.

The code is not working - there were some issues with unexpected symbol on this line:

checkTimer = os.startTimer(tSettings.cokeCheckTime))

changed it to this:

checkTimer = os.startTimer(tSettings.cokeCheckTime)

also, there were more than a couple "end's" missing at the end to close if statements, etc. Not sure if I got that right were to add them, but I placed them at the end and it resolved the computer to stop giving me the error.

Additionally, you took out some needed things for the Sensor on the Left to actually get the information from the chest - I was getting an error that said it was attempting to index a nil value. I added the API back in, however, instead of the NIL value, now I get nothing counting, and it says NIL on the monitor up top.

My setup for the computercraft computer is a Monitor ontop, a bundled cable hooked to the bottom, an "openCCsensor" radar dish on the left side with an "Inventory Card x4" in the radar dish…. a Chest with some coke in it nearby (run /ocs/programs/sensorview to find target location) and a gray jacketed wire coming out of the bundle for pulsing a filter that extracts coke from it out of a duplicator when pulsed. A lime jacketed wire hooked to a button and a yellow jacketed wire hooked to another button. I need to eventually put in the other 2 chest for the wood and coal. Wood fires on the brown jacketed wire and the coal fires on the black jacketed wire.



Here is what I am working with now, based on what you gave me, and what I had to add in at the top to get things to work, some…




-- CLEAR &amp; INITIALIZE TERMINAL SCREEN
term.clear()
term.setCursorPos(1,1)
print "Loader Control System v1.0"
term.setCursorPos(1,3)
print "System: Online"

-- CLEAR &amp; INITIALIZE MONITOR SCREEN (TOP)
local mon = peripheral.wrap("top")
mon.clear()
mon.setTextScale(1)
mon.setCursorPos(3,1)
mon.write "Loader Control System v1.0"
mon.setCursorPos(3,3)
mon.write "System: Online"

-- SET BUNDLED CABLE TO "BOTTOM" AND INITIALIZE IN/OUTPUTS (OFF)
	    rs.setBundledOutput( "bottom", 0 )

-- SET BUNDLEDCABLE TO "BOTTOM"
	    local CablePort = "bottom"



-- SETTINGS
local tSettings = {
  ["cokeCheckTime"] = 5 --secs
}
-- FUNCTIONS
-- PULSE
local tTimers = {}
local tSide = {}
local function pulse(side, colors, time)
  rs.setBundledOutput(side, colors)
  table.insert(tTimers,os.startTimer(time / 2))
  table.insert(tSide,side)
end

-- CHECKS COALCOKE CHEST INVENTORY AND UPDATES COUNTER WITH CURRENT INVENTORY COUNT
local checkTimer
function updateCoke()
  os.loadAPI("ocs/apis/sensor")
  local chestCokeCount = sensor.wrap("left")
  cokeCount = 0
  details = chestCokeCount.getTargetDetails("-6,0,-1")
	    for i = 1, #details.Slots do
	    if details.Slots[i].Size then
		  cokeCount = cokeCount + details.Slots[i].Size
	    end
  end

  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
  term.setCursorPos(1,5)
  term.clearLine()
  print("Coalcoke Inventory:", cokecount)


  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
  mon.setCursorPos(3,5)
  mon.clearLine()
  mon.write "Coalcoke Inventory:"
  mon.setCursorPos(22,5)
  mon.write(tostring(cokecount))
  checkTimer = os.startTimer(tSettings.cokeCheckTime)
end

-- CLEAR &amp; INITIALIZE TERMINAL
term.clear()
term.setCursorPos(1,1)
print "Loader Control System v1.0"
term.setCursorPos(1,3)
print "System: Online"

-- CLEAR &amp; INITIALIZE MONITOR SCREEN (TOP)
local mon = peripheral.wrap("top")
mon.clear()
mon.setTextScale(1)
mon.setCursorPos(3,1)
mon.write "Loader Control System v1.0"
mon.setCursorPos(3,3)
mon.write "System: Online"

-- SET BUNDLED CABLE TO "BOTTOM" AND INITIALIZE IN/OUTPUTS (OFF)
local cablePort = "bottom"
rs.setBundledOutput( cablePort, 0 )
-- SENSOR SETUP
os.loadAPI("ocs/apis/sensor")
local chestCokeCount = sensor.wrap("left")
-- PROGRAM BEGINS
local cokeCount = 0
updateCoke()
-- SET LOOP
while true do
  -- EVENTS
  local tEvent = {os.pullEvent()}
  if tEvent[1] == "redstone" then
	    -- REDSTONE
	    -- BUNDLED CABLE "INPUTS"		
	    local rebootSystemButton = redstone.testBundledInput(cablePort, colors.lime)
	    local resetCounterButton = redstone.testBundledInput(cablePort, colors.yellow)
	    -- REBOOT BUTTON CODE
	    if rebootSystemButton == true then
		  --REBOOT
		  mon.clear()
		  os.reboot()
	    -- RESET BUTTON CODE
	    elseif resetCounterButton == true then
		  -- SETS THE VARIABLE FOR COUNTER BACK TO ZERO
		  cokecount = 0
		  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
		  term.setCursorPos(1,5)
		  term.clearLine()
		  print("Coalcoke Inventory:", cokecount)
		  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
		  mon.setCursorPos(3,5)
		  term.clearLine()
		  mon.write "Coalcoke Inventory:"
		  mon.setCursorPos(22,5)
		  mon.write(tostring(cokecount))
   -- DUPLICATE &amp; LOAD COKE INTO CHESTS (OUTPUT)
  elseif tEvent[1] == "timer" then
	    -- TIMERS
	    if tEvent[2] == checkTimer then
		  updateCoke()
		  if cokecount <= 512 then
			    for i = 1, 6400 do
			    pulse(CablePort, colors.gray, .500) -- make a .5-second pulse and make COKE on Gray wire
		  end
	    elseif #tTimers > 0 then
		  for i=1,#tTimers do
			    if tEvent[2] == tTimers[i] then
				  rs.setBundledOutput(tSide[i],0)
				  table.remove(tTimers,i)
				  table.remove(tSide,i)
				  break
			    end
end
end
		  end
	    end
  end
end
Edited on 04 January 2014 - 08:23 AM
CometWolf #4
Posted 04 January 2014 - 10:07 AM
The code is not working - there were some issues with unexpected symbol on this line:

checkTimer = os.startTimer(tSettings.cokeCheckTime))

changed it to this:

checkTimer = os.startTimer(tSettings.cokeCheckTime)

also, there were more than a couple "end's" missing at the end to close if statements, etc. Not sure if I got that right were to add them, but I placed them at the end and it resolved the computer to stop giving me the error.

Yeah, that was bound to happen since i didn't test it. anyways, the part about just placing the ends at the end…. sounds like a really bad idea.

Additionally, you took out some needed things for the Sensor on the Left to actually get the information from the chest - I was getting an error that said it was attempting to index a nil value. I added the API back in, however, instead of the NIL value, now I get nothing counting, and it says NIL on the monitor up top.
probably related to the ends you added, as i did not remove the wrap or os.loadAPI, i simply placed these before the loop, as they are only needed once. No reason to wrap the same sensor to the same side again, or load the same api again.

Gimme a few minutes and i'll have a look into it
Chloe #5
Posted 04 January 2014 - 10:13 AM
I'm learning… lol

I really appreciate your help, and any notes you include in the code that explain what is going on. I really want to learn, and a few weeks ago, I didn't know anything. I have been picking things up along the way from this forum and people that have helped me. The code I wrote, was a conglomerate of other lessons that I have pieced together. I know I need to learn the basics - so, your feedback is very appreciated… and your patients with me. :)/>
Edited on 04 January 2014 - 09:13 AM
CometWolf #6
Posted 04 January 2014 - 10:34 AM
No worries, i enjoy anything related to coding anyways.
Give this one a go http://pastebin.com/nn3ivk50, i couldn't test it cause the openCCSensors included in ftb monster is derped. My computer dosen't even have the ocs folder lol.
Also, you might have to make some changes once you get more redstone outputs in there. Cause when you set a redstone cable to a specific color or 0, that is the only color it will power on. Using the colors.combine and colors.subtract functions is probably the best way to go about doing this. http://computercraft.info/wiki/index.php?title=Colors_%28API%29
Chloe #7
Posted 04 January 2014 - 11:21 AM
Same problem.

These items must be at the top first - otherwise, it still gives me an error that its trying to index a nil value. Once I put them at the top of the code, then that error goes away. However, it still prints nothing to the screen, and I can't even force it to print a value. I know the chest target location is correct. When I run my original code that I had first posted, I can at least get the chest inventory count.


local mon = peripheral.wrap("top")
os.loadAPI("ocs/apis/sensor")
local chestCokeCount = sensor.wrap("left")

It still is not counting or acquiring anything.
If I press the reset or Reboot button, it ends the program with an error.


What I think maybe the problem, is the Tables


Also, I believe they fixed the issue with openCCsensors. There is a new version you can download, and place the file in your FTB mod pack folder. It fixes the issue.
Edited on 04 January 2014 - 10:26 AM
Moody #8
Posted 04 January 2014 - 11:52 AM
Hey there!
Regarding your original code:
You should really try to use more functions, makes your life easier. (e.g. use a function to print your Startupscreen, so you dont have to do it all over again)
I found it pretty important to just to try to make a function out of everything - otherwise my code just tends to clump up, repeats or just take much time to understand. (especially if your code grows bigger)
Also: Dont load an API to a subfunction as this will load it everytime you call the subfunction - instead load it once at the start of your mainprogram. (In CometWolf's code - probably a mistake?)

To the topic:
With this code you cant really conveniently handle inputs WHILE it is processing a task, because the event listener will block everything.
Try the Parallel API ( http://computercraft.&#46;&#46;/Parallel_(API) ) and run a job processing queue (i would advice to create a real jobqueue, e.g. with a table - you can save &amp; load after a restart of minecraft) und run an eventlistener and handler parallel to it.
Edited on 04 January 2014 - 10:56 AM
CometWolf #9
Posted 04 January 2014 - 11:53 AM
turns out monster dosen't include openCCS, so i just installed it lol.
Anyways, after some testing, i have fixed it.
http://pastebin.com/mqb06tc2
for some reason wrapping stuff to local variables and then calling them within a function later dosen't work. I suspect this is because the function was global and the variable was local, but anyhow i just changed the variables to global.
And the text was printing wrong cause i wrote cokecount instead of cokeCount, derp.

However, lookin at the code a bit more closely… i noticed you want to make 6400 pulses in a row, so we'll need to do some modifications to account for that aswell. Like preventing it from triggering more pulses while it's still making the original set, aswell as making it pause inbetween each pulse without using sleep. Right now it will jsut make all the pulses at the same time.
Chloe #10
Posted 04 January 2014 - 12:15 PM
Ok, that is working better.

However, once it sees the chest is less that 512, it send one solid pulse of red stone, instead of oscillating the count of pulses.

Let me future explain. The point of the reset button was to eventually CLEAR the inventory completely of all items and rest the count. The reboot button is just to reboot the computer. I know there is more code needed to clear the inventory - however, I am not aware of it yet….

I need to study how functions work and tables work. This is my weakness.

Anyhow, that is where I am at.

I'm off to Chicago now, so chat in 24hrs. I have access to the forum on my iphone, but wont be able to test until I get back.

THANK YOU! *hugs*
Edited on 04 January 2014 - 11:17 AM
CometWolf #11
Posted 04 January 2014 - 12:22 PM
Yeah that happens because the previous code was meant for single pulses each time the function was called. I've fixed this now, so give this one a try.
http://pastebin.com/pHm0RRVr
i added some comments so it's easier to understand what im doing. I can't test it myself btw, as ftb monster does not have cc supported bundled cables.
Moody #12
Posted 04 January 2014 - 12:35 PM
for some reason wrapping stuff to local variables and then calling them within a function later dosen't work. I suspect this is because the function was global and the variable was local, but anyhow i just changed the variables to global.

actually, local variables are just defined in the block they were declared - you can even do the following:


  local x, y = 1, 10
	if x<y then
	  print(x)   -- prints  "1"
	  local x   = nil
	  print(x)   -- prints "nil"
	end		  -- ends the block started with 'then'
	print(x,y)   -- prints  1   10

so changes made to local variables dont even persist after their block is finished
Edited on 04 January 2014 - 11:37 AM
CometWolf #13
Posted 04 January 2014 - 12:48 PM
Indeed, but if your read the program, you would see that the variables are declared in the main block of the program, same as the functions which used them. Ergo it should have worked.
Moody #14
Posted 04 January 2014 - 04:00 PM
Indeed, but if your read the program, you would see that the variables are declared in the main block of the program, same as the functions which used them. Ergo it should have worked.

Well i think the matter lies with the order of declaration - for example:
If you do this:

local function f()
  print(x)
end
f()
x = 6
f()

It will print "5 \n 6"
but if you do


local function f()
  print(x)
end
local x = 5
f()
x = 6
f()

it will print "nil \n nil"

because it compiles the code from top to bottom, it sets all not defined variables environments to global - in this case, there doesnt exist any global x! so it return Nil.
To understand that better: this is the way the compiler works:

local x = 5  -- Declare variable x as local -> create new Environment _ENV
local function f()
  print(x) -- x translates to _ENV["x"], because it was declared physically beforehead
end

vs

local function f()
  print(x) -- "Was it declared beforehand?" -> No -> x translates to _G["x"]
end
local x = 5 -- -- Declare variable x as local -> create new Environment _ENV
(note that there is no actual "current" Environment, it rather accesses the register directly, but for simplicities sake i left it at that)

now you have 2 totally different Environment references:
In the first case, the variable X in the function has the Environment _ENV.
In the second case, the variable X has the global Environment _G

So if you would declare a variable "local chestcokecount" before you declare the function it would be fine. (you can just declare without a value at all)


To give another example:

local function f()
  print(x)
end
local x = 8
_G["x"] = 5
f() --> 5
x = 6
print("Local:"..x)
f() --> 6
returns this:

5
Local:6
5
Edited on 04 January 2014 - 03:31 PM
CometWolf #15
Posted 04 January 2014 - 04:32 PM
You are indeed correct. I've never had the problem before as i always declare the variable prior to using it, so it never crossed my mind. I usually do my wrapping at the start.
Chloe #16
Posted 06 January 2014 - 03:46 PM
It doesn't pulse the Gray wire at all now. It should pulse when the chest is lower than 512. I can get it to do anything to go. Something is wrong.
CometWolf #17
Posted 06 January 2014 - 04:12 PM
Im a derp, i mixed up the subtraction and addition of redstone colors, so it was removing gray when it was supposed to add it.
Also realized i could use rednet cables to test it, so i know it runs now :P/>
http://pastebin.com/pHm0RRVr
Chloe #18
Posted 06 January 2014 - 04:26 PM
well, it pulses now, but only makes a few pieces, then it stops making them. It keeps printing "Got Timer!" on the screen too?! The count on the screen only updates every few seconds - it doesn't show in real time 1 by 1 by 1, etc… not sure. I think it may be the order things are in?
OReezy #19
Posted 06 January 2014 - 05:06 PM
What are you using to move items?
CometWolf #20
Posted 06 January 2014 - 05:19 PM
Like i already said, you have to set the update timer for how often to check the coke. Come on, atleast look through the code, it's literally the first thing in it… I've set it to 5 secs to be on the safe side. as for the got timer thing, that was me doing some testing, forgot to remove it :P/>
I haven't tested this, but it should do the trick, just configure the check timer however you like.
From what i can tell it stops pulsing if the sensor is in use at the same time the timer is supposed to fire. My guess would be it's a bug with the sensor really. Anyhows, i did a quick work around to restart the timer whenever the sensor is used. And i set the coke update to 2 secs.
http://pastebin.com/pHm0RRVr
Chloe #21
Posted 06 January 2014 - 08:26 PM
Hey, thank you for all your help. I took a long hard look at it. I am trying to follow your methodology of using the tables. What I am having trouble with, and I took a while to see if I could figure it out, and can't, is, that, even though it is set to ONLY make coke if its at 512 or less, it STILL makes coke no matter what number the chest has in it.
Edited on 06 January 2014 - 07:28 PM
Moody #22
Posted 07 January 2014 - 05:30 AM
Maybe the same problem as earlier discussed in this thread.
try to remove

local cokeCount = 0
completely and test again
CometWolf #23
Posted 07 January 2014 - 09:25 AM
lol good point, i should pay more attention to this stuff when im not working with my own code i guess.
http://pastebin.com/pHm0RRVr
I moved it to it's proper location, above the function updating it.
Edited on 07 January 2014 - 08:26 AM
Chloe #24
Posted 07 January 2014 - 08:44 PM
Awesome. THANK YOU.

I took the code and tried adding in the additional for the coal, and the wood. The wood and coal will pulse when below 512, but for some reason, the coke also has to be below 512 too for the coal and wood to fire. I have a feeling it is due to the DUPLICATION portion at the bottom of the code. Either I have the tables messed up, or, the ENDs in the wrong order.

What do you think?



Spoiler– SETTINGS
local tSettingsCoke = {
["cokeCheckTime"] = 1 –secs
}

local tSettingsCoal = {
["coalCheckTime"] = 1 –secs
}

local tSettingsWood = {
["woodCheckTime"] = 1 –secs
}















– COKE FUNCTIONS
– PULSE COKE
local tTimersCoke = {}
local tRsCoke = {}
local tNameCoke = {}

local function pulseCoke(side, colors, time,name,amount)
for i=1,#tRsCoke do
if name == tRsCoke["name"] then
return –cancels pulseCoke if it's already running
end
end
table.insert(tTimersCoke,os.startTimer(time)) – starts pulseCoke timer
table.insert(tRsCoke,{
["side"] = side,
["color"] = colors,
["amount"] = amount or 1,
["time"] = time,
["name"] = name
}) – creates table containing relevant rs and timer info
end




– COAL FUNCTIONS
– PULSE COAL
local tTimersCoal = {}
local tRsCoal = {}
local tNameCoal = {}

local function pulseCoal(side, colors, time,name,amount)
for i=1,#tRsCoal do
if name == tRsCoal["name"] then
return –cancels pulseCoal if it's already running
end
end
table.insert(tTimersCoal,os.startTimer(time)) – starts pulseCoal timer
table.insert(tRsCoal,{
["side"] = side,
["color"] = colors,
["amount"] = amount or 1,
["time"] = time,
["name"] = name
}) – creates table containing relevant rs and timer info
end




– WOOD FUNCTIONS
– PULSE WOOD
local tTimersWood = {}
local tRsWood = {}
local tNameWood = {}

local function pulseWood(side, colors, time,name,amount)
for i=1,#tRsWood do
if name == tRsWood["name"] then
return –cancels pulseWood if it's already running
end
end
table.insert(tTimersWood,os.startTimer(time)) – starts pulseWood timer
table.insert(tRsWood,{
["side"] = side,
["color"] = colors,
["amount"] = amount or 1,
["time"] = time,
["name"] = name
}) – creates table containing relevant rs and timer info
end














– CHECKS COALCOKE CHEST INVENTORY AND UPDATES COUNTER WITH CURRENT INVENTORY COUNT
local checkTimerCoke
local cokeCount = 0
function updateCoke()
cokeCount = 0
detailsCoke = chestCokeCount.getTargetDetails("-6,0,-1")
for i = 1, #detailsCoke.Slots do
if detailsCoke.Slots.Size then
cokeCount = cokeCount + detailsCoke.Slots.Size
end
end

– PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
term.setCursorPos(1,5)
term.clearLine()
print("Coalcoke Inventory:", cokeCount)
– PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
mon.setCursorPos(3,5)
mon.clearLine()
mon.write "Coalcoke Inventory:"
mon.setCursorPos(22,5)
mon.write(tostring(cokeCount))
checkTimerCoke = os.startTimer(tSettingsCoke.cokeCheckTime)
for i=1,#tRsCoke do
tTimersCoke = os.startTimer(tRsCoke["time"])
end
end





– CHECKS COAL CHEST INVENTORY AND UPDATES COUNTER WITH CURRENT INVENTORY COUNT
local checkTimerCoal
local coalCount = 0
function updateCoal()
coalCount = 0
detailsCoal = chestCoalCount.getTargetDetails("-6,0,1")
for i = 1, #detailsCoal.Slots do
if detailsCoal.Slots.Size then
coalCount = coalCount + detailsCoal.Slots.Size
end
end

– PRINT CURRENT COAL INVENTORY COUNT TO TERMINAL SCREEN
term.setCursorPos(1,6)
term.clearLine()
print(" Coal Inventory:", coalCount)
– PRINT CURRENT COAL INVENTORY COUNT TO MONITOR SCREEN (TOP)
mon.setCursorPos(3,6)
mon.clearLine()
mon.write " Coal Inventory:"
mon.setCursorPos(22,6)
mon.write(tostring(coalCount))
checkTimerCoal = os.startTimer(tSettingsCoal.coalCheckTime)
for i=1,#tRsCoal do
tTimersCoal = os.startTimer(tRsCoal["time"])
end
end





– CHECKS WOOD CHEST INVENTORY AND UPDATES COUNTER WITH CURRENT INVENTORY COUNT
local checkTimerWood
local woodCount = 0
function updateWood()
woodCount = 0
detailsWood = chestWoodCount.getTargetDetails("-6,0,3")
for i = 1, #detailsWood.Slots do
if detailsWood.Slots.Size then
woodCount = woodCount + detailsWood.Slots.Size
end
end

– PRINT CURRENT WOOD INVENTORY COUNT TO TERMINAL SCREEN
term.setCursorPos(1,7)
term.clearLine()
print(" Wood Inventory:", woodCount)
– PRINT CURRENT WOOD INVENTORY COUNT TO MONITOR SCREEN (TOP)
mon.setCursorPos(3,7)
mon.clearLine()
mon.write " Wood Inventory:"
mon.setCursorPos(22,7)
mon.write(tostring(woodCount))
checkTimerWood = os.startTimer(tSettingsWood.woodCheckTime)
for i=1,#tRsWood do
tTimersWood = os.startTimer(tRsWood["time"])
end
end





















– CLEAR &amp; INITIALIZE TERMINAL
term.clear()
term.setCursorPos(1,1)
print "Loader Control System v1.0"
term.setCursorPos(1,3)
print "System: Online"


– CLEAR &amp; INITIALIZE MONITOR SCREEN (TOP)
mon = peripheral.wrap("top")
mon.clear()
mon.setTextScale(1)
mon.setCursorPos(3,1)
mon.write "Loader Control System v1.0"
mon.setCursorPos(3,3)
mon.write "System: Online"








– SET BUNDLED CABLE TO "BOTTOM" AND INITIALIZE IN/OUTPUTS (OFF)
local cablePort = "bottom"
rs.setBundledOutput( cablePort, 0 )







– SENSOR SETUP
os.loadAPI("ocs/apis/sensor")
chestCokeCount = sensor.wrap("left")
chestCoalCount = sensor.wrap("left")
chestWoodCount = sensor.wrap("left")











– PROGRAM BEGINS
updateCoke()
updateCoal()
updateWood()










– SET LOOP
while true do










– EVENTS

local tEvent = {os.pullEvent()}






– BUTTON EVENTS ****

term.setCursorPos(1,5)

if tEvent[1] == "redstone" then
– REDSTONE
– BUNDLED CABLE "INPUTS"
local rebootSystemButton = redstone.testBundledInput(cablePort, colors.lime)
local resetCounterButton = redstone.testBundledInput(cablePort, colors.yellow)
– REBOOT BUTTON CODE
if rebootSystemButton == true then
–REBOOT
mon.clear()
os.reboot()
– RESET BUTTON CODE
elseif resetCounterButton == true then
– SETS THE VARIABLE FOR COUNTER BACK TO ZERO
cokecount = 0
– PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
term.setCursorPos(1,5)
term.clearLine()
print("Coalcoke Inventory:", cokecount)
– PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
mon.setCursorPos(3,5)
term.clearLine()
mon.write "Coalcoke Inventory:"
mon.setCursorPos(22,5)
mon.write(tostring(cokecount))
end








– DUPLICATE &amp; LOAD COKE INTO CHESTS (OUTPUT)

elseif tEvent[1] == "timer" then
– TIMERS
if tEvent[2] == checkTimerCoke then – whenever this timer is fired, the coke count will be checked again
updateCoke()
if cokeCount <= 512 then
pulseCoke(cablePort, colors.gray, 0.5,"coke",6400) – make a .5-second pulse and make COKE on Gray wire
end

elseif #tTimersCoke > 0 then –if it's not the checkTimerCoke, it will check the tTimersCoke table
for i=1,#tTimersCoke do
if tEvent[2] == tTimersCoke then
local curColors = rs.getBundledOutput(tRsCoke["side"]) – get current output colors
if colors.test(curColors,tRsCoke["color"]) then –checks if pulse color is on or not
–already on
rs.setBundledOutput(tRsCoke["side"],colors.subtract(curColors,tRsCoke["color"])) – removes pulse color from current output
tRsCoke["amount"] = tRsCoke["amount"]-1 –subtracts amount of pulses by one
else – not on
rs.setBundledOutput(tRsCoke["side"],colors.combine(curColors,tRsCoke["color"])) –adds pulse color to current output
end
if tRsCoke["amount"] <= 0 then –checks amount, if it's 0 or less the table indices are removed
table.remove(tTimersCoke,i) –clears the fired timer from the table
table.remove(tRsCoke,i) –clears the redstone info from the table
else –otherwise, the timer is started up again
tTimersCoke = os.startTimer(tRsCoke["time"])
end



elseif tEvent[1] == "timer" then
if tEvent[2] == checkTimerCoal then – whenever this timer is fired, the coal count will be checked again
updateCoal()
if coalCount <= 512 then
pulseCoal(cablePort, colors.black, 0.5,"coal",6400) – make a .5-second pulse and make COAL on Black wire
end
elseif #tTimersCoal > 0 then –if it's not the checkTimerCoal, it will check the tTimersCoal table
for i=1,#tTimersCoal do
if tEvent[2] == tTimersCoal then
local curColors = rs.getBundledOutput(tRsCoal["side"]) – get current output colors
if colors.test(curColors,tRsCoal["color"]) then –checks if pulse color is on or not
–already on
rs.setBundledOutput(tRsCoal["side"],colors.subtract(curColors,tRsCoal["color"])) – removes pulse color from current output
tRsCoal["amount"] = tRsCoal["amount"]-1 –subtracts amount of pulses by one
else – not on
rs.setBundledOutput(tRsCoal["side"],colors.combine(curColors,tRsCoal["color"])) –adds pulse color to current output
end
if tRsCoal["amount"] <= 0 then –checks amount, if it's 0 or less the table indices are removed
table.remove(tTimersCoal,i) –clears the fired timer from the table
table.remove(tRsCoal,i) –clears the redstone info from the table
else –otherwise, the timer is started up again
tTimersCoal = os.startTimer(tRsCoal["time"])
end




elseif tEvent[1] == "timer" then
if tEvent[2] == checkTimerWood then – whenever this timer is fired, the wood count will be checked again
updateWood()
if woodCount <= 512 then
pulseWood(cablePort, colors.brown, 0.5,"wood",6400) – make a .5-second pulse and make WOOD on Brown wire
end
elseif #tTimersWood > 0 then –if it's not the checkTimerWood, it will check the tTimersWood table
for i=1,#tTimersWood do
if tEvent[2] == tTimersWood then
local curColors = rs.getBundledOutput(tRsWood["side"]) – get current output colors
if colors.test(curColors,tRsWood["color"]) then –checks if pulse color is on or not
–already on
rs.setBundledOutput(tRsWood["side"],colors.subtract(curColors,tRsWood["color"])) – removes pulse color from current output
tRsWood["amount"] = tRsWood["amount"]-1 –subtracts amount of pulses by one
else – not on
rs.setBundledOutput(tRsWood["side"],colors.combine(curColors,tRsWood["color"])) –adds pulse color to current output
end
if tRsWood["amount"] <= 0 then –checks amount, if it's 0 or less the table indices are removed
table.remove(tTimersCoal,i) –clears the fired timer from the table
table.remove(tRsWood,i) –clears the redstone info from the table
else –otherwise, the timer is started up again
tTimersWood = os.startTimer(tRsWood["time"])
end



end
end
end

end
end
end


end
end
end
end
end
Edited on 08 January 2014 - 04:12 AM
oeed #25
Posted 08 January 2014 - 03:23 AM
Awesome. THANK YOU. I took the code and tried adding in the additional for the coal, and the wood. The wood and coal will pulse when below 512, but for some reason, the coke also has to be below 512 too for the coal and wood to fire. I have a feeling it is due to the DUPLICATION portion at the bottom of the code. Either I have the tables messed up, or, the ENDs in the wrong order. What do you think? –snip–

I highly recommend you wrap spoiler tags around you code, the code takes up a huge amount of space.

What do you mean by pulse?

To use spoiler tags, put SPOILER in between two square brackets (I can't write it as it converts it to a spoiler) then the same but with a / in front of the SPOILER to end it. It's just like code tags but with spoiler instead.

Which does this:

SpoilerStuff here
Edited on 08 January 2014 - 02:27 AM
Chloe #26
Posted 08 January 2014 - 05:16 AM
I highly recommend you wrap spoiler tags around you code, the code takes up a huge amount of space.


Thank you for the tip! I have made the change.


What do you mean by pulse?


The computer program will "pulse" a redstone signal to a specified color wire in the bundled cable. Meaning, it will turn it ON and then OFF for a set interval of amount of times, and have a set length of duration for each pulse to be ON and then OFF.
CometWolf #27
Posted 08 January 2014 - 05:33 AM
Lookin through the code you posted, you did it all wrong lol. Just reuse the original pulse function, instead of making multiple copies of it. Otherwise it won't work properly.
Chloe #28
Posted 08 January 2014 - 04:41 PM
I have tried using the original pulse Function, but then I can't get anything to fire.

Would making everything a function like this, help?

I am just stuck… and way over my head. :(/>


function func1()
  while true do
    --stuff
  end
end
function func2()
  while true do
    --more stuff
  end
end
parallel.waitForAny(func1,func2)
Edited on 08 January 2014 - 03:41 PM
CometWolf #29
Posted 08 January 2014 - 06:13 PM
Personally im not big on parallel, as i feel It should'nt nessacary, that's why we use events. But yes, it could work. You would need a seperate function for each of the pulses however, because each time you called sleep with the functions running it parallel it would yield for that long.
So basically one function that updates all your inventories then sleeps for say 2-3 secs, and one function per each color of redstone pulse that uses sleep() to time them. Keep in mind that each function needs to run in it's own while true do loop, to avoid ending the function.
Chloe #30
Posted 08 January 2014 - 07:59 PM
I DID IT!!!

Ok, I finally figured how to do what you said – repeat using the same pulse function – and I was able to clean up the DUPLICATION portion of the code, and it works PERFECT!

THANK YOU! THANK YOU! THANK YOU!

I still need to address some minor concerns with the reset and reboot button, but I think I can manage that.


Take a look at the finished code.



-- SETTINGS
local tSettingsCoke = {
  ["cokeCheckTime"] = 1 --secs
}
local tSettingsCoal = {
  ["coalCheckTime"] = 1 --secs
}
local tSettingsWood = {
  ["woodCheckTime"] = 1 --secs
}


-- FUNCTIONS
-- COKE
local tTimers = {}
local tRs = {}
local tNamee = {}
local function pulse(side, colors, time,name,amount)
  for i=1,#tRs do
    if name == tRs[i]["name"] then
	  return --cancels pulse if it's already running
    end
  end
  table.insert(tTimers,os.startTimer(time)) -- starts pulse timer
  table.insert(tRs,{
    ["side"] = side,
    ["color"] = colors,
    ["amount"] = amount or 1,
    ["time"] = time,
    ["name"] = name
  }) -- creates table containing relevant rs and timer info
end

-- CHECKS COALCOKE CHEST INVENTORY AND UPDATES COUNTER WITH CURRENT INVENTORY COUNT
local checkTimerCoke
local cokeCount = 0
function updateCoke()
  cokeCount = 0
  detailsCoke = chestCokeCount.getTargetDetails("-6,0,-1")
  for i = 1, #detailsCoke.Slots do
    if detailsCoke.Slots[i].Size then
	  cokeCount = cokeCount + detailsCoke.Slots[i].Size
    end
  end
 
  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
  term.setCursorPos(1,5)
  term.clearLine()
  print("Coalcoke Inventory:", cokeCount)
  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
  mon.setCursorPos(3,5)
  mon.clearLine()
  mon.write "Coalcoke Inventory:"
  mon.setCursorPos(22,5)
  mon.write(tostring(cokeCount))
  checkTimerCoke = os.startTimer(tSettingsCoke.cokeCheckTime)
  for i=1,#tRs do
    tTimers[i] = os.startTimer(tRs[i]["time"])
  end
end

-- CHECKS COAL CHEST INVENTORY AND UPDATES COUNTER WITH CURRENT INVENTORY COUNT
local checkTimerCoal
local coalCount = 0
function updateCoal()
  coalCount = 0
  detailsCoal = chestCoalCount.getTargetDetails("-6,0,1")
  for i = 1, #detailsCoal.Slots do
    if detailsCoal.Slots[i].Size then
	  coalCount = coalCount + detailsCoal.Slots[i].Size
    end
  end
 
  -- PRINT CURRENT COAL INVENTORY COUNT TO TERMINAL SCREEN
  term.setCursorPos(1,6)
  term.clearLine()
  print("    Coal Inventory:", coalCount)
  -- PRINT CURRENT COAL INVENTORY COUNT TO MONITOR SCREEN (TOP)
  mon.setCursorPos(3,6)
  mon.clearLine()
  mon.write "    Coal Inventory:"
  mon.setCursorPos(22,6)
  mon.write(tostring(coalCount))
  checkTimerCoal = os.startTimer(tSettingsCoal.coalCheckTime)
  for i=1,#tRs do
    tTimers[i] = os.startTimer(tRs[i]["time"])
  end
end

-- CHECKS WOOD CHEST INVENTORY AND UPDATES COUNTER WITH CURRENT INVENTORY COUNT
local checkTimerWood
local woodCount = 0
function updateWood()
  woodCount = 0
  detailsWood = chestWoodCount.getTargetDetails("-6,0,3")
  for i = 1, #detailsWood.Slots do
    if detailsWood.Slots[i].Size then
	  woodCount = woodCount + detailsWood.Slots[i].Size
    end
  end
 
  -- PRINT CURRENT WOOD INVENTORY COUNT TO TERMINAL SCREEN
  term.setCursorPos(1,7)
  term.clearLine()
  print("    Wood Inventory:", woodCount)
  -- PRINT CURRENT WOOD INVENTORY COUNT TO MONITOR SCREEN (TOP)
  mon.setCursorPos(3,7)
  mon.clearLine()
  mon.write "    Wood Inventory:"
  mon.setCursorPos(22,7)
  mon.write(tostring(woodCount))
  checkTimerWood = os.startTimer(tSettingsWood.woodCheckTime)
  for i=1,#tRs do
    tTimers[i] = os.startTimer(tRs[i]["time"])
  end
end


-- CLEAR &amp; INITIALIZE TERMINAL
term.clear()
term.setCursorPos(1,1)
print "Loader Control System v1.0"
term.setCursorPos(1,3)
print "System: Online"

-- CLEAR &amp; INITIALIZE MONITOR SCREEN (TOP)
mon = peripheral.wrap("top")
mon.clear()
mon.setTextScale(1)
mon.setCursorPos(3,1)
mon.write "Loader Control System v1.0"
mon.setCursorPos(3,3)
mon.write "System: Online"


-- SET BUNDLED CABLE TO "BOTTOM" AND INITIALIZE IN/OUTPUTS (OFF)
local cablePort = "bottom"
rs.setBundledOutput( cablePort, 0 )

-- SENSOR SETUP
os.loadAPI("ocs/apis/sensor")
chestCokeCount = sensor.wrap("left")
chestCoalCount = sensor.wrap("left")
chestWoodCount = sensor.wrap("left")


-- PROGRAM BEGINS
updateCoke()
updateCoal()
updateWood()

-- SET LOOP
while true do


-- EVENTS
  local tEvent = {os.pullEvent()}


  -- BUTTON EVENTS ****
  term.setCursorPos(1,5)
  if tEvent[1] == "redstone" then
    -- REDSTONE
    -- BUNDLED CABLE "INPUTS"	   
    local rebootSystemButton = redstone.testBundledInput(cablePort, colors.lime)
    local resetCounterButton = redstone.testBundledInput(cablePort, colors.yellow)
    -- REBOOT BUTTON CODE
    if rebootSystemButton == true then
	  --REBOOT
	  mon.clear()
	  os.reboot()
    -- RESET BUTTON CODE
    elseif resetCounterButton == true then
	  -- SETS THE VARIABLE FOR COUNTER BACK TO ZERO
	  cokecount = 0
	  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO TERMINAL SCREEN
	  term.setCursorPos(1,5)
	  term.clearLine()
	  print("Coalcoke Inventory:", cokecount)
	  -- PRINT CURRENT COALCOKE INVENTORY COUNT TO MONITOR SCREEN (TOP)
	  mon.setCursorPos(3,5)
	  term.clearLine()
	  mon.write "Coalcoke Inventory:"
	  mon.setCursorPos(22,5)
	  mon.write(tostring(cokecount))
    end



  -- DUPLICATE &amp; LOAD COKE, COAL AND WOOD INTO CHESTS (OUTPUT)
elseif tEvent[1] == "timer" then
    -- TIMERS
    if tEvent[2] == checkTimerCoke then -- whenever this timer is fired, the coke count will be checked again
	  updateCoke()
	  if cokeCount <= 512 then
	    pulse(cablePort, colors.gray, 0.5,"coke",6400) -- make a .5-second pulse and make COKE on Gray wire
	  end

elseif tEvent[1] == "timer" then
    if tEvent[2] == checkTimerCoal then -- whenever this timer is fired, the clearsoal count will be checked again
	  updateCoal()
	  if coalCount <= 512 then
	    pulse(cablePort, colors.black, 0.5,"coal",6400) -- make a .5-second pulse and make COAL on Black wire
	  end

elseif tEvent[1] == "timer" then
    if tEvent[2] == checkTimerWood then -- whenever this timer is fired, the wood count will be checked again
	  updateWood()
	  if woodCount <= 512 then
	    pulse(cablePort, colors.brown, 0.5,"wood",6400) -- make a .5-second pulse and make WOOD on Brown wire
	  end

   
    elseif #tTimers > 0 then --if it's not the checkTimerCoke, it will check the tTimers table
	  for i=1,#tTimers do
	    if tEvent[2] == tTimers[i] then
		  local curColors = rs.getBundledOutput(tRs[i]["side"]) -- get current output colors
		  if colors.test(curColors,tRs[i]["color"]) then --checks if pulse color is on or not
		    --already on
		    rs.setBundledOutput(tRs[i]["side"],colors.subtract(curColors,tRs[i]["color"])) -- removes pulse color from current output
		    tRs[i]["amount"] = tRs[i]["amount"]-1 --subtracts amount of pulses by one
		  else -- not on
		    rs.setBundledOutput(tRs[i]["side"],colors.combine(curColors,tRs[i]["color"])) --adds pulse color to current output
		  end
		  if tRs[i]["amount"] <= 0 then --checks amount, if it's 0 or less the table indices are removed
		    table.remove(tTimers,i) --clears the fired timer from the table
		    table.remove(tRs,i) --clears the redstone info from the table
		  else --otherwise, the timer is started up again
		    tTimers[i] = os.startTimer(tRs[i]["time"])
		  end
		    end
		  end
	    end
	  end
    end
  end
end


I am now going to add another computer that will read the amount of inventory that is in my Railcraft Loaders for Coke,Coal, and Wood, and I will send the inventory count back to my main computer (This program we just worked on) and I will add another function to fill the loaders from the chest as needed.

I could not have done this without you CometWolf! You are daBomb!
Edited on 08 January 2014 - 07:06 PM
CometWolf #31
Posted 08 January 2014 - 08:36 PM

elseif tEvent[1] == "timer" then
    -- TIMERS
    if tEvent[2] == checkTimerCoke then -- whenever this timer is fired, the coke count will be checked again
		  updateCoke()
		  if cokeCount <= 512 then
		    pulse(cablePort, colors.gray, 0.5,"coke",6400) -- make a .5-second pulse and make COKE on Gray wire
		  end
elseif tEvent[1] == "timer" then
    if tEvent[2] == checkTimerCoal then -- whenever this timer is fired, the clearsoal count will be checked again
		  updateCoal()
		  if coalCount <= 512 then
		    pulse(cablePort, colors.black, 0.5,"coal",6400) -- make a .5-second pulse and make COAL on Black wire
		  end
elseif tEvent[1] == "timer" then
    if tEvent[2] == checkTimerWood then -- whenever this timer is fired, the wood count will be checked again
		  updateWood()
		  if woodCount <= 512 then
		    pulse(cablePort, colors.brown, 0.5,"wood",6400) -- make a .5-second pulse and make WOOD on Brown wire
		  end
Does this actually work? cause i don't think it should :P/> there should only be one if tEvent[1] == "timer" then
everything else should go inside that if statement.
Chloe #32
Posted 08 January 2014 - 09:36 PM
Its working perfect!
CometWolf #33
Posted 08 January 2014 - 09:39 PM
lol i think i know why, the ends are messed up aswell. Oh well, if it ain't broke, don't fix it i guess.
Chloe #34
Posted 08 January 2014 - 10:00 PM
If you know how to fix it, please enlighten/show me. I would love to learn.

As for your project, that is awesome!


I've been thinking about a program that would act as a PLC (like for machinery) where you could have a simple interface for inputs and out puts and select the color cable, and function you expect it to do. It would make building machinery easier for a wider base of people who do not understand how to use computercraft.
CometWolf #35
Posted 08 January 2014 - 10:14 PM
a PLC in computercraft would be godamn amazing, im an automatition so i have extensive PLC knowledge hehe…
Anyways, the code

-- DUPLICATE &amp; LOAD COKE, COAL AND WOOD INTO CHESTS (OUTPUT)
  elseif tEvent[1] == "timer" then --checks for timer event
    -- TIMERS
    if tEvent[2] == checkTimerCoke then -- whenever this timer is fired, the coke count will be checked again
	  updateCoke()
	  if cokeCount <= 512 then
	    pulse(cablePort, colors.gray, 0.5,"coke",6400) -- make a .5-second pulse and make COKE on Gray wire
	  end
    elseif tEvent[2] == checkTimerCoal then -- whenever this timer is fired, the clearsoal count will be checked again
	  updateCoal()
	  if coalCount <= 512 then
	    pulse(cablePort, colors.black, 0.5,"coal",6400) -- make a .5-second pulse and make COAL on Black wire
	  end
    elseif tEvent[2] == checkTimerWood then -- whenever this timer is fired, the wood count will be checked again
	  updateWood()
	  if woodCount <= 512 then
	    pulse(cablePort, colors.brown, 0.5,"wood",6400) -- make a .5-second pulse and make WOOD on Brown wire
	  end
    elseif #tTimers > 0 then --if it's not any of the sensor timers, it will check the tTimers table for pulse timers
	  for i=1,#tTimers do
	    if tEvent[2] == tTimers[i] then
		  local curColors = rs.getBundledOutput(tRs[i]["side"]) -- get current output colors
		  if colors.test(curColors,tRs[i]["color"]) then --checks if pulse color is on or not
		    --already on
		    rs.setBundledOutput(tRs[i]["side"],colors.subtract(curColors,tRs[i]["color"])) -- removes pulse color from current output
		    tRs[i]["amount"] = tRs[i]["amount"]-1 --subtracts amount of pulses by one
		  else -- not on
		    rs.setBundledOutput(tRs[i]["side"],colors.combine(curColors,tRs[i]["color"])) --adds pulse color to current output
		  end
		  if tRs[i]["amount"] <= 0 then --checks amount, if it's 0 or less the table indices are removed
		    table.remove(tTimers,i) --clears the fired timer from the table
		    table.remove(tRs,i) --clears the redstone info from the table
		  else --otherwise, the timer is started up again
		    tTimers[i] = os.startTimer(tRs[i]["time"])
		  end
	    end
	  end
    end
  end
end
The idea here being that we check for timer events by checking the first index of the tEvents table, which contains the event type, then we check which timer it fired by checking the second index and react accordingly.
Chloe #36
Posted 09 January 2014 - 12:54 AM
I am an electrician, and build controls and panels for machinery. We use PLC's and program our ladder logic all the time.

If you could invent a PLC program to wrap a bundled cable to a side and then be able to hook inputs and outputs to it, and set a pulse, or set/detect a Normally Closed (true/on) or Normally Opened Status (false/off) for Redstone, You would have the program that would change everything!

For Example:

The left side could be the INPUTS and the right side the OUTPUTS. Each side could use a bundled cable and give the user 16 colors on each.

So, if Yellow is (true) on the input side, you could tell it to "pulse" the blue cable in the bundle on the output side… etc…

Would also need some variables like timing and count and duration so you could do some trick stuff!
Edited on 08 January 2014 - 11:55 PM
CometWolf #37
Posted 09 January 2014 - 02:43 AM
So what you're looking for is basically the old mitsubishi medoc? Gx and iec dev would be far too complex, but i guess medoc would be doable.
I don't have any experience with PLCs other than mitsubishi :P/>

There is however a PLC included in the MFR mod i think.
Edited on 09 January 2014 - 03:23 AM