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

Multiple Rednet signals

Started by ihatetn931, 31 December 2013 - 01:05 PM
ihatetn931 #1
Posted 31 December 2013 - 02:05 PM
Right now i have 2 turtles and one computer, the 2 turtles send rednet signals to the computer, i got it to recieve both signals but it seems to recieve one signal more then the other one.

What is the best way to send multiple rednet signals to one computer.

Example

1 turtle sends rednet signal to computer, computer displays info
Once it displays the data it reads the next turtle

Basically i want it to recieve both signals all the time keeping the display program up todate, I tried many things done some searching but haven't really came across much.

I recive one singal and moves on to the next and keeps repeating it.

I thought about addin an additonal wireless modem but the way i have things setup that would be a little hard since i have monitors on the top and sides, modem on the back and bundled cable on the bottom and putting it in the front would make it hard to access the computer
gollark8 #2
Posted 31 December 2013 - 03:19 PM
Right now i have 2 turtles and one computer, the 2 turtles send rednet signals to the computer, i got it to recieve both signals but it seems to recieve one signal more then the other one.

What is the best way to send multiple rednet signals to one computer.

Example

1 turtle sends rednet signal to computer, computer displays info
Once it displays the data it reads the next turtle

Basically i want it to recieve both signals all the time keeping the display program up todate, I tried many things done some searching but haven't really came across much.

I recive one singal and moves on to the next and keeps repeating it.

I thought about addin an additonal wireless modem but the way i have things setup that would be a little hard since i have monitors on the top and sides, modem on the back and bundled cable on the bottom and putting it in the front would make it hard to access the computer
What's your code?
Extra modems make no difference.
The parallel API may be useful to you.
ihatetn931 #3
Posted 31 December 2013 - 04:21 PM
Recieve computer
Spoiler


--Reciever computer that shows all info

os.loadAPI("ocs/apis/graph")
rednet.open("back")

montop = peripheral.wrap("top")
monleft = peripheral.wrap("left")
monright = peripheral.wrap("right")

gradient1 = {colors.green, colors.yellow, colors.orange, colors.red}
gradient2 = {colors.purple, colors.magenta, colors.red, colors.orange}

local incomingID,message = rednet.receive()
local reData = textutils.unserialize(message)

cableSide = "bottom"
dBug = 0
function setBundledColor(side, color, state)
if state then
if not colors.test(rs.getBundledOutput(side), color) then
rs.setBundledOutput(side, colors.combine(rs.getBundledOutput(side), color))
end
else
if colors.test(rs.getBundledOutput(side), color) then
rs.setBundledOutput(side, colors.subtract(rs.getBundledOutput(side), color))
end
end
end
-------------------Reactor
function checkReactorHeat()
incomingID,message = rednet.receive()
reData = textutils.unserialize(message)
rHeatLevel = reData.Heat
return rHeatLevel
end
--print("Reactor check done")
-------------------Breeder
function checkBreederHeat()
incomingID,message = rednet.receive()
reData = textutils.unserialize(message)
heatLevel = reData.Heat
return heatLevel
end
--print("Breeder check done")


-------------------
--local grtop, err = graph.new(montop, {checkReactorHeat}, {"Reactor1 Heat"}, {gradient1}, {0}, {gRinfo.MaxHeat}, true)
local grleft, err = graph.new (monleft, { checkReactorHeat } , { "Reactor1 Heat" } , {gradient1} , {0 }, { reData.MaxHeat }, true)
local grright, err = graph.new(monright, {checkBreederHeat}, {"Breeder1 Heat"}, {gradient1}, {0}, {reData.MaxHeat}, true)

function checkData()
if incomingID == 2 then
term.clear()
term.setCursorPos(1,1)
print("Two ",incomingID)
grleft:draw()
if incomingID == 3 then
term.setCursorPos(1,2)
print("Three ",incomingID)
grright:draw()
end
end
end

while true do
checkData()
-- grleft:draw()
-- grright:draw()
end


One of the turltes (both have same code)
Spoiler


---Reactor Wireless Sensor Turtle

--loading apu
os.loadAPI("ocs/apis/sensor")
--Wrapping sensor
local nReactor = sensor.wrap("left")
--For debugging
local debug = 1
--opening the rednet to send rednet signal
rednet.open("right")
--Loop sending the signal to keep everything updated
while true do
local reActor = nReactor.getTargetDetails("0,0,2")
rMsg = textutils.serialize(reActor)
rednet.send(1, rMsg)
if debug == 1 then
print("Reactor1 Heat = ",textutils.unserialize(reActor.Heat))
print("Reactor1 Max Heat = ",textutils.unserialize(reActor.MaxHeat))
print("Reactor1 Output = ",textutils.unserialize(reActor.Output))
print("ID: ",os.getComputerID())
print("Powered On = ", tostring(reActor.Active))
sleep(0)
term.clear()
term.setCursorPos(1,1)
end
end

I'm gonna have a look at the parallel api will prolly have to rewrite my entire code to make it work as you can tell by the code, it sucks, all done by trial and error.

I want each turtle to write on it's own monitor, one writes on the left and the other writes on the right (on the recieve computer)
Edited on 31 December 2013 - 04:43 PM
Bomb Bloke #4
Posted 31 December 2013 - 06:41 PM
You shouldn't need the parallel API here - in fact I can't actually see why you wouldn't get updates on both monitors, though the order of your rednet pulls is a bit odd…

I'd also say that having the turtles sending in new data constantly is excessive (I'd have them use a sleep(1) instead of a sleep(0) at the very least, and make that sleep statement execute regardless as to whether the turtles are in debug mode), but that's up to you.

Anyway, I'd recommend taking these lines from the top of your server script:

local incomingID,message = rednet.receive()
local reData = textutils.unserialize(message)

… and turn them into just local declarations for now:

local incomingID,message,reData

Now at the top of the checkData() function:

function checkData()
  incomingID,message = rednet.receive()
  reData = textutils.unserialize(message)
  if incomingID == 2 then
    .
    .
    .

And remove the rednet pulls from your checkReactorHeat/checkBreederHeat functions:

-------------------Reactor
function checkReactorHeat()
  return reData.Heat
end
--print("Reactor check done")

-------------------Breeder
function checkBreederHeat()
  return reData.Heat
end
--print("Breeder check done")

(I assume you're using those functions with the graph API correctly; I've not meddled with it myself).

Now you're checking to see which system the data came from before you work with it, as opposed to checking which system the last set of data came from before pulling in a new set from who-knows-what source.

Edit: It's probably worth mentioning that rednet messages come in as events. Most functions that pull items from the event queue grab whatever event's're next in line there and discards them until it finds what it wants, which will obviously cause other event-reliant functions to malfunction if you try to use them together. For example, sleep() relies on the event queue for a timer event, and rednet.receive() wants a rednet_message event - so a computer that uses sleep will "miss" any rednet messages sent to it until it sleeping, after which it'll act like those messages were never received.

As far as I can tell your server script doesn't have this problem, but I thought it worth mentioning. The parallel API is a good way around this issue if it DOES come up, as each function you run in parallel gets it own copy of the event queue - meaning one function can pull what it likes from its copy without affecting what the other can see.
Edited on 31 December 2013 - 05:55 PM
ihatetn931 #5
Posted 31 December 2013 - 08:03 PM
Thank you for your help, that works but i've ran in to one issue drawing the graph

I ended up having to add one more rednet.recieve so it recieves the MaxHeat of the reactors, since it only needed to get it once i didn't have to put it in a loop plus i couldn't figure out how to put it in a loop and the graph update cause when i put the grLeft and grRight above the draws in checkData the graphs wouldn't update, and if i took them out and put them above the function i would get a nil value so the graphs wouldn't draw. Unless i am missin somthing, it would be nice for the MaxHeat to update on it's own so when i put heat plates in it i don't have to restart the program for it to update the maxheat



incomingID,message = rednet.receive()
reData = textutils.unserialize(message)
local grLeft = graph.new (monleft, {checkReactorHeat } , { "Reactor1 Heat" } , {gradient1} , {0 }, {reData.MaxHeat}, true)
local grRight = graph.new(monright, {checkBreederHeat}, {"Breeder1 Heat"}, {gradient1}, {0}, {reData.MaxHeat}, true)
-------------------
function checkData()
incomingID,message = rednet.receive()
reData = textutils.unserialize(message)
if incomingID == 2 then
--local grLeft = graph.new (monleft, {checkReactorHeat } , { "Reactor1 Heat" } , {gradient1} , {0 }, { reData.MaxHeat }, true)
grLeft:draw()
else if incomingID == 3 then
--local grRight = graph.new(monright, {checkBreederHeat}, {"Breeder1 Heat"}, {gradient1}, {0}, {reData.MaxHeat}, true)
grRight:draw()
end
end
end
Bomb Bloke #6
Posted 31 December 2013 - 10:34 PM
Hmmmm. This is entirely conjecture, but you may be able to pre-define a table with that original value in it before making your graph objects. Because the variable you assign the table to gets a pointer to the actual table, handing that pointer to the graph API may allow you to alter the max bounds later down the track:

local MaxHeat = {reData.MaxHeat}
local grLeft = graph.new (monleft, {checkReactorHeat } , { "Reactor1 Heat" } , {gradient1} , {0 }, MaxHeat, true)
local grRight = graph.new(monright, {checkBreederHeat}, {"Breeder1 Heat"}, {gradient1}, {0}, MaxHeat, true)
-------------------
function checkData()
incomingID,message = rednet.receive()
reData = textutils.unserialize(message)
MaxHeat[1] = reData.MaxHeat
.
.
.

This is, however, making pure assumptions as to how the graph API works - it may not hang on to its version of the pointer, and only keep the original value that was in the table at the time you defined the new graph. But I suppose it's either this or call graph.new again whenever you notice that value needs to be updated.
Lyqyd #7
Posted 31 December 2013 - 11:13 PM
It copies the bounds values, the tables are just for packaging when using multiple traces. The maximum bound for the table would go up as the values increased, though obviously, that's not really what you want for a reactor. I guess I don't really understand why you're changing the configuration of a monitored reactor… ever. Anyway, you've got the graph instance and can change it directly:


grLeft.max[1] = newValue
ihatetn931 #8
Posted 31 December 2013 - 11:28 PM
I want it to change so i don't have to manually up the the maxheat in the program and it does it for me. I got it to update but the program needs to be restarted to do so.

So i can add heat-capacity reactor plating without having to change the max heat manually it would do it it's self.

It worked before i change the code to the suggestion Bomb Bloke gave me, it would automatically update the MaxHeat in the graph.

I just like everything being automatic, it makes doing stuff much easier
Bomb Bloke #9
Posted 01 January 2014 - 08:14 AM
If I've got this right, Lyqyd is saying that the graph API will automatically adjust itself if your reactors fill up with more energy then you initially specified as the maximum. Presumably this is why you saw it "work" before changing your code: Because since then you haven't modified your reactors in the same way.

He's also saying that you can indeed have your script tweak that maximum value if the graph API doesn't do it the way you want. For eg:

function checkData()
incomingID,message = rednet.receive()
reData = textutils.unserialize(message)

if grLeft.max[1] ~= reData.MaxHeat  then
  grLeft.max[1] = reData.MaxHeat
  grRight.max[1] = reData.MaxHeat
end

if incomingID == 2 then
  .
  .
  .

One thing I'm scratching my head over, do the turtles have different sensors installed or something? I've not played with that type of turtle (or ever set up a reactor for that matter), but I'm beginning to suspect you've both got them monitoring the same system, sending in copies of the same data, and cherry-picking what info to pay attention to from each turtle. Or do their sensors really gather different things?
ihatetn931 #10
Posted 01 January 2014 - 12:01 PM
The sensors gather diffrent things, each sensor is connected to it's own reactor, sensors are gonna be the one controllin the reactors like turning them off if they get to hot, the computer is just to show the data so i don't have to be by the sensors to know what the reactors are doing, 1 reactor is gonna be the one producing all the power then the other one is going to be my breeder reactor, in this pic, the circled turtles are the sensor turtles, the other turtles are just gonna be for pulling out depleted fuel cells and putting them in the breeder reactor, they will also be putting in the coolant cells, so basically the whole system is gonna do everything by itself so i don't have to do anything.

I am gonna give that a try, 1 question would the


local grLeft = graph.new (monleft, {checkReactorHeat } , { "Reactor1 Heat" } , {gradient1} , {0 }, {reData.MaxHeat}, true)

Go in checkData() or above it if i use that code.

Spoiler
The system is not done, i still need to make a way to auto craft all the stuff needed for each

Sorry for being such a pain, trying to get how lua works nshit, i know other progamming langs and computercraft is the first time i really messed with lua.


Edit
Nevermind i figured it out, thank you both for the help.
Edited on 01 January 2014 - 10:38 PM
Bomb Bloke #11
Posted 01 January 2014 - 05:10 PM
It'd likely work in either position - I'm not sure where you put it, but our intention was for you to leave it where it was.
Lyqyd #12
Posted 01 January 2014 - 05:45 PM
Ideally, you should only declare it once, toward the beginning of the program.
ihatetn931 #13
Posted 01 January 2014 - 10:58 PM
Ahh ok, thank you again for your help.

I'm use to pawn scripting, it kinda the same but the way it works is diffrent and the way functions work are diffrent