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

Interrupt Service Routine

Started by newcat, 15 June 2014 - 02:45 PM
newcat #1
Posted 15 June 2014 - 04:45 PM
Hello,

is there any way to implement a kind of an ISR?

Basically what I tried (and what didn't work) is to use the ParallelAPI.


function receiveStandard()
  while (true) do
    sID, msg = rednet.receive("sP")
    uMsg = textutils.unserialize(msg) 
    print("Received Message from ", sID, ": ", uMsg["fct"])
    if (uMsg["fct"] == "sortInto") then
	  sortOutInvalid()
	  sortIntoWarehouse()
    end
  end
end
function receiveTurtleStatusChange()
  while (true) do
    sID, msg = rednet.receive("tscP")
    turtleState = tonumber(msg)
    print("New turtle state: ", turtleState)
  end
end
parallel.waitForAll(receiveStandard, receiveTurtleStatusChange)

I have a network with three computers, each commicating with each other. There is also a turtle, which can do something (turtleState = 1) or stand by (turtleState = 0).
Since all computers need to know if they can send commands to the turtle, everytime the turtle starts to do an action, it broadcasts "1" via the protocol "tscP".

Besides this, the computers also have to receive messages from other computers, which im doing over the "sP" (standard Protocol). When they receive a message, they have to execute something, but while they are executing, they should still be able to receive the turtle status change, since this can happen at any time.
This is similar to an ISR, since the turtle status change should be an interrupt, then the variable should be set, and afterwards the program should continue what it started.

Now is there a way to do this in lua? Or do you have any similar idea how to solve this problem?
Bomb Bloke #2
Posted 15 June 2014 - 04:58 PM
To be clear, there isn't any sort of "interrupt" available. The VM will only run one of those functions at a time - when one yields, it'll pass control to the other until it yields, and so on.

That said, your code looks to be about the closest you can get to what you're after, and should serve your purposes (assuming your sortOutInvalid() / sortIntoWarehouse() functions don't yield, which might cause you to miss some messages from other computers). How did the results differ from what you wanted?
newcat #3
Posted 15 June 2014 - 05:33 PM
It works now! The problem was that there was a rednet.receive() before the code I posted, which didn't get served.

Just a little question: If a message comes over the "tscP" protocol while the other coroutine is active, does it get queed and processed after the active coroutine yields ore is it just lost?
wieselkatze #4
Posted 15 June 2014 - 08:56 PM
As far as I know the event should get queued and the computer shouldn't miss the message.
CometWolf #5
Posted 15 June 2014 - 09:45 PM
All events are passed to the currently running parallel function, aswell as queued up for any others and passed to them as well when they are called. To be honest, you'd be far better off just using the same protocol or the modem API directly. That way you wouldn't need parallel.
Edited on 15 June 2014 - 07:45 PM
Bomb Bloke #6
Posted 16 June 2014 - 02:30 AM
Truth be told, you could use both protocols in the one function. Just remove the filter from the rednet.receive() statements, then use "if" statements to check which protocol came down the line.

Just to be sure it's clear, each function running in "parallel" gets its own copy of the event queue. If one function pulls an event out of the queue, the other still has that event in its copy until it pulls it out.

Certain commands have a tendency to flush everything out of the event queue. For example, it doesn't matter what you type while rednet.receive() is waiting for a rednet message - it'll throw away all your key events until it finds the rednet_message event it's waiting for.

Likewise, if you use the sleep command, all your rednet_message events get thrown away until that finds the timer event it's waiting for.

Given that a command will typically only yield in order to wait for an event, if your sortOutInvalid() / sortIntoWarehouse() do yield, then your use of parallel here means that at least your incoming turtle-related messages won't be lost.