Jump to content




posting same text to multiple wired monitors

peripheral lua networking

8 replies to this topic

#1 rokkwarr

  • Members
  • 6 posts

Posted 21 July 2015 - 05:58 AM

So I'm working on these store signs that should surround the building, (8 monitors, 1Wx3L in size) to be connected to one computer. I am HORRIBLE with LUA and with all the crap that happens around me when I'm trying to learn anything (cat bugging me, fiancee bugging me, phone ringing) I can't keep my concentration enough to figure out how to make this work. Code follows,

print('Store Sign Engaged')
text = "Welcome to Renegade Inc"
monitorWrap = {
"monitor_6", "monitor_7", "monitor_8", "monitor_9", "monitor_10", "monitor_11", "monitor_12", "monitor_13"
}
monitor = peripheral.wrap(monitorWrap)
monitor.setTextScale(2)
while true do
  monitor.setCursorPos(1,1)
  monitor.write(text)
  monitor.setCursorPos(1,2)
  monitor.write(textutils.formateTime(os.time(),false)
  sleep(1)
  monitor.clear()
  term.setCursorPos(1,1)
end
executing this code ends with,
Store Sign Engaged
startup:7: Expected string

I know this is probably trival as all hell but it's 1AM and I can't think straight at the moment.

#2 O.S

  • Members
  • 10 posts

Posted 21 July 2015 - 06:49 AM

You are going to want a loop to feed your monitors into peripheral.wrap()

Right now, you are passing it a table (monitorWrap) not the individual strings it is expecting. Something like:

for k, v in ipairs(monitorWrap) do
   local monitor = peripheral.wrap(v)
   -- Do stuff to current monitor
end

k is the key or index to the table. (Not really needed in your case)
v is the value at that index. (one of the strings in your table)
ipairs can really only be used with the default ordered numerical keys (like you are using here), otherwise you need pairs.

#3 flaghacker

  • Members
  • 655 posts

Posted 21 July 2015 - 06:50 AM

You can't wrap a table of peripherals, you have to
wrap them one by one. You'll then have to create your own functions like print who operate on all of the peripherals:

names = {"monitor_1", "..."}
monitors = {}

for i, name in ipairs (names) do
  monitors[i] = peripheral.wrap (name)
end

function multiWrite (text)
  for _, monitor in ipairs (monitors) do
    monitor.write (text)
  end
end

function multiSetTextColor (color)
  for _, monitor in ipairs (monitors) do
    monitor.setTextColor (color)
  end
end

--Test code
multiSetTextColor(colors.red)
multiWrite ("Hello world!")
The variable name '_' in the for loops is just a convention to say 'I don't need this variable'

You could also write something up to automatically create all those multifunctions and make a new monitor object from them, but I think that's a bit overkill for this project.

Edit: :ph34r:, read the post above me for an excellent explenation on for loops :P

Edited by flaghacker, 21 July 2015 - 06:54 AM.


#4 O.S

  • Members
  • 10 posts

Posted 21 July 2015 - 07:49 AM

 flaghacker, on 21 July 2015 - 06:50 AM, said:

names = {"monitor_1", "..."}
monitors = {}

for i, name in ipairs (names) do
  monitors[i] = peripheral.wrap (name)
end
...
Yes, if you are going to repeatedly access/change these monitors, I second flaghacker's approach of making a table of wrapped monitors (opposed to just a table of their string names) so you can easily pull them back up without needed to rerun the peripheral.wrap loop.

It also looks like you want to have updating time on the signs, so maybe something like this will strike the right balance for simplicity:
print('Store Sign Engaged')
text = "Welcome to Renegade Inc"
names = {"monitor_6", "monitor_7",
		 "monitor_8", "monitor_9",
		 "monitor_10", "monitor_11",
		 "monitor_12", "monitor_13"}
monitors = {}

for i, name in ipairs (names) do
  monitors[i] = peripheral.wrap (name)
  monitors[i].setTextScale(2)
  -- Anything else you want to set up the first time
end

while true do
   for _, mon in ipairs (monitors) do
	  mon.clear()
	  mon.setCursorPos(1,1)
	  mon.write(text)
	  mon.setCursorPos(1,2)
	  mon.write(textutils.formateTime(os.time(),false))
   end
   sleep(1)
end

Also, if you don't want to hardcode your monitor names (in case you add, remove, or move them around) you can use the peripheral API to automatically find them like so:
local names = peripheral.getNames()
local monitors = {}
for _, v in ipairs(names) do
   if(string.find(v, "monitor")) then
	  table.insert(monitors, peripheral.wrap(v))
   end
end
*This only works for networked monitors (since they have "monitor" in their name) and won't see monitors directly touching the computer.

 flaghacker, on 21 July 2015 - 06:50 AM, said:

Edit: :ph34r:, read the post above me for an excellent explenation on for loops :P
Appreciate that. :)

#5 MKlegoman357

  • Members
  • 1,170 posts
  • LocationKaunas, Lithuania

Posted 21 July 2015 - 08:44 AM

 O.S, on 21 July 2015 - 07:49 AM, said:

Also, if you don't want to hardcode your monitor names (in case you add, remove, or move them around) you can use the peripheral API to automatically find them like so:
local names = peripheral.getNames()
local monitors = {}
for _, v in ipairs(names) do
   if(string.find(v, "monitor")) then
	  table.insert(monitors, peripheral.wrap(v))
   end
end
*This only works for networked monitors (since they have "monitor" in their name) and won't see monitors directly touching the computer.

If you're using CC 1.6+ then you can simply use the 'peripheral.find()' function. Also, instead of looking for the 'monitor' word in the network name you can use 'peripheral.getType()' which will work for any side or network name.

#6 O.S

  • Members
  • 10 posts

Posted 21 July 2015 - 08:55 AM

Doesn't peripheral.find('type') only return the first of the given type?

You're right about using getType(), there is no reason not to use it there. I got stuck in the mindset of working with those strings. :P

#7 Bomb Bloke

    Hobbyist Coder

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

Posted 21 July 2015 - 08:59 AM

 O.S, on 21 July 2015 - 08:55 AM, said:

Doesn't peripheral.find('type') only return the first of the given type?

It returns as many as are available.

If you only want to catch the first, you can do:

local myPeripheral = peripheral.find("whatever")

To get the first couple:

local peri1, peri2 = peripheral.find("whatever")

Often it's handy to just dump them all into a table:

local peripherals = {peripheral.find("whatever")}


#8 O.S

  • Members
  • 10 posts

Posted 21 July 2015 - 09:11 AM

Ach, wrong on all accounts. Ah well, I'll just crawl back into my lurker hole. :)

Though now I know that function is much more useful than I previously thought.

#9 Bomb Bloke

    Hobbyist Coder

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

Posted 21 July 2015 - 02:28 PM

Hey, you don't ask, you don't learn. :P

I just realised I know exactly where you got that avatar from - in fact, it was a bit over six years ago when I made a class based off it!

My file time-stamps make me feel old sometimes...





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users