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

Mfr Bundled Cable Test Program

Started by infinitehavoc, 27 October 2013 - 06:19 AM
infinitehavoc #1
Posted 27 October 2013 - 07:19 AM
Hi

my program that is simply checking bundled cable and says something using the speaker from MiscPeripherals keeps throwing out errors relating to java, waited to long before yield and just hanging. It also frequently crashes the computer at startup. I have re-written it three times now to see if it is just a logic bug, but no difference, here is the code;


s = perihperal.wrap("back")
print"Started successfully
while true do
redalert = colors.test(redstone.getBundledInput("bottom"), colors.red)
intruder = colors.test(redstone.getBundledInput("bottom"), colors.blue)

if redalert == true then
  print"red alert"
  s.speak("Red alert")
  sleep(2)
end

if intruder == true then
  print("intruder alert")
  s.speak("intruder alert")
  sleep(2)
end
end

thanks for any help in advance
Bomb Bloke #2
Posted 27 October 2013 - 07:32 AM
I scribbled out something earlier today which more or less explains the error. There's also a note in this thread.

There happens to be an event that fires when redstone input changes, so waiting for that to occur is your fix here (as that involves yielding). Add a line stating os.pullEvent("redstone") just above that final "end", and make your "alerts" loop until they detect another such change. Eg:

s = peripheral.wrap("back")
print("Started successfully")
while true do
  while colors.test(redstone.getBundledInput("bottom"), colors.red) do
    print"red alert"
    s.speak("Red alert")
    sleep(2)
  end

  while colors.test(redstone.getBundledInput("bottom"), colors.blue) do
    print("intruder alert")
    s.speak("intruder alert")
    sleep(2)
  end

  os.pullEvent("redstone")
end

Note also that you did not need to compare "redalert" or "intruder" to "true", as they already evaluated to either that or false. Eg, "if redalert then" would've sufficed.
theoriginalbit #3
Posted 27 October 2013 - 07:33 AM
ok so firstly, I'm assuming you typed this out as opposed to using pastebin or copying the contents of the file from disk, as this wouldn't even compile, you're missing a closing " on line 2.

However assuming that you're not missing this… So the error "too long without yielding" occurs for the reason that if neither of your conditions are true, your computer runs without taking a break to let others to run. With the current implementation of ComputerCraft only one computer is running at a given time meaning that a computer must give up (a.k.a. yield) its processor time to allow others to run, failure to do so will result in the programs termination.

The solution that I suggest however instead of using sleeps is to tell the computer to wait for a change in redstone (MFR included) like so

local s = peripheral.wrap("back") --# localise all your variables
print("Started successfully")
while true do
  local input = rs.getBundledInput("bottom") --# rs is the same as redstone, just shorthand
  local redalert = colors.test(input, colors.red)
  local intruder = colors.test(input, colors.blue)

  if redalert then --# we don't need == true, redalert is already a boolean, why should we do true == true or false == true, we already know the answer
	print("Red alert")
	s.speak("Red alert")
  end

  if intruder then --# same goes here
	print("intruder alert")
	s.speak("intruder alert")
  end

  os.pullEvent("redstone") --# wait here until something with the redstone changes
end

Now if there are any other errors that are not "too long without yielding" just tell us the precise error message as they help us tell you exactly why they are happening.

EDIT: Aaaannnd ninja'd by a post that didn't show up when I refreshed, only when I posted….. :/
Edited on 27 October 2013 - 06:34 AM
infinitehavoc #4
Posted 27 October 2013 - 07:54 AM
thanks alot for the help, crashes are gone, buuuut, the sound is supposed to loop. i could probably fix this with a normal redstone circuit that pulses every few seconds if this is impossible without causing issues with the rest of the server.
theoriginalbit #5
Posted 27 October 2013 - 08:00 AM
ok if you wish them to loop, you can use the parallel api in order to have both the individual loops to run independent of each other, then each loop of a redstone signal check the input, if the input is on, repeat until the signal is off, making sure to say the words and sleep for enough time until the words are over.

Something like this would work

local input

local function intruder()
  while true do
	input = rs.getBundledInput("bottom")
	while colors.test(input, colors.red) do
	  --# have the say code here, also make sure to sleep for the length of the voice so as to not get overlaps, then refresh the input variable just incase redstone has changed while sleeping
	end
	os.pullEvent("redstone")
  end
end

local function alert()
  while true do
	input = rs.getBundledInput("bottom")
	while colors.test(input, colors.blue) do
	  --# have the say code here, also make sure to sleep for the length of the voice so as to not get overlaps, then refresh the input variable just incase redstone has changed while sleeping
	end
	os.pullEvent("redstone")
  end
end

parallel.waitForAny(intruder, alert) --# run both the functions together(ish)
Edited on 27 October 2013 - 07:53 AM
infinitehavoc #6
Posted 27 October 2013 - 08:47 AM
so this is the code i am running;

s = peripheral.wrap("back")
print("started")
local input
local function intruder()
while true do
  input = rs.getInput("bottom")
  while colors.test(input, colors.red) do
   s.speak("red alert")
   sleep(2)
   input = rs.getInput("bottom")
  end
  os.pullEvent("redstone")
end
end
local function alert()
while true do
  input = rs.getInput("bottom")
  while colors.test(input, colors.blue) do
   s.speak("intruder alert")
   sleep(2)
   input = rs.getInput("bottom")
  end
  os.pullEvent("redstone")
end
end
parallel.waitForAny(intruder, alert) --# run both the functions together(ish)

but when run i get parallel:22:colors:36: number expected. i looked at line 22 to see what the problem was, and it is the speak line, which runs fine in any other program i run with it.
theoriginalbit #7
Posted 27 October 2013 - 08:53 AM
whoops, I just noticed a mistake I did make in the code, rename getInput to getBundledInput… which I'd assume is what's causing the error.