Reading SMB values from the TwinCAT I/O driver

If only TwinCAT-CP is available instead of a TwinCAT PLC runtime environment, the SMB device can also be read out using the ADS client. The visualization allows constant monitoring of the desired temperature or fan values. Thus, it can be detected at an early stage whether the current temperature is approaching a critical value. The following is a sample of a possible implementation in Java (for correct operation, an SMB device must be entered in the current System Manager configuration)

Unpack the sample program 'Reading SMB values from the TwinCAT I/O driver': sample10.zip

 

import de.beckhoff.jni.Convert;
import de.beckhoff.jni.JNIByteBuffer;
import de.beckhoff.jni.tcads.AdsCallDllFunction;
import de.beckhoff.jni.tcads.AdsState;
import de.beckhoff.jni.tcads.AmsAddr;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.ByteBuffer;
import java.util.Timer;

public class Main {
    final static short SMB_ID = 32;

    public static void main(String[] args) {
    long err = 0;
    AmsAddr addr = new AmsAddr();

    Visualization visu = new Visualization();
    visu.addWindowListener(new WindowAdapter() {
        // When the form is closed the ADS port is closed as well
        @Override
        public void windowClosing(WindowEvent e) {
        AdsCallDllFunction.adsPortClose();
        }
    });

    try {
        // Open communication        
        AdsCallDllFunction.adsPortOpen();
        err = AdsCallDllFunction.getLocalAddress(addr);
        addr.setPort(AdsCallDllFunction.AMSPORT_R0_PLC_RTS1);

        if (err != 0) {
        System.out.println("Error: Open communication: 0x"
            + Long.toHexString(err));
        } else {
        System.out.println("Success: Open communication!");
        } 

        //Gets the device count of devices appended to active configuration
        //if TwinCAT is in run mode
        AdsState adsState = new AdsState();
        AdsState deviceState = new AdsState();

        err = AdsCallDllFunction.adsSyncReadStateReq(addr,
            adsState,
            deviceState);
        if(err!=0) { 
        visu.setInfoMsg("Error: Read device state: 0x"
            + Long.toHexString(err));
        }

        if (adsState.getState() != AdsState.ADSSTATE_RUN ) {
        visu.setInfoMsg("Bad TwinCAT state: " 
            + "Please restart the application.");
        } else {
        //Get devices count
        JNIByteBuffer deviceCountBuff = new JNIByteBuffer(Integer.SIZE / Byte.SIZE);
        int devCount = 0;

        err = AdsCallDllFunction.adsSyncReadReq(addr,
            0x5000,
            0x2,
            deviceCountBuff.getUsedBytesCount(),
            deviceCountBuff);
        if(err!=0) { 
            visu.setInfoMsg("Error: Read device count: 0x"
                + Long.toHexString(err));
        }

        devCount = Convert.ByteArrToInt(
            deviceCountBuff.getByteArray()) + 1;

        //Gets the device count of devices appended to active
        //configuration as zero-based index and gets the devices ID's of
        //all active devices for the remaining indices (inverted sort)
        JNIByteBuffer deviceBuff = new JNIByteBuffer(
            (Short.SIZE * devCount) / Byte.SIZE);
        ByteBuffer devices;

        err = AdsCallDllFunction.adsSyncReadReq(addr,
            0x5000,
            0x1,
            deviceBuff.getUsedBytesCount(),
            deviceBuff);
        if(err!=0) { 
            visu.setInfoMsg("Error: Read devices: 0x"
                + Long.toHexString(err));
        }

        devices = ByteBuffer.wrap(deviceBuff.getByteArray());

        for (int i = 1; i <= devCount; i++) {
            JNIByteBuffer identNrBuff = 
                new JNIByteBuffer(Short.SIZE / Byte.SIZE);
            short identNr = 0;

            //gets the device identification number
            //(Motherboard System Management Bus(SMB) => 32)
            err = AdsCallDllFunction.adsSyncReadReq(addr,
                0x5000 + devices.getShort(i),
                0x7,
                identNrBuff.getUsedBytesCount(),
                identNrBuff);
            if(err!=0) {
            visu.setInfoMsg("Error: Read ident numbers: 0x"
                + Long.toHexString(err));
            } else {
            identNr = Convert.ByteArrToShort(
                identNrBuff.getByteArray());

            //checks whether the device is of type SMB
            if (identNr == SMB_ID) {
                int indexGroup = 0x9000 + devices.getShort(i);

                // If a SMB-Device was found a TimerTask is started
                // to read the specified input from the device once
                // every second
                Timer tmr = new Timer();
                tmr.schedule(new SMBTask(indexGroup, addr, visu),
                    0,
                    1);

                break;
            }
            }
        }
        }

    } catch (Exception ex) {
        visu.setInfoMsg(ex.getMessage());
    } 
    }
}
Reading SMB values from the TwinCAT I/O driver 1:

In this view the respective IndexOffset of the different inputs can be read.

import de.beckhoff.jni.Convert;
import de.beckhoff.jni.JNIByteBuffer;
import de.beckhoff.jni.tcads.AdsCallDllFunction;
import de.beckhoff.jni.tcads.AmsAddr;
import java.util.TimerTask;

class SMBTask extends TimerTask {
    private int indexGroup;
    private AmsAddr addr;
    private Visualization visu;

    public SMBTask(int indexGroup, AmsAddr addr, Visualization visu) {
    this.indexGroup = indexGroup;
    this.addr = addr;
    this.visu = visu;
    }

    @Override
    public void run() {
    long err = 0;
    JNIByteBuffer valueBuff = new JNIByteBuffer(Integer.SIZE / Byte.SIZE);

    //IOffset may be adjusted to monitor different inputs e.g. temperature
    err = AdsCallDllFunction.adsSyncReadReq(this.addr,
        this.indexGroup,
        0x4,
        valueBuff.getUsedBytesCount(),
        valueBuff);

    if(err!=0) {
        visu.setInfoMsg("Error: Retrieve value: 0x" + Long.toHexString(err));
    } else {
        visu.setCurValue(Convert.ByteArrToInt(valueBuff.getByteArray()));
    }
    }
}