Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
read EtherCAT status
#1
I'm using an EtherCAT Yaskawa amplifier. Because of some hardware issues, the encoder occasionally heats up and the amplifier has an alarm. At this point the control of the coordinate system goes awry, with the other axes seemingly continuing motion. I think this is because there's seemingly no error on the PMAC side.

I can read the error
debug1 = ecattypedsdo(0,2,1,$603F,0,0,4) debug1
P8208=2144 //0x860 = overheat

but I saw some document not to put this in a loop, presumably because it is slow. I could make a loop that only read it every 10ms. Is there any standard way to handle this?

And to stop can I just issue a Motor[3].InterlockStop?

Thanks
Reply
#2
I think your best bet is to use the "auxiliary fault" function here. (I am a little surprised that this is not rolled into the standard amplifier fault bit, but auxiliary fault was meant for special cases like this.)

You ~10-msec sampling routine needs to put your sampling result into a fixed bit of an integer register (possibly Sys.Udata[i] in the shared buffer). Then you point to this register with Motor[x].pAuxFault and specify the bit with Motor[x].AuxFaultBit. Also set AuxFaultLevel and AuxFaultLimit.

Now when the fault occurs, PMAC will automatically "kill" this motor, and stop all other motors in the coordinate system, either to a closed-loop zero-velocity state, or a disabled (killed) state, depending on the setting of Motor[x].FaultMode.
Reply
#3
JeffB. You set everything up the normal way (with system setup) so that Motor[x].pAmpFault is pointed to an EtherCAT register? That really sounds like it should be part of the normal amp fault function. Curt's suggestion to use the auxiliary amp fault bit should solve the problem.

Motor[3].InterlockStop is a status bit.
Reply
#4
Thanks Curt, Eric

It looks like EtherCAT is correctly configured:
﹒﹒Motor[1].pAmpFault
﹒﹒Motor[1].pAmpFault=ECAT[0].IO[4096].Data.a
﹒﹒Motor[2].pAmpFault
﹒﹒Motor[2].pAmpFault=ECAT[0].IO[4098].Data.a
﹒﹒Motor[3].pAmpFault
﹒﹒Motor[3].pAmpFault=ECAT[0].IO[4100].Data.a

So I wrote a plc routine to monitor.

from configuration.pmh
﹒﹒Motor[3].pAuxFault = Sys.Udata[0].a
﹒﹒Motor[3].AuxFaultBit = 0
﹒﹒Motor[3].AuxFaultLevel = 1
﹒﹒Motor[3].AuxFaultLimit = 1

// PLC Motor Monitor
//check for alarm on Yaskawa amplifier

#define ECAT_NETWORK 0
#define J3_AXIS_INDEX 2
#define SDO_READ 1 //Service Dictionary Object
#define YASKAWA_ALARM_ADDRESS $603F
#define YASKAWA_OVERHEAT_ALARM $860

OPEN PLC MotorMonitor
local time_sec = 0.0;
local alarm

//if motors from coordinate system 1 are moving
if (Coord[1].DesVelZero != TRUE)
{
﹒﹒if (time_sec < Sys.RunTime)
﹒﹒{
﹒﹒﹒﹒time_sec = Sys.RunTime + 0.010//10ms
﹒﹒﹒﹒alarm = ecattypedsdo(ECAT_NETWORK,J3_AXIS_INDEX,SDO_READ,YASKAWA_ALARM_ADDRESS,0,0,4)
﹒﹒﹒﹒if (alarm == YASKAWA_OVERHEAT_ALARM)
﹒﹒﹒﹒﹒﹒Sys.Udata[0] |= $1
﹒﹒﹒﹒else
﹒﹒﹒﹒﹒﹒Sys.Udata[0] &= ~$1
﹒﹒}
}

CLOSE
Reply
#5
Yes, that was exactly what I had in mind!

One quick note: When a motor is enabled that has no hardware mapped to it, it may use Sys.Udata[0] for some automatic functions. You probably want to move it to any other Sys.Udata[i] (1 or greater).
Reply
#6
Any reason why a SDO read ecattypedsdo(0,0,1,$603F,0,0,4) return nan in a subprogram but works in the terminal?
Reply
#7
Quote:Any reason why a SDO read ecattypedsdo(0,0,1,$603F,0,0,4) return nan in a subprogram but works in the terminal?
Nothing comes to mind, but are you calling the subprogram from a PLC or Motion Program?
Are you sure it ran? Maybe have it increment a variable on the next line.
Reply
#8
Calling from a motion program when it fails; calling directly from plc routine when succeeds. And I'm sure the subprogram ran because it changes the value from 0 to nan.

I will experiment some more.
Reply
#9
Unfortunately, commands to read SDOs won't work in realtime processes, such as Motion Programs or realtime PLCs. Waiting for a response from the slave device would block execution of other realtime PLCs and/or the motion calculations. As such, whether in a motion program or a subprogram called from one, the ecattypedsdo command will not wait for a response.
Reply
#10
I figured the reason was something like that; unless I missed something, it sounds like it's time for a manual update.

So I assume the preferred method of calling ecattypedsdo from a motion program would be to call a non blocking plc routine and wait until plc routine was done by looking at when Plc[x].Active and/or Plc[x].Running equals false.
Reply
#11
Pretty much--I might leave the PLC active at all times and just pass a flag back and forth instead, but it's the same general idea. You could even make it more generic:

GLOBAL ReadWriteSDOFlag = 0
GLOBAL EcatMasterNum = 0
GLOBAL EcatSlaveNum = 0
GLOBAL EcatReadWriteFlag = 0
GLOBAL EcatIndex = 0
GLOBAL EcatSubIndex = 0
GLOBAL EcatValue = 0
GLOBAL EcatNumBytes = 0
GLOBAL EcatResult = 0


OPEN PLC ReadWriteSDOPLC
IF(ReadWriteSDOFlag == 1)
{
EcatResult = ecattypedsdo(EcatMasterNum,EcatSlaveNum,EcatReadWriteFlag,EcatIndex,EcatSubIndex,EcatValue,EcatNumBytes)
ReadSDOFlag = 0
}
CLOSE

Then just have your motion program set the parameters you want to read/write, set ReadWriteSDOFlag true, and wait for it to go false and read the result from EcatResult.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)