Jump to content




Script waits longer than defined in os.sleep


  • You cannot reply to this topic
10 replies to this topic

#1 BlackStar

  • Members
  • 6 posts

Posted 30 August 2014 - 04:47 PM

Hello,
I am currently starting out using ComputerCraft.
At the moment I am trying to set up a computer that monitors my energy storage (Thermal Expansion Energycells) using open peripherals in FTB Monster.

Most of the code I have currently is copied from different tutorials and adjusted to the needs of my System as I don't have good knowledge of lua.
code: http://pastebin.com/7sXChvBD (Will be kept up to date)

The code is supposed to constantly check my energy and if neccessary activate a Netherstar Generator.

The problem I have is, that although I have specified my sleep timers as 2 times 0.25 seconds if the generator is running, to keep my display up to date and 0.5 seconds when it is not running, It takes far longer to execute. (The times were initially doubled, I cut them in half for testing purposes)
As it is now, While the generator is running, It takes 3 seconds to proceed the countdown by 1 second. So it updates my screen every 1.5 seconds. While the generator is not running, it updates roughly every 2 seconds.
I wouldn't care about the long update times, but the countdown should be accurate, as It can only start the generator again once it is finished.

The sleep timer are in lines: 144, 176, 194

The game is running at 20 TPS, so this is not causing the long delays.

I hope someone can help me with the problem, thanks in advance

#2 MKlegoman357

  • Members
  • 1,170 posts
  • LocationKaunas, Lithuania

Posted 30 August 2014 - 07:16 PM

I think there was a lag issue when a lot of peripherals are connected with long-distance wires (wired modems). In your case you are getting information from 12 cells, try something like this to test how much it takes to get information from the energy cells:

...

local start = os.clock()

for j=#storageUnits,1,-1 do
  storageUnit = storageUnits[j]
  capacity = capacity + net.callRemote(storageUnit["id"], "getMaxEnergyStored", "unknown")
  amount = amount + net.callRemote(storageUnit["id"], "getEnergyStored", "unknown")    
end

print("Getting info took: ", os.clock() - start, " seconds")

...


#3 BlackStar

  • Members
  • 6 posts

Posted 30 August 2014 - 08:19 PM

I added that code at the end of my program and it output 1.2 seconds, does that mean it just takes to long to get all the information? I don't think distance should be an issue, since I only used 19 cables to connect all cells and my monitor.

Do I have to use less cells or would wireless modems improve the situation?

#4 flaghacker

  • Members
  • 655 posts

Posted 30 August 2014 - 08:33 PM

Wireless modems don't work for peripherals.

I think the problem is that the methods from openperipherals yield internally.
I don't think there's anything you can do about this, except maybe coroutines.

#5 BlackStar

  • Members
  • 6 posts

Posted 30 August 2014 - 09:01 PM

Could you maybe explain what you mean by coroutines? As I said, I'm still a beginner and don't know all of this stuff (yet :D )

Something I thought about that might help would be to use if statements, since I know how the energy flows inside my "battery" So for example if the second cell Is full, all following cells are bound to be full as well. I think I will try this tomorrow.

Edit: Or would it be possible to write the Countdown as a seperate program that is executed when neccessary while the rest just continous along?

Edited by BlackStar, 30 August 2014 - 09:08 PM.


#6 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 31 August 2014 - 12:53 AM

I'd just integrate MKlegoman357's code into your script proper.

That is to say, take this structure:

		minute = 2
		second = 0
		while minute > 0 or second > 0 do
			mon.setCursorPos(3,11)
			mon.clearLine()
			if second >= 10 then
				mon.write("ONLINE:  " ..minute.." : "..second.." Remaining")
			else
				mon.write("ONLINE:  " ..minute.." : 0"..second.." Remaining")
			end
		
			.
			.
			.
				
			if(minute==2) then
				rs.setBundledOutput(rednetside, colors.red) 
			end
			if(second==0) then
				minute = minute-1
				second = 59
			else
				second = second-1
			end
		end

... and turn it into this structure:

		local remainingTime = 120
		while remainingTime > 0 do
			local startTime = os.clock()
			
			mon.setCursorPos(3,11)
			mon.clearLine()
			
			local minute, second = tostring(math.floor(remainingTime/60)), tostring(math.floor(remainingTime%60))
			mon.write("ONLINE:  " ..minute.." : "..(#second==1 and "0" or "")..second.." remaining")
		
			.
			.
			.
			
			if(remainingTime==120) then rs.setBundledOutput(rednetside, colors.red) end
			remainingTime = remainingTime - os.clock() + startTime
		end


#7 natedogith1

  • Members
  • 110 posts

Posted 31 August 2014 - 02:35 AM

Might I suggest changing
for i=#storageUnits,1,-1 do
	storageUnit = storageUnits[i]
	capacity = capacity + net.callRemote(storageUnit["id"], "getMaxEnergyStored", "unknown")
	amount = amount + net.callRemote(storageUnit["id"], "getEnergyStored", "unknown")	
end
to
local funcs={}
for i=#storageUnits,1,-1 do
	funcs[i]=function()
		storageUnit = storageUnits[i]
		capacity = capacity + net.callRemote(storageUnit["id"], "getMaxEnergyStored", "unknown")
		amount = amount + net.callRemote(storageUnit["id"], "getEnergyStored", "unknown")
	end
end
parallel.waitForAll(unpack(funcs))
The change should make all the calls run in parallel, helping to mitigate the fact that OpenPeripheral sometimes won't return from their functions until a tick occurs.

#8 BlackStar

  • Members
  • 6 posts

Posted 02 September 2014 - 09:04 PM

Hi,
thanks for all your help.
I finally got around to rearrange my setup and in the process I applied both your fixes, Bomb Bloke and natedogith1.
When I did this another problem occured, Percentage of storage was displayed as "nil%" and Current Energy was 0. I then reverted the change by natedogith1 and now My display works again. I don't know why that happened, but since everything is working now I guess it doesn't matter.
Again thanks for your help :)

#9 natedogith1

  • Members
  • 110 posts

Posted 03 September 2014 - 01:07 AM

Might I ask to see how you implemented my fix (I've used it myself recently and want to make sure I'm not going to break my own stuff as well)

#10 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 03 September 2014 - 01:22 AM

Presumably the OpenPeripheral functions work by throwing and catching events. If they don't stick some sort of unique identifier on those events (similar to timer IDs), then running them in parallel will cause a messy collapse.

That said, even if that is the case and the solution's unworkable, I still consider it an excellent idea.

#11 BlackStar

  • Members
  • 6 posts

Posted 03 September 2014 - 08:43 AM

View Postnatedogith1, on 03 September 2014 - 01:07 AM, said:

Might I ask to see how you implemented my fix (I've used it myself recently and want to make sure I'm not going to break my own stuff as well)
There you go: http://pastebin.com/1t4hnyMg





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users