Start Background Task after it stopped

I have a Background Task, which is responsible for some Signals between PLC and glue dispensing. The Task is declared as semistatic, the trustlever is “SysFail”. Sometimes it stops working and the only way to get it back running is to Restart the whole Controller, which is not so nice as the whole production line has an E-Stop.

Does anyone know a solution to Restart the Background Task to get the Signals back running?

Controller is IRC5 with RW 6.08

Thank you in Advance,
best, Matthias

Since the task is semistatic, not normal, then that would be your only option. Try to fix the error (debug) your background task so that it does not stop. Do you use error handling in that task?

NO Error handling. The task just reads digital inputs and then triggers digital outputs, as the robot is used to transfer signals from one plc to the dispensing unit…
this is basically the only function of the task…
What kind of error handling do you have in mind??

Any kind of error handler to begin with. You could at least pinpoint the actual error code by reading the system variable ERRNO.

Could you use cross connections instead of the task?
They would update automatically without any need for RAPID programing.

@graemepaulin
Very good point. And I have to ask if the robot is dispensing on a part or holding the part on to which you are dispensing. If so, you would probably be much better off buying the Dispenseware option. You have much better integration and coordination with the dispense equipment than by having the robot or PLC as the go between. You get more control over dispense lags and have faster response times. Not only that, but also, you can have TCP driven flows which give you better bead controls.

I found the problem!!! The task was fine, but inside, when you used the function keys…the way that was programmed, the program pointer got caught inside of a While -Loop. But that is necessary…
So I will just set up another task, which runs and is only responsible for the signals to route through the controller.

THANK YOU ALL FOR YOUR HELP!!! This was my first time in this forum.
Great community

Best, Matthias

Hello, I’m currently experiencing a similar issue to yours. I want to send a signal to the PLC through a background task, but when the device connection is disconnected, the signal is lost and the task stops running. Could you guide me on how to handle this problem?

Hi…
Background tasks perform excellently when they follow the logic of a PLC: each instruction executes its function and the flow advances, without internal loops or waits that block the cycle. In your case, what happens when the connection drops? Does the system try to reconnect and wait? For how long?

If these signals are fundamental, what is the impact on execution if they fail? Is there a routine to handle this error?

I use semi-static data exclusively to collect data that does not compromise the continuity of the program—such as a repositioning parameter, for example. If your reality is different, I recommend not using this structure, as any failure will cause the execution to freeze, requiring a complete restart to resume.

A semi-static data structure needs to be like a clock: it must maintain a constant execution pattern and, under no circumstances, can it stop.

Good job!

My robot has an automatic tool change application, specifically changing between different grippers. I want to monitor the gripper clamp open/close signals and send them to the PLC for supervision/monitoring.

The problem is that when changing tools, I have to disconnect the gripper. When it is disconnected like that, the robot can no longer detect the signals, which causes an error. I already have logic to check whether a gripper is mounted on the robot, but in some cases this error still occurs.
FOR i_zone FROM 1 TO MaxIN DO
AliasIO stGripperInputs{i_zone,nGrp},aio_diRBGripperInput{i_zone};
AliasIO stPLCGripperInput{i_zone},aio_doPLCGripperInput{i_zone};
WaitTime 0.1;
IF nGrp=0 THEN
RETURN;
ELSEIF nGrp<>0 THEN
SetDO aio_doPLCGripperInput{i_zone},aio_diRBGripperInput{i_zone};
ENDIF
ENDFOR

FOR i_zone FROM 1 TO MaxOUT DO
AliasIO stGripperOutputs{i_zone,nGrp},aio_doRBGripperOutput{i_zone};
AliasIO stPLCGripperOutput{i_zone},aio_doPLCGripperOutput{i_zone};
WaitTime 0.1;
IF nGrp=0 THEN
RETURN;
ELSEIF nGrp<>0 THEN
SetDO aio_doPLCGripperOutput{i_zone},aio_doRBGripperOutput{i_zone};
ENDIF
ENDFOR

Hi…
I’m a little confused… I didn’t quite understand how you define the value of ‘nGrp’? Without the complete code, it’s difficult to suggest a solution. My guess is that you’re trying to access an invalid position in the array, in: “AliasIO stGripperInputs{i_zone,nGrp},aio_diRBGripperInput{i_zone};” or “AliasIO stGripperOutputs{i_zone,nGrp},aio_doRBGripperOutput{i_zone};”

I suggest that before doing that you test the value of ‘nGrp’. And if it’s ‘0’, execute a stop, so you’ll know if that’s the problem.

Good job.

Are you using the instructions IODisable and IOEnable? Do you have an error handler? Lastly, why do you not simply cross connect those signals?

Yes, that’s exactly what I mean. When the robot changes tools, the I/O signals are disconnected, which causes the instruction to be unable to find a value in the array.

Below is my code snippet.
nGrp:=nGrOnRobot();
FUNC num nGrOnRobot()
!******************************************
!* Funktion Rückgabe Greifer Nr. am Robot *
!******************************************

VAR num nGrp;

FOR i FROM 1 TO nMaxGrp DO

	nGrp:=i;

	IF IOUnitState("GR"+NumToStr(nGrp,0)+"_Gripper")=IOUNIT_RUNNING RETURN nGrp;

ENDFOR

RETURN 0;

ERROR

SkipWarn;

!** Error Handler **
IF ERRNO=ERR_NAME_INVALID THEN
	IF nGrp=1 THEN
		RETURN 0;
	ELSE
		TRYNEXT;
	ENDIF
ENDIF

ENDFUNC

!(nGrOnRobot)

!*******************************************************************************

Yes, I use the IODisable and IOEnable instructions in the robot’s working program. I can’t cross-connect the signals because my arrays are very large—64×4 and 40×4—with four different grippers.

Hi…
Well… In your case, is a semi-static task necessary for this? Wouldn’t a trap solve it?

In your case, your function returns 0 in case of error, but you are not handling this value before using it as an index in your vector. That is, when an error occurs, the return will be 0 and will cause index problems in your call.

I suggest you change your logic a bit so that the return is NEVER 0 or do some handling before using nGrp.

IF nGrp=0 THEN
    RETURN;
ELSEIF nGrp > 0 THEN
    FOR i_zone FROM 1 TO MaxIN DO
        AliasIO stGripperInputs{i_zone,nGrp},aio_diRBGripperInput{i_zone};
        AliasIO stPLCGripperInput{i_zone},aio_doPLCGripperInput{i_zone};

        WaitTime 0.1;
        SetDO aio_doPLCGripperInput{i_zone},aio_diRBGripperInput{i_zone};
    ENDFOR

    FOR ....
    ENDFOR
ENDIF

… If your nGrp changes constantly during execution, I suggest you wrap it in a WHILE loop instead of FOR…

! Something like this...
WHILE nGrp > 0 And nGrp <= MaxIN DO
    .... 
ENDWHILE

Good Job.

OK, I see that your function has an error handler. The line, RETURN 0; ought to cause an error, ERR_FUNCNORET, the function returned no value. Try adding that in an error handler in the routine that calls the function.

Another thing that I would add is ERR_NORUNUNIT, the IO unit is not running. One more thing that I almost always do is use a TEST CASE in the error handler with a DEFAULT (Instead of an IF ENDIF).

That is a placeholder for an instruction. An attempt to execute a placeholder will cause an error that stops program execution. At this point one would look for the vale stored in the ERRNUM data, ERRNO. This holds the error number for the last occurring error. Compare that value with the built in error numbers to find the actual fault. It could be that there has been an error occurrence that you never thought would happen.

Finally, maybe you add a WaitGI your_GI_here,\NOTEQ, 0; where appropriate to ensure that the program execution only continues when the desired GI has a non zero value.