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

os.startTimer(1)? or os.setAlarm(1) pinging program

Started by Goof, 15 December 2013 - 09:20 AM
Goof #1
Posted 15 December 2013 - 10:20 AM
Hello..

Im still new to the whole "modem API" and therefore i wanted to make some test with modem.transmit, modem.open etc..

I want to make a pinging program ( 1 client ( can be as many as i want ) and 1 server ( which handles everything ) )

but i'm having trouble calculating how long the response time was from when the ping was sent, to a pong was received..

CLIENT
Spoiler

-- ID
local modem = peripheral.wrap("right")
local data={
	["channel"]={
		_server=24510,
		_client=24511
	},
	["message"]={
		_check={"PING";"PONG"};
	},
}
local colorW=function(...)
	local curColor
	for i=1, #arg do -- arg is ...
		if type(arg[i]) == 'number' then
			curColor = arg[i]
		else
			if curColor then
				term.setTextColor(curColor)
			end
			term.write(arg[i])
		end
	end
	print()
end;
modem.open(data["channel"]._server) modem.open(data["channel"]._client)
colorW(colors.blue,"PINGING "..data["channel"]._server)
local timeToRespond = os.startTimer(0)
modem.transmit(data["channel"]._client, data["channel"]._server, data["message"]._check[1])
while true do
	local event, p1,p2,p3,p4,p5 = os.pullEvent()
	--local event, modemSide, senderChannel, replyChannel, message, senderDistance
	if event == "timer" then
		local str=tostring(p1)
		if p2 then
			str=str.." - "..tostring(p2)
			if p3 then
				str=str.." - "..tostring(p3)
				if p4 then
					str=str.." - "..tostring(p4)
					if p5 then
						str=str.." - "..tostring(p5)
					end
				end
			end
		end
		print("TIMER\n"..str)
	elseif event == "modem_message" then
		if senderChannel==data["channel"]._server then
			if message==data["message"]._check[1] then
				colorW(colors.blue,"Received PING from "..senderChannel)
				colorW(colors.blue,"Reply PONG to "..data["channel"]._client)
				modem.transmit(data["channel"]._client, data["channel"]._server, data["message"]._check[2])
			elseif message==data["message"]._check[2] then
				colorW(colors.blue,"Received PONG from "..senderChannel)
				colorW(colors.green,"Server respond in "..timeToRespond)
			else
				print("The message was: "..message)
			end
		end
	end
end
SERVER
Spoiler

-- ID
local modem = peripheral.wrap("right")
local data={
	["channel"]={
		_server=24510,
		_client=24511
	},
	["message"]={
		_check={"PING";"PONG"};
	},
}
local colorW=function(...)
	local curColor
	for i=1, #arg do -- arg is ...
		if type(arg[i]) == 'number' then
			curColor = arg[i]
		else
			if curColor then
				term.setTextColor(curColor)
			end
			term.write(arg[i])
		end
	end
	print()
end;
modem.open(data["channel"]._server) modem.open(data["channel"]._client)
while true do
	local event, modemSide, senderChannel, replyChannel, message, senderDistance = os.pullEvent("modem_message")
	if senderChannel==data["channel"]._client then
		if message==data["message"]._check[1] then
			colorW(colors.lime,"CLIENT ",colors.yellow,"> ",colors.blue,"Ping from "..senderChannel)
			modem.transmit(data["channel"]._server, data["channel"]._client, data["message"]._check[2])
		elseif message==data["message"]._check[2] then
			colorW(colors.lime,"CLIENT ",colors.yellow,"> ",colors.blue,"Reply from "..senderChannel.." PONG")
		else
			print("The message was: "..message)
		end
	end
end



If you have time, i would also like to hear more about how the os.startTimer works so i can improve my knowledge :)/>


Thanks in Advance
MKlegoman357 #2
Posted 15 December 2013 - 12:51 PM
You can find all of the ComputerCraft events and what they return here.

os.startTimer is a function that will fire a timer event when a certain amount of time has passed. With event it returns one parameter - unique ID for that timer. The same ID is returned when calling os.startTimer:


local timer1 = os.startTimer(2) --// Start a timer to wait for 2 seconds
print("Timer 1 has started with ID of " .. timer1)

local timer2 = os.startTimer(1) --// Start a timer to wait for 1 second
print("Timer 2 has started with ID of " .. timer2)

local timer1Stopped = false
local timer2Stopped = false

--// We'll use these to stop the loop when both timers will stop

print()

while not timer1Stopped and not timer2Stopped do --// Run until both timers will have stopped
  local event, timerID = os.pullEvent("timer")

  if timerID == timer1 then
    print("Timer 1 has stopped! ID: " .. timerID)
    timer1Stopped = true
  elseif timerID == timer2 then
    print("Timer 2 has stopped! ID: " .. timerID)
    timer2Stopped = true
  end
end

--/* Output:
-- Timer 1 has started with ID of 6
-- Timer 2 has started with ID of 7
-- 
-- Timer 2 has stopped! ID: 7
-- Timer 1 has stopped! ID: 6
--*/

os.setAlarm is a function that when called will set an alarm that will fire alarm event at a specified Minecraft in-game time. Like timers, with events it will return a unique ID which is returned when calling os.setAlarm:


local alarm = os.setAlarm(7) --// Will set an alarm at 7 am
print("Alarm set at 7 am.")

repeat
  local event, alarmID = os.pullEvent("alarm") --// Will wait for alarm event
until alarmID == alarm --// Checking if it is the alarm we want, it's the same thing like we did with timer ID

print("It's 7 am. Wake up!")

--/* Output:
-- Alarm set at 7 am.
-- It's 7 am. Wake up!
--*/

For your particular case you should use os.clock. os.clock returns a number in seconds about how long the computer is running (in-game ComputerCraft computer):


local ping = os.clock()

--// Do the rednet messages here

local pong = os.clock()

local timePassed = pong - ping

print("Time between ping and pong (in seconds) is " .. timePassed)
Edited on 15 December 2013 - 11:54 AM
Goof #3
Posted 15 December 2013 - 02:20 PM
Ahhhh! Thank you so much!
that explains a lot, why i couldn't do it with os.setTimer xD
:P/>


Thanks !
Edited on 15 December 2013 - 01:35 PM