Community

Does RSIEventTypeLIMIT_ERROR generate an interrupt?

Suppose I want to be notified when an axis/multiaxis gets a limit error (exceeds position error exceeds ErrorLimitTriggerValueGet()). Can I turn on the RSIEventTypeLIMIT_ERROR interrupt mask and receive an interrupt?

Which object(s) do I need to enable this on? Both the MotionController and the Axis? Only the axis? Do (or can) all the interrupts come in through the motion controller’s InterruptWait() method or do I have to check on each object, too?

I’m not seeing an interrupt like this when I’ve set this via InterruptMaskOnSet() and retrieved interrupts via MotionController::InterruptWait(). There aren’t examples of doing this, so I’m trying to make an educated guess (but seem to be doing it wrong).

I found this in our automated tests. I believe it achieves what you are trying to do.
Hopefully this can be a use full example for you for now.

[Test]
public void InterruptTestPositionLimit()
{
const int moveid = 1234;

        axis.InterruptEnableSet(true);
        axis.InterruptMaskOnSet(RSIEventType.RSIEventTypeLIMIT_ERROR);

        axis.MotionIdSet(moveid);

        Assert.AreEqual(moveid, axis.MotionIdGet(), "Motion ID not equal, this is a problem");
        Console.WriteLine("MotionId is set to:  " + moveid);
        axis.UserUnitsSet(1);
        axis.ErrorLimitTriggerValueSet(20);

        // move 30 counts  in about one second
        axis.MoveTrapezoidal((axis.CommandPositionGet() + 30), 1000, 1000, 10000);

        Assert.AreEqual(moveid, axis.MotionIdExecutingGet(), "We commanded a motion with this ID, it should be executing.");

        bool gotLimitError = false;
        bool done = false;
        while (!done)
        {
            RSIEventType myInterrupt = axis.InterruptWait(4000);


            if (myInterrupt == RSIEventType.RSIEventTypeLIMIT_ERROR)
            {
                gotLimitError = true;
            }

            if (myInterrupt == RSIEventType.RSIEventTypeMOTION_DONE)
            {
                done = true;
                Console.WriteLine("Axis Interrupt Test -- Got Motion Done");
                Console.WriteLine("InterruptMotionId = " + axis.InterruptMotionIdGet());
                Assert.That(moveid, Is.EqualTo(axis.InterruptMotionIdGet()), "Interrupt Motion ID does not match set value!");

            }
            else if (myInterrupt == RSIEventType.RSIEventTypeTIMEOUT)
            {
                done = true;
                Console.WriteLine("InterruptTest failed with TIMEOUT");
                Assert.Fail("InterruptTest failed with TIMEOUT");
            }
            Console.WriteLine("Axis IRQ " + myInterrupt);
            Console.WriteLine("IRQ Type " + axis.InterruptNameGet());
            Console.WriteLine("InterruptSourceNumber = " + axis.InterruptSourceNumberGet());
            Console.WriteLine("InterruptSampleTimer = " + axis.InterruptSampleTimeGet());

            Console.WriteLine();

        }

        Assert.That(gotLimitError, Is.True);

        // this added 20070808 -- failing with exception
        axis.InterruptWake();

        axis.InterruptEnableSet(false);
    }
1 Like

Thanks for the good example.

Does this mean that I ought to spawn separate threads (one per axis, say) to wait for and handle these interrupts? I already have a thread that waits for interrupts on the motion controller, but I won’t see the axis interrupts, right?

Yes, ideally you would have a thread for each axis.

1 Like

Thanks, @nikolas.

For the sake of offering constructive criticism, I did not find any clear direction about how to do this on the documentation portal. Here’s where I started looking:

Perhaps the problem is that I didn’t know where to start looking for information, but I couldn’t find any docs that provided any detail for the interrupt interface or how it worked. I suppose it’s a logical assumption to think that whatever object you MaskSetOn(...) for would be the object that you Wait() for, but I would prefer to have definitive answers as opposed to good guesses. (-8