Auslesen von SMB-Werten aus dem TwinCAT I/O Treiber

Falls statt einer TwinCAT PLC Laufzeitumgebung nur TwinCAT-CP zur Verfügung steht, kann das SMB-Gerät auch mit Hilfe des ADS-Clients ausgelesen werden. Die Visualisierung erlaubt ein ständiges Überwachen der gewünschten Temperatur- oder Lüfterwerte. Somit kann frühzeitig erkannt werden, ob sich die aktuelle Temperatur einem kritischen Wert annähert. Nachfolgend ein Beispiel einer möglichen Implementierung in Java (Für eine korrekte Funktionsweise muss ein SMB-Gerät in der aktuellen System Manager-Konfiguration eingetragen sein)

Beispielprogramm 'Auslesen von SMB-Werten aus dem TwinCAT I/O Treiber' entpacken: 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());
    } 
    }
}
Auslesen von SMB-Werten aus dem TwinCAT I/O Treiber 1:

In dieser Ansicht kann der jeweilige IndexOffset der verschiedenen Eingänge abgelesen werden.

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()));
    }
    }
}