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

Combining Similar Peripherals

Started by rawritsdan, 09 August 2013 - 02:22 PM
rawritsdan #1
Posted 09 August 2013 - 04:22 PM
Hi guys, wondering if there is a way to combine multiple peripherals (All of the same type), and use one command to tinker with them all? Instead of setting them all individually. By this I mean over a wired modem, not at the side of the computer.
One peripheral I am using is the Glowstone Illuminator from Thermal Expansion, With openperipheral to control it via a computer. But I am sure if there was a way, it could be used for things such as printing on multiple printers or using a few different monitors.
thanks, Dan :)/>
HurricaneCoder #2
Posted 09 August 2013 - 05:00 PM
I don't think there is a way. However maybe if you can set them in a table. For example:

--using the monitor peripheral
t = {}
t[1] = peripheral.wrap("left")
t[2] = peripheral.wrap("right")
-- you can say this
for i = 1,#t do
t[i].setCursorPos(1,1)
end

you see I can now execute one command on both monitor just by setting a table.
rawritsdan #3
Posted 09 August 2013 - 06:27 PM
Thanks for the quick reply, I failed to say that I was trying to call these peripherals over a wired modem… Ooops!
I tried to adapt your code to this:

t = {}
t[1] = "glowstone_illuminator_0"
t[2] = "glowstone_illuminator_1" -- Both can be accessed by the peripheral.call
for i = 1,#t do
t[i].setColor(0x00FFFF)
end
I had no luck in executing the command, anything else you can recommend?
MysticT #4
Posted 09 August 2013 - 06:59 PM
You still have to use peripheral.wrap with wired modems:

local t = {}
t[1] = peripheral.wrap("glowstone_illuminator_0")
t[2] = peripheral.wrap("glowstone_illuminator_1")
for i = 1, #t do
  t[i].setColor(0x00FFFF)
end

You could also make a function to get all the peripherals automatically:

local function getPeripherals(sType)
  local t = {}
  for _,name in ipairs(peripheral.getNames()) do
	if peripheral.getType(name) == sType then
	  t[#t + 1] = peripheral.wrap(name)
	end
  end
  return t
end
Then you call it and use the same loop as before to call the methods.

local t = getPeripherals("monitor") -- get all the monitors
for i = 1, #t do
  t[i].write("Hello")
end
Bubba #5
Posted 09 August 2013 - 07:01 PM
Edit: Gah, I've been ninja'd.

Thanks for the quick reply, I failed to say that I was trying to call these peripherals over a wired modem… Ooops!
I tried to adapt your code to this:

t = {}
t[1] = "glowstone_illuminator_0"
t[2] = "glowstone_illuminator_1" -- Both can be accessed by the peripheral.call
for i = 1,#t do
t[i].setColor(0x00FFFF)
end
I had no luck in executing the command, anything else you can recommend?

You've just inserted the names of the peripherals into the table. What you want to insert instead is the actual wrapped object. Below is an example of what you want to do

local t = {} --# A table can contain any Lua type, including numbers, functions, strings, and other tables.
             --# This particular table will contain all of the wrapped objects returned by peripheral.wrap

t[1] = peripheral.wrap("glowstone_illuminator_0") --# By typing 't[1]', we specify that we are inserting the result
                                                  --# of peripheral.wrap into the first slot of the table
t[2] = peripheral.wrap("glowstone_illuminator_1") --# Now we insert the next result into the second slot

for i=1,#t do --# This loop will go from the first element of the table to the last element of the table. In this case, just 2 elements
  t[i].setColor(0x00FFFF)
end

If you have a lot of the glowstone illuminators, you'll probably want an easier way to wrap all of them without typing it out manually. In this case, we can take advantage of the pattern each wrapped illuminator follows (illuminator_0, illuminator_1, illuminator_2).

A for loop is perfect for this:

local t = {} --# Our wrapped objects table
for count=0, 5 do --# Assuming that we have 6 glowstone illuminators, because we start counting at 0 rather than 1
  t[count] = peripheral.wrap("glowstone_illuminator_"..count) --# The .. operator will concatenate (join) the "glowstone_illuminator_" string with the count
end

And then you could use another for loop like in the first example to do the setColor function on each illuminator.
rawritsdan #6
Posted 14 August 2013 - 01:36 PM
Ooohhhhh I see… I am going to try MysticT's function and loop. It has also been made 'Future proof' for when I want to add more lights.
WOW! Works just as I wanted it to, many thanks both for the explaination and a fix , I can hopefuilly learn from my mistakes. :D/>
Dan :)/>
theoriginalbit #7
Posted 14 August 2013 - 01:47 PM
Just for some diversity, this is a method I used earlier today, modified to your purpose. I used it to cycle through and calculate total storage in a redstone cell network. NOTE: I programmed this in-game on an extremely laggy server, a TPS of about 3, so I was feeling extremely lazy and took shortcuts so I didn't have to type as much)


for _,name in pairs( peripheral.call("left", "getNamesRemote") ) do --# where "left" is the side of the modem
  if name:find("glowstone_illuminator_") then --# make sure that it's name contains what we're after
    peripheral.call( name, "setColor", 0x00FFFF ) --# make the change
  end
end
rawritsdan #8
Posted 14 August 2013 - 03:12 PM
I used it to cycle through and calculate total storage in a redstone cell network.
Thanks for the input!
I have something sort of slightly like that, I use it to monitor the amount of energy stored over total capacity in my MFSU system… The data was then sent over rednet and to my hud using Openperipherals glasses. The only problem I have now is taking the color hex value from the string and using it as a number, the peripheral only accepts numbers. Perhaps you have tackled something similar?
theoriginalbit #9
Posted 15 August 2013 - 03:40 AM
The only problem I have now is taking the color hex value from the string and using it as a number.
Which color hex value in a string?

Also as a slight point of helpfulness, obvious the format for hex values in Lua is 0xRRGGBB where each set of 2 is a value between 00 and FF (0—255). Here is a good site to find hex colours, however if you wish I've created 2 things, the first is a function to convert from RGB to hex.

local function rgbToHex( _r, _g, _b )
  return bit.bor(bit.blshift(bit.bor(bit.blshift(_r, 8), _g), 8), _B)/>
end
The second is a colour library, that I've called glColors (original right?! xD), that contains a predefined list of a bunch of colours that actually appear in (the real) glColor. NOTE: It does use the above function as I haven't got around to manually converting them to hex, as glColors (that I found) had them in RGBA.
rawritsdan #10
Posted 15 August 2013 - 12:35 PM
Not sure if we are on about the same thing! :') The hex value is coming from another computer (Sent via rednet), I set the variables for id and message,
message of course contains the hex value. (In this case blue, 0x0000FF) But as it is from a rednet message, it becomes a string… how could I turn that back into a number.?
Setting the variable locally, eg foo = 0x0000FF works, but I believe that it treats this as a number? Does this meanI would have t send the colour code as rgb and then convert it? Ps Sorry for any confusion!
theoriginalbit #11
Posted 15 August 2013 - 01:43 PM
ohhh I get you… well this is your best bet:

Sender

rednet.send( tostring(0x0000FF) )
[code]

Receiver
[code]
local id, msg = rednet.receive()
local colour = tonumber(msg)

This works due to the fact that a hex is actually just a programatic nicety, given to us programmers because it is easier to represent larger numbers. What actually happens behind the scenes is (in this case) LuaJ interprets 0x0000FF into a number, which is 255. So basically we perform a to string on the hex value so that we can send it over rednet (the string is 255) and then on the other side get the string and convert it back to a number.


Now just as another point of diversity and learning, if you were to change this up a little and do the following:

Sender

rednet.send("0x0000FF") --# note it is a string now

You can still do the same as before as you have the "0x" at the front. This means that the tonumber function realises the string is hexadecimal and performs the conversion from base-16 (hex) to base-10 (decimal).

However if we were to make one change and do the following

rednet.send("0000FF")

You would need to make a change on the receiving end

local id, msg = rednet.receive()
local colour = tonumber(msg, 16)
[code]

This tells the tonumber function that the string we gave it is in the base-16 and it will need to convert it appropriately.
rawritsdan #12
Posted 16 August 2013 - 07:21 AM
ohhh I get you… well this is your best bet:

Sender

rednet.send( tostring(0x0000FF) )
[code]

Receiver
[code]
local id, msg = rednet.receive()
local colour = tonumber(msg)

This works due to the fact that a hex is actually just a programatic nicety, given to us programmers because it is easier to represent larger numbers. What actually happens behind the scenes is (in this case) LuaJ interprets 0x0000FF into a number, which is 255. So basically we perform a to string on the hex value so that we can send it over rednet (the string is 255) and then on the other side get the string and convert it back to a number.


Now just as another point of diversity and learning, if you were to change this up a little and do the following:

Sender

rednet.send("0x0000FF") --# note it is a string now

You can still do the same as before as you have the "0x" at the front. This means that the tonumber function realises the string is hexadecimal and performs the conversion from base-16 (hex) to base-10 (decimal).

However if we were to make one change and do the following

rednet.send("0000FF")

You would need to make a change on the receiving end

local id, msg = rednet.receive()
local colour = tonumber(msg, 16)
[code]

This tells the tonumber function that the string we gave it is in the base-16 and it will need to convert it appropriately.
That's why it wasn't working when I used tonumber… Forgot the 16 :') Yet another problem fixed by theoriginalbit, My code is now finally working!
Many many thanks again :D/>