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

Send "Order" via Wireless modem and output redstone signal just once

Started by A2020, 19 January 2016 - 09:46 PM
A2020 #1
Posted 19 January 2016 - 10:46 PM
Hi guys, I'm new to the forum, and kinda new with LUA and Computercraft in general (familiarized with other languages)

I have a problem. I have 2 Computers with modems and the idea is that Computer one sends an order to computer 2 via wireless modem, I need Computer 2 (There will be many others listening too) to output a redstone signal if the order sent matches what its waiting for to be true.

Here is what I have so far (Totally raw code) the idea will be making it more complex and with a GUI on an interface, but I'm testing so far.

Computer 1:


local modem = peripheral.wrap("top")
local orderChannel = 55
modem.open(orderChannel)
modem.transmit(orderChannel, orderChannel, "TTT")
sleep(1.5)
modem.transmit(orderChannel, orderChannel, "Clear")

Computer 2:


local modem = peripheral.wrap("top")
local orderChannel = 55
local terminal = "TTT"
modem.open(orderChannel)
local messageArguments = {os.pullEvent("modem_message")}
while true do

if terminal==messageArguments[5] then
redstone.setOutput("back", true)
sleep(1)
redstone.setOutput("back", false)
print("We receive 1 order")
else
redstone.setOutput("back", false)
end
sleep(0.1)
end


I'm almost sure that my error is on Computer 2, where I check for the argument to be true and even when I sleep on computer 1 and send a different message, that if statement on computer 2 remains true and that's why the redstone signal keep active.

How should I fix this?

Thanks a lot.
Bomb Bloke #2
Posted 19 January 2016 - 11:59 PM
Computer two receives one message, and then checks its content over and over, without ever bothering to pull the next one out of the event queue. Stick this line:

local messageArguments = {os.pullEvent("modem_message")}

into your loop.

Also bear in mind that sleep works like this:

function sleep( nTime )
    local timer = os.startTimer( nTime or 0 )
    repeat
        local sEvent, param = os.pullEvent( "timer" )
    until param == timer
end

If any modem messages arrive while this function is running, they'll be discarded from the event queue while it searches for timer events - you'll hence want to ditch your "sleep(0.1)" line, as it's not doing anything of value.
A2020 #3
Posted 20 January 2016 - 12:05 AM
Thanks a lot, gonna try it.

I used the sleep to prevent this http://www.computercraft.info/forums2/index.php?/topic/1525-lua-too-long-without-yielding/ but I didn't realize it needs to be sleep(0)

Thanks once again for the help.
Bomb Bloke #4
Posted 20 January 2016 - 12:32 AM
Er, no, it doesn't need to be sleep(0). Simply calling os.pullEvent() every so often is good enough, and you're already doing that when you pull your modem_message events.
Dragon53535 #5
Posted 20 January 2016 - 02:44 AM
As BB said, as long as you're using os.pullEvent(), you're never going to run into that error.
I suspect however, you at one point you ran into that error and then googled it and added the sleep into it and it didn't error again. Thing is, as BB said, sleep calls os.pullEvent() internally and while you're sleeping, anything that comes in gets discarded.