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

[Snippet] How to detect peripherals

Started by 3istee, 11 March 2012 - 04:27 PM
3istee #1
Posted 11 March 2012 - 05:27 PM
Hey,
I am not sure if it is "enough" for a tutorial, but I would like to try ^^

I used the new peripheral API which came in 1.3 to detect if there is a modem and on which side it is.
Of course you could ask for any peripheral.

Spoiler

function hasPeripheral(name)
 local Sides = {"back","right","left","front","top","bottom"} -- a simple list of all sides
 int = 1 -- An integer for going trough the list index
 repeat
  if peripheral.isPresent(Sides[i]) then -- checks if there is an peripheral at the current side
   if peripheral.getType(Sides[i]) == name then -- when yes, then check if it is the right peripheral
    side = Sides[i]
   end
  end
  int = int + 1
 until int == #Sides or sides ~= nil -- stop going trough the list index if every index was checked or the searched peripheral was found.
 return side -- gives back the side on that the peripheral is placed. If the computer/turtle hasn't got the peripheral it will return nil.
end

As you can see, it is really simple.
So I think this tutorial/snippet is mostly usefull for beginners.
Espen #2
Posted 11 March 2012 - 05:44 PM
Hey 3istee,
in the name of efficiency and everyone's benefit I've tried to make the code a little bit more compact.
I hope you don't mind. Just trying to help. ;)/>/>

function hasPeripheral( sName )
  local tSides = redstone.getSides()

  for i = 1, #tSides do
	if peripheral.isPresent( tSides[i] ) and peripheral.getType( tSides[i] ) == sName then
	  return tSides[i]
	end
  end

end

Alternative (iterate through the table instead of accessing the index via a counter loop):

function hasPeripheral( sName )
 
  for _, sSide in pairs( redstone.getSides() ) do
    if peripheral.isPresent( sSide ) and peripheral.getType( sSide ) == sName then
	  return sSide
    end
  end
 
end


Disclaimer: Haven't tried the code in-game yet, but it should work. If you get any error, give me a holler. :mellow:/>/>
Edited on 11 March 2012 - 04:51 PM
3istee #3
Posted 11 March 2012 - 05:51 PM
Oh I have no problem with that :mellow:/>/>
I think it should work, too, I don't really want to copy the text, tough.

Do the letters before the variablenames (t,s,..) stand for the type of the variable?
And could you say me where locals are valid? ^^
Sebra #4
Posted 11 March 2012 - 06:02 PM
I think it can be peripheral.find( sName ) for peripheral API
Espen #5
Posted 11 March 2012 - 06:03 PM
Oh I have no problem with that ;)/>/>
I think it should work, too, I don't really want to copy the text, tough.

Do the letters before the variablenames (t,s,..) stand for the type of the variable?
And could you say me where locals are valid? ^^
Yes exactly, I adopted the habit to add the type infront of the variable names. That is very helpful for finding bugs the bigger a program gets.^^
I mostly use these:
  • s - String
  • t - Table
  • n - Number
Local variables are accessible within the block they were defined in.
This includes all functions that you define within the same block, even nested functions.

Let me try an analogy:
Let's say we have a blue box and you declare a local variable within this blue box.
Then all boxes within that blue box can also access this variable.
But if the blue box itself is part of one ore more bigger boxes around itself, then these can't access the blue box's local variable.
Local variables can only be accessed downards, not upwards.

I hope the analogy didn't confuse more that it tried to clarify. :mellow:/>/>



I think it can be peripheral.find( sName ) for peripheral API
There is no find() function in the peripheral API.
Edited on 11 March 2012 - 05:04 PM
Sebra #6
Posted 11 March 2012 - 06:15 PM
I mean it's worth to be added.
Liraal #7
Posted 11 March 2012 - 06:20 PM
i dont think it is, you can only have 6 peripherals (unless im wrong) so just look up all 6 sides for a match.
Espen #8
Posted 11 March 2012 - 06:20 PM
I mean it's worth to be added.
Ah, sorry my bad. Misunderstood you then. :mellow:/>/>
DrEckenbecker #9
Posted 04 May 2012 - 04:38 AM
I actually use this in my scripts to find rednet modems.

Sides = {"back","right","left","front","top","bottom"}
for i=1,#Sides do
if peripheral.isPresent(Sides[i]) then
  if peripheral.getType(Sides[i]) == "modem" then
   side = Sides[i]
  end
end
end
rednet.open(side)

its easier than having to remember where to put the stupid modem in refrence to the the program, and its only a few lines.
yoskaz01 #10
Posted 04 May 2012 - 04:50 AM
I actually added a fun to the latest sensors API which returns a dictionary with all connected peripherals

that is for when u want to use more than one peripheral in your program

why loop again each time?

just loop once and get all I'm one go.
Espiroth #11
Posted 29 May 2012 - 07:36 PM

function hasPeripheral(sName)
 local Sides = {"back","right","left","front","top","bottom"}
 int = 1
 repeat
  if peripheral.isPresent(Sides[i]) then
   if peripheral.getType(Sides[i]) == (sName) then 
    dside = Sides[i]
   end
  end
  int = int + 1
 until int == #Sides or sides ~= nil
 return side
end

When I try to asign the found peripheral to a varialbe for use in my programs it says that I tried to call NIL
Same goes for Espen's variation.

How do i assign the Sides to a string for use later?
Cloudy #12
Posted 29 May 2012 - 07:51 PM
Your problem is you're assigning the value of Sides to dside and trying to return side. This code will be better though:

function getPeripheral(perType)
  for k,v in pairs(rs.getSides()) do
    if peripheral.getType(v) == perType then 
      return v
    end
  end
  return nil
end

It will return the side that the peripheral is on.
MysticT #13
Posted 29 May 2012 - 07:54 PM
You have to store it in a variable like this:

local side = hasPeripheral("name of the peripheral")
And then use it like:

peripheral.call(side, "Method", ...)
-- or
local p = peripheral.wrap(side)
p.<Method>(...)
Espiroth #14
Posted 29 May 2012 - 09:04 PM
Your problem is you're assigning the value of Sides to dside and trying to return side. This code will be better though:

function getPeripheral(perType)
  for k,v in pairs(rs.getSides()) do
	if peripheral.getType(v) == perType then
	  return v
	end
  end
  return nil
end

It will return the side that the peripheral is on.


What do i do with a "returned side", is it a variable, how do i call it? The limit of my experience is pretty much:

sSide = "however you got a string input"
rednet.open(sSide)

Plus, albeit unrelated to the thread, what's all that fancy stuff with the k,v in pairs and return nil?


You have to store it in a variable like this:

local side = hasPeripheral("name of the peripheral")
And then use it like:

peripheral.call(side, "Method", ...)
-- or
local p = peripheral.wrap(side)
p.<Method>(...)


peripheral.call(side, "Method", ...)
Is that phrase necessary for me to make use of the variable side, because i'm not sure how to use that phrase, let alone what "Method" means.

Would, for example, this work?

redstone.setBundledOutput(side, color)

Furthermore, you make it seem simple to store the side variable but I don't see where in the function the Sides goes from a table to a string for me to store.

Thanks for the assist so far guys!
Cloudy #15
Posted 29 May 2012 - 09:13 PM
In my function you'd do this:

side = getPeripheral("peripheraltype")

Then you'd use the peripheral however using that.
E.g. If you want to use a monitor you could wrap it using mon = peripheral.wrap(side) then call functions like mon.write("test").

The "k, v" stuff is to iterate through the sides table and check the sides one by one.