User calibration in the PLC
You can also perform the correction calculation in the PLC instead of in the box. This has the advantage that you can set the measured value resolution as required: if the correction calculation is carried out in the box, the measured value resolution is limited to 1 mg/LSB.
Beckhoff also recommends reading the calibration coefficients from the CoE parameters provided for this purpose when calculating corrections in the PLC. This means that the PLC program does not have to be adapted when the box is replaced.
Sample program for the X-axis
Preparation:
- Integrate the PLC library “Tc2_EtherCAT”. (includes FB_EcCoESdoRead)
- Link "Device ‘EtherCAT’ > InfoData > AmsNetId" with
sAmsNetIdArr
. - Link "EP3751-0160 > AI Acc X Inputs > Value" with
nAx
. - Link "EP3751-0160 > InfoData > AdsAddr > port" with
nSlaveAdress
.
PROGRAM MAIN
VAR
nAmsNetIdArr AT %I*: T_AmsNetIdArr;
nSlaveAddress AT %I*: WORD;
nAxis_Value AT %I*: DINT;
eState: (IDLE, INIT_READ_OFFSET, READING_OFFSET, INIT_READ_GAIN, READING_GAIN,
NOMINAL_OPERATION, ERROR);
fbSdoRead: FB_EcCoESdoRead;
sAmsNetId: T_AmsNetId;
nOffset: INT;
nGainRaw: INT;
fGain: REAL;
fAxCalibrated: REAL;
bExecute: BOOL;
END_VAR
CASE eState OF
IDLE:
fbSdoRead(bExecute := FALSE);
sAmsNetId := F_CreateAmsNetId(nAmsNetIdArr);
IF bExecute THEN
eState := INIT_READ_OFFSET;
END_IF
INIT_READ_OFFSET:
fbSdoRead(
sNetId := sAmsNetId,
nSlaveAddr := nSlaveAddress,
nSubIndex := 16#17,
nIndex := 16#8000,
pDstBuf := ADR(nOffset),
cbBufLen := SIZEOF(nOffset),
bExecute := TRUE
);
eState := READING_OFFSET;
READING_OFFSET:
fbSdoRead();
IF NOT fbSdoRead.bBusy THEN
IF fbSdoRead.bError THEN
eState := Error;
ELSE
fbSdoRead(bExecute := FALSE);
eState := INIT_READ_GAIN;
END_IF
END_IF
INIT_READ_GAIN:
fbSdoRead(
sNetId := sAmsNetId,
nSlaveAddr := nSlaveAddress,
nSubIndex := 16#18,
nIndex := 16#8000,
pDstBuf := ADR(nGainRaw),
cbBufLen := SIZEOF(nGainRaw),
bExecute := TRUE
);
eState := READING_GAIN;
READING_GAIN:
fbSdoRead();
IF NOT fbSdoRead.bBusy THEN
IF fbSdoRead.bError THEN
eState := ERROR;
ELSE
fbSdoRead(bExecute := FALSE);
fGain := INT_TO_REAL(nGainRaw) / 16384;
eState := NOMINAL_OPERATION;
END_IF
END_IF
NOMINAL_OPERATION:
fAxCalibrated := fGain * DINT_TO_REAL(nAxis_Value - nOffset);
ERROR:
;
END_CASE