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

Multiple Modem Signals

Started by Czarified, 21 September 2013 - 09:24 AM
Czarified #1
Posted 21 September 2013 - 11:24 AM
Hello everyone! I want to send modem signals from multiple computers and receive them at a single computer, and perform an action based on the message and which computer sent it.

For example:
I have 1 Master computer and 2 slaves. All have wireless modems wrapped properly. Let's say Slave1 is monitoring a redstone line next to him, and Slave2 is monitoring a boiler via OpenPeripherals. Slave1 will send a "TRUE" or "FALSE" in the message based on the signal. Slave2 will send a "Temperature Low!" message when it drops below a certain value. I want the master to constantly know Slave1's redstone status, and whether or not Slave2's temperature is low.

I tried to explain that as best I could. Perhaps the example was a little too complicated, but I want to do the same thing with 5 different slaves, some will constantly send a signal, others will only send a message if a certain event happens, but I want the Master to always know what these variables are.

Could someone point me in the right direction here? I've tried it a couple different ways and now I've just confused myself…
Czarified #2
Posted 21 September 2013 - 12:58 PM
UPDATE: From testing I've noticed that when simultaneously sending multiple signals, the signal with the lowest distance value is the one received. Is this true or am I doing something wrong? Is there a way to queue the signals or receive them simultaneously? :/
GravityScore #3
Posted 21 September 2013 - 01:08 PM
UPDATE: From testing I've noticed that when simultaneously sending multiple signals, the signal with the lowest distance value is the one received. Is this true or am I doing something wrong? Is there a way to queue the signals or receive them simultaneously? :/

Is that simultaneously from multiple computers, or from the same computer in quick succession?

Anyway, basically what you should do here is have the slave computers send a message to the master computer when their state changes (like the redstone is toggled or the temperature is low), and have the master computer constantly listening for these state changes.

Eg:

Slave 1:

modem = ... -- wrap your modem, etc

local previousState = false
while true do
  os.pullEvent('redstone')
  if rs.getInput("left") ~= previousState then -- if the redstone signal has actually changed
    previousState = rs.getInput("left") -- update the previous state
    modem.transmit(MASTER_COMPUTER_CHANNEL, 12, "input " .. tostring(previousState)) -- will a message to the master computer
  end
end

Slave 2:

modem = ... -- wrap your modem, etc

while true do
  -- dunno what you do here to detect the temperature
  if temperatureChanged then
    modem.transmit(MASTER_COMPUTER_CHANNEL, 12, "temperature " .. tostring(isTemperatureLow)) -- send a message
  end
end

Master:

modem = ... -- wrap your modem, etc

while true do
  local event, side, from, sendBackOn, msg = os.pullEvent("modem_message")
  if msg:sub(1, 5) == "input" then -- if the message starts with the word input, we know the redstone input has changed
    newState = msg:sub(7) -- will be either "true" or "false"
    -- Do whatever you want
  elseif msg:sub(1, 11) == "temperature" then -- if the message starts with "temperature", we know the temperature has changed
    newState = msg:sub(13) -- will be either "true" if the temperature is low or "false" otherwise
    -- Do whatever you want
  end
end
theoriginalbit #4
Posted 21 September 2013 - 01:08 PM
Please post some code so we are able to see how you're currently going about it and make suggestions.

If you're using the event system then each message will be sitting in a queue waiting for your program to do something with it, however sometimes you can miss of forget about these by not handling them correctly.

EDIT: Ninja'd, my first point still stands though for all your future posts, please post your code (no matter how bad you may think it is) so that we can better help
Czarified #5
Posted 21 September 2013 - 01:30 PM
here's what I have so far. The program uses OpenPeripherals to detect and display information on the terminal glasses HUD, but only if states are critical. This is the master program, I haven't written anything else yet.

http://pastebin.com/9aiSFMPd

Spoiler

--Program for base control and HUD display.
--Master program
--Functions
function clearBoiler()
boilerInfo.setOpacity(0)
boilerTitle.setText(" ")
boilerTemp.setText(" ")
end
function clearTurbine()
turbineInfo.setOpacity(0)
turbineTitle.setText(" ")
turbineMaintenence.setText(" ")
end
function clearEngergyCell1()
energyCell1Info.setOpacity(0)
energyCell1Title.setText(" ")
energyCell1Text.setText(" ")
end
function clearEngergyCell2()
energyCell2Info.setOpacity(0)
energyCell2Title.setText(" ")
energyCell2Text.setText(" ")
end
--Peripherals
glass = peripheral.wrap("left")
modem = peripheral.wrap("top")
--Variable definitions
--  y   : Starting yPos for user names.
--  usertitle : Title text in user box. Configurable.
name1 = "Liquid Fueled Boiler  "
name2 = "Steam Turbine   "
name3 = "Energy Cell  "
--HUD Object Initialization (None display)
glass.clear()
boilerInfo = glass.addBox( 12, 195, glass.getStringWidth( name1 )+7, 34, 0xfb0000, 0)
boilerTitle = glass.addText( 15, 200, " ", 0 )
boilerTemp = glass.addText( 20, 210, " ", 0 )
turbineInfo = glass.addBox( 12, 95, glass.getStringWidth( name2 )+7, 34, 0xfb0000, 0)
turbineTitle = glass.addText( 15, 100, " ", 0 )
turbineMaintenance = glass.addText( 15, 110, " ", 0 )
energyCell1Info = glass.addBox( 23, 15, glass.getStringWidth( name3 )+7, 24, 0x17c92c, 0)
energyCell1Title = glass.addText( 25, 20, " ", 0 )
energyCell1Text = glass.addText( 25, 30, " ", 0 )
energyCell2Info = glass.addBox( 23, 25, glass.getStringWidth( name3 )+7, 24, 0x17c92c, 0)
energyCell2Title = glass.addText( 25, 30, " ", 0 )
energyCell2Text = glass.addText( 25, 40, " ", 0 )
--Wireless Channel Documentation
boilerChannel = 10
turbineChannel = 20
mfsu1Channel = 30
mfsu2Channel = 31
energyCell1Channel = 40
energyCell2Channel = 41
--Program
modem.open(boilerChannel)
modem.open(turbineChannel)
modem.open(mfsu1Channel)
modem.open(mfsu2Channel)
modem.open(energyCell1Channel)
modem.open(energyCell2Channel)
while true do
local usertitle = glass.addText( 15, 42, "Connected Users:", 0xffffff )
users = glass.getUsers()
local y = 50
for k, v in pairs(users) do	   --Updating User list
glass.addText(25, y, tostring(v), 0xffffff )
y = y + 10
end

event, modemSide, sendCh, rplyCh, message, dist = os.pullEvent("modem_message")
modem.open(boilerChannel)
if sendCh == boilerChannel && message == "Low" then
boilerInfo.setOpacity(.15)
boilerTitle.setText( name1 )
boilerTemp.setText("Low Fuel!")
elseif sendCH == boilerChannel && message == "High" then
boilerInfo.setOpacity(0)
boilerTitle.setText(" ")
boilerTemp.setText(" ")
end
if sendCh == turbineChannel && message == "TurbineBad" then
turbineInfo.setOpacity(.15)
turbineTitle.setText( name2 )
turbineMaintenance.setText("Needs Maintenance!")
elseif sendCh == turbineChannel && message == "TurbineGood" then
turbineInfo.setOpacity(0)
turbineTitle.setText(" ")
turbineMaintenance.setText(" ")
end
if sendCh == energyCell1Channel && message == "Low" then
energyCell1Info.setOpacity(.15)
energyCell1Title.setText( name2 )
energyCell1Text.setText("Energy Low!")
elseif sendCh == energyCell1Channel && message == "Good" then
energyCell1Info.setOpacity(0)
energyCell1Title.setText(" ")
energyCell1Text.setText(" ")
end
if sendCh == energyCell2Channel && message == "Low" then
energyCell2Info.setOpacity(.15)
energyCell2Title.setText( name2 )
energyCell2Text.setText("Energy Low!")
elseif sendCh == energyCell1Channel && message == "Good" then
energyCell2Info.setOpacity(0)
energyCell2Title.setText(" ")
energyCell2Text.setText(" ")
end

end

I'm looking at your examples now. I'll modify this code and repost to make sure I understand what you were saying. Thanks originalbit!!


EDIT: Format is a little better on the pastebin link, idk why but it lost all formatting when i put in code tags. I think it's easier to read on teh pastebins. :)/>
Edited on 21 September 2013 - 11:33 AM
Czarified #6
Posted 21 September 2013 - 04:32 PM
I tried a different approach this time. I open each channel, and tell the slave that the master is listening, then wait for a response, then close. Updated code below, haven't tested this yet.

Master: http://pastebin.com/wyPP35E7
Spoiler

--Program for base control and HUD display.
--Master program

--Functions
function clearBoiler()
boilerInfo.setOpacity(0)
boilerTitle.setText(" ")
boilerTemp.setText(" ")
end

function clearTurbine()
turbineInfo.setOpacity(0)
turbineTitle.setText(" ")
turbineMaintenence.setText(" ")
end

function clearEngergyCell1()
energyCell1Info.setOpacity(0)
energyCell1Title.setText(" ")
energyCell1Text.setText(" ")
end

function clearEngergyCell2()
energyCell2Info.setOpacity(0)
energyCell2Title.setText(" ")
energyCell2Text.setText(" ")
end

--Peripherals
glass = peripheral.wrap("left")
modem = peripheral.wrap("top")

--Variable definitions
-- y : Starting yPos for user names.
-- usertitle : Title text in user box. Configurable.
name1 = "Liquid Fueled Boiler  "
name2 = "Steam Turbine   "
name3 = "Energy Cell  "

--HUD Object Initialization (None display)
glass.clear()

boilerInfo = glass.addBox( 12, 195, glass.getStringWidth( name1 )+7, 34, 0xfb0000, 0)
boilerTitle = glass.addText( 15, 200, " ", 0 )
boilerTemp = glass.addText( 20, 210, " ", 0 )

turbineInfo = glass.addBox( 12, 95, glass.getStringWidth( name2 )+7, 34, 0xfb0000, 0)
turbineTitle = glass.addText( 15, 100, " ", 0 )
turbineMaintenance = glass.addText( 15, 110, " ", 0 )

energyCell1Info = glass.addBox( 23, 15, glass.getStringWidth( name3 )+7, 24, 0x17c92c, 0)
energyCell1Title = glass.addText( 25, 20, " ", 0 )
energyCell1Text = glass.addText( 25, 30, " ", 0 )

energyCell2Info = glass.addBox( 23, 25, glass.getStringWidth( name3 )+7, 24, 0x17c92c, 0)
energyCell2Title = glass.addText( 25, 30, " ", 0 )
energyCell2Text = glass.addText( 25, 40, " ", 0 )

--Wireless Channel Documentation
boilerChannel = 10
turbineChannel = 20
mfsu1Channel = 30
mfsu2Channel = 31
energyCell1Channel = 40
energyCell2Channel = 41

--Program

while true do

local usertitle = glass.addText( 15, 42, "Connected Users:", 0xffffff )
users = glass.getUsers()
local y = 50

for k, v in pairs(users) do --Updating User list
glass.addText(25, y, tostring(v), 0xffffff )
y = y + 10
end


modem.open(boilerChannel)
modem.transmit( boilerChannel, boilerChannel, "Go" ) --Tells slave it's listening
event, modemSide, sendCh, rplyCh, message, dist = os.pullEvent("modem_message") --Waits for slave to respond.
if message == "High" then
boilerInfo.setOpacity(0)
boilerTitle.setText(" ")
boilerTemp.setText(" ")
else
boilerInfo.setOpacity(.15)
boilerTitle.setText( name1 )
boilerTemp.setText( message )
end
modem.close(boilerChannel)

modem.open(turbineChannel)
modem.transmit( turbineChannel, turbineChannel, "Go" ) --Tells slave it's listening
event, modemSide, sendCh, rplyCh, message, dist = os.pullEvent("modem_message") --Waits for slave to respond.
if message == "TurbineBad" then
turbineInfo.setOpacity(.15)
turbineTitle.setText( name2 )
turbineMaintenance.setText("Needs Maintenance!")
elseif message == "TurbineGood" then
turbineInfo.setOpacity(0)
turbineTitle.setText(" ")
turbineMaintenance.setText(" ")
end
modem.close(turbineChannel)

modem.open(energyCell1Channel)
modem.transmit( energyCell1Channel, energyCell1Channel, "Go" ) --Tells slave it's listening
event, modemSide, sendCh, rplyCh, message, dist = os.pullEvent("modem_message") --Waits for slave to respond.
if message == "Low" then
energyCell1Info.setOpacity(.15)
energyCell1Title.setText( name2 )
energyCell1Text.setText("Energy Low!")
elseif message == "Good" then
energyCell1Info.setOpacity(0)
energyCell1Title.setText(" ")
energyCell1Text.setText(" ")
end
modem.close(energyCell1Channel)

modem.open(energyCell2Channel)
modem.transmit( energyCell2Channel, energyCell2Channel, "Go" ) --Tells slave it's listening
event, modemSide, sendCh, rplyCh, message, dist = os.pullEvent("modem_message") --Waits for slave to respond.
if message == "Low" then
energyCell2Info.setOpacity(.15)
energyCell2Title.setText( name2 )
energyCell2Text.setText("Energy Low!")
elseif message == "Good" then
energyCell2Info.setOpacity(0)
energyCell2Title.setText(" ")
energyCell2Text.setText(" ")
end
modem.close(energyCell2Channel)



sleep(.1)
end

Slave: http://pastebin.com/aRUfv6kB
Spoiler


--Boiler Slave

--Peripheral wrapping
boiler = peripheral.wrap("left")
modem = peripheral.wrap("top")

--Variable Definition
boilerChannel = 10

--Program
modem.open( boilerChannel )

while true do
event, modemSide, sendCh, rplyCh, message, dist = os.pullEvent("modem_message")
if boiler.getTemperature() < "1000" then
modem.transmit( boilerChannel, boilerChannel, boiler.getTemperature() )
else
modem.transmit( boilerChannel, boilerChannel, "High" )
end
end
Czarified #7
Posted 22 September 2013 - 02:08 PM
UPDATE: Finally got a chance to test this out on a server and it doesn't seem to be updating properly. My boiler's temperature is 20, but the box still does not display.