Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add linux support samples #14

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions samples/adslib/03_WriteByVariableName/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import de.beckhoff.jni.Convert;
import de.beckhoff.jni.JNIByteBuffer;
import de.beckhoff.jni.JNILong;
import de.beckhoff.jni.tcads.AdsCallDllFunction;
import de.beckhoff.jni.tcads.AmsAddr;

/**
* Sample - write PLC variable by its name
*
* @author Fabio Richeri ([email protected])
* @author Matteo Cartieri ([email protected])
*
*/
public class Main {
public static void main(String[] args) {
// Set up the ADS route between your Linux system and target PLC before running
// the program. Usually <linux_netid> is <linux_ip> plus .1.1

// ./adslib_for_linux/build/AdsTool/AdsTool <target_ip> addroute
// --addr=<linux_ip> --netid=<linux_netid> --password=<target_password>

long err;

JNIByteBuffer handleBuff = new JNIByteBuffer(Integer.SIZE / Byte.SIZE);
JNIByteBuffer symbolBuff = new JNIByteBuffer(Convert.StringToByteArr("MAIN.PLCVar", true));
// New buffer to hold integer value
JNIByteBuffer dataBuff = new JNIByteBuffer(Integer.SIZE / Byte.SIZE);

// Open communication
long port = AdsCallDllFunction.adsPortOpenEx();
if (port == 0) {
System.out.println("Error: Unable to open an ADS port.");
}

AmsAddr addr = new AmsAddr();
// Set the netId of the PLC target
addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE!
addr.setPort(851);

// Uncomment and adjust if automatic AMS NetId deduction is
// not working as expected:
// {
// AmsAddr local = new AmsAddr();
// local.setNetIdStringEx("Y.Y.Y.Y.1.1");
// AdsCallDllFunction.adsSetLocalAddress(local.getNetId());
// }

// Since the AMS routing isn't handled by the TwinCAT AMS Router, we need
// to tell the AdsLib which IP address is associated with the AMS NetId.
// Set this with the IP of the PLC target
AdsCallDllFunction.adsAddLocalRoute(addr.getNetId(), "X.X.X.X"); // TODO ADJUST THIS VALUE!

// Get handle by symbol name
JNILong lengthReturn = new JNILong();
err = AdsCallDllFunction.adsSyncReadWriteReqEx2(port, addr, AdsCallDllFunction.ADSIGRP_SYM_HNDBYNAME, 0x0,
handleBuff.getUsedBytesCount(), handleBuff, symbolBuff.getUsedBytesCount(), symbolBuff, lengthReturn);
if (err != 0) {
System.out.println("Error: Get handle: 0x" + Long.toHexString(err));
} else {
System.out.println("Success: Get handle!");
}

// Handle: byte[] to int
int hdlBuffToInt = Convert.ByteArrToInt(handleBuff.getByteArray());

// Write byte array with new PLCVar value = 123
int newValue = 123;
ByteBuffer bb = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(newValue);
byte[] byArr = bb.array();
// Set data buffer
dataBuff.setByteArray(byArr, false);

// Write value by handle
lengthReturn = new JNILong();
err = AdsCallDllFunction.adsSyncWriteReqEx(port, addr, AdsCallDllFunction.ADSIGRP_SYM_VALBYHND, hdlBuffToInt,
dataBuff.getUsedBytesCount(), dataBuff);

if (err != 0) {
System.out.println("Error: Write by handle: 0x" + Long.toHexString(err));
} else {
System.out.println("Success: PLCVar write value: " + newValue);
}

// Read value to check the write
err = AdsCallDllFunction.adsSyncReadReqEx2(port, addr, AdsCallDllFunction.ADSIGRP_SYM_VALBYHND, hdlBuffToInt,
dataBuff.getUsedBytesCount(), dataBuff, lengthReturn);
if (err != 0) {
System.out.println("Error: Read by handle: 0x" + Long.toHexString(err));
} else {
// Convert byte array to int
int plcVar = Convert.ByteArrToInt(dataBuff.getByteArray());
System.out.println("Success: PLCVar read value: " + plcVar);
}

// Release handle
err = AdsCallDllFunction.adsSyncWriteReqEx(port, addr, AdsCallDllFunction.ADSIGRP_SYM_RELEASEHND, 0,
handleBuff.getUsedBytesCount(), handleBuff);

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

// Remove the associating between the AMS NetId and the IP address of
// our target system
AdsCallDllFunction.adsDelLocalRoute(addr.getNetId());

// Close communication
err = AdsCallDllFunction.adsPortCloseEx(port);
if (err != 0) {
System.out.println("Error: Close Communication: 0x" + Long.toHexString(err));
}

try {
System.in.read();
} catch (Exception e) {
System.out.println("Error: Close program");
}
}
}
27 changes: 27 additions & 0 deletions samples/adslib/04_EventDrivenReading/AdsListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import de.beckhoff.jni.Convert;
import de.beckhoff.jni.tcads.AdsNotificationHeader;
import de.beckhoff.jni.tcads.AmsAddr;
import de.beckhoff.jni.tcads.CallbackListenerAdsState;
import java.util.Date;

public class AdsListener implements CallbackListenerAdsState {
private final static long SPAN = 11644473600000L;

// Callback function
public void onEvent(AmsAddr addr, AdsNotificationHeader notification, long user) {

// The PLC timestamp is coded in Windows FILETIME.
// Nano secs since 01.01.1601.
long dateInMillis = notification.getNTimeStamp();

// Date accepts millisecs since 01.01.1970.
// Convert to millisecs and substract span.
Date notificationDate = new Date(dateInMillis / 10000 - SPAN);

System.out.println("Value:\t\t" + Convert.ByteArrToInt(notification.getData()));
System.out.println("Notification:\t" + notification.getHNotification());
System.out.println("Time:\t\t" + notificationDate.toString());
System.out.println("User:\t\t" + user);
System.out.println("ServerNetID:\t" + addr.getNetIdString() + "\n");
}
}
134 changes: 134 additions & 0 deletions samples/adslib/04_EventDrivenReading/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import de.beckhoff.jni.AdsConstants;
import de.beckhoff.jni.Convert;
import de.beckhoff.jni.JNIByteBuffer;
import de.beckhoff.jni.JNILong;
import de.beckhoff.jni.tcads.AdsCallDllFunction;
import de.beckhoff.jni.tcads.AdsCallbackObject;
import de.beckhoff.jni.tcads.AdsNotificationAttrib;
import de.beckhoff.jni.tcads.AmsAddr;

/**
* Sample - add event listener for PLC variable
*
* @author Fabio Richeri ([email protected])
* @author Matteo Cartieri ([email protected])
*
*/
public class Main {
public static void main(String[] args) {
// Set up the ADS route between your Linux system and target PLC before running
// the program. Usually <linux_netid> is <linux_ip> plus .1.1

// ./adslib_for_linux/build/AdsTool/AdsTool <target_ip> addroute
// --addr=<linux_ip> --netid=<linux_netid> --password=<target_password>

try {
long err;

JNIByteBuffer handleBuff = new JNIByteBuffer(Integer.SIZE / Byte.SIZE);
JNIByteBuffer symbolBuff = new JNIByteBuffer(Convert.StringToByteArr("MAIN.PLCVar", true));
JNILong notification = new JNILong();

// Open communication
long port = AdsCallDllFunction.adsPortOpenEx();
if (port == 0) {
System.out.println("Error: Unable to open an ADS port.");
}

AmsAddr addr = new AmsAddr();
// Set the netId of the PLC target
addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE!
addr.setPort(851);

// Uncomment and adjust if automatic AMS NetId deduction is
// not working as expected:
// {
// AmsAddr local = new AmsAddr();
// local.setNetIdStringEx("Y.Y.Y.Y.1.1");
// AdsCallDllFunction.adsSetLocalAddress(local.getNetId());
// }

// Since the AMS routing isn't handled by the TwinCAT AMS Router, we need
// to tell the AdsLib which IP address is associated with the AMS NetId.
// Set this with the IP of the PLC target
AdsCallDllFunction.adsAddLocalRoute(addr.getNetId(), "X.X.X.X"); // TODO ADJUST THIS VALUE!

// Get handle by symbol name
JNILong lengthReturn = new JNILong();
err = AdsCallDllFunction.adsSyncReadWriteReqEx2(port, addr, AdsCallDllFunction.ADSIGRP_SYM_HNDBYNAME, 0x0,
handleBuff.getUsedBytesCount(), handleBuff, symbolBuff.getUsedBytesCount(), symbolBuff,
lengthReturn);
if (err != 0) {
System.out.println("Error: Get handle: 0x" + Long.toHexString(err));
} else {
System.out.println("Success: Get handle!");
}

// Handle: byte[] to int
int hdlBuffToInt = Convert.ByteArrToInt(handleBuff.getByteArray());

// Write value by handle
lengthReturn = new JNILong();
// Specify attributes of the notificationRequest
AdsNotificationAttrib attr = new AdsNotificationAttrib();
attr.setCbLength(Integer.SIZE / Byte.SIZE);
attr.setNTransMode(AdsConstants.ADSTRANS_SERVERONCHA);
attr.setDwChangeFilter(10000000); // 1 sec
attr.setNMaxDelay(20000000); // 2 sec

// Create and add listener
AdsListener listener = new AdsListener();
AdsCallbackObject callObject = new AdsCallbackObject();
callObject.addListenerCallbackAdsState(listener);

// Create notificationHandle
err = AdsCallDllFunction.adsSyncAddDeviceNotificationReqEx(port, addr,
AdsCallDllFunction.ADSIGRP_SYM_VALBYHND, hdlBuffToInt, // IndexOffset
attr, // The defined AdsNotificationAttrib object
0, // Choose arbitrary number
notification);

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

// Read as long as user does not press return
System.out.println("Press enter to continue..\n");
System.in.read();

// Delete device notification
err = AdsCallDllFunction.adsSyncDelDeviceNotificationReqEx(port, addr, notification);

if (err != 0) {
System.out.println("Error: Remove device notification: 0x" + Long.toHexString(err));
}

// Delete listener
callObject.removeListenerCallbackAdsState(listener);

// Release handle
err = AdsCallDllFunction.adsSyncWriteReqEx(port, addr, AdsCallDllFunction.ADSIGRP_SYM_RELEASEHND, 0,
handleBuff.getUsedBytesCount(), handleBuff);

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

// Remove the associating between the AMS NetId and the IP address of
// our target system
AdsCallDllFunction.adsDelLocalRoute(addr.getNetId());

// Close communication
err = AdsCallDllFunction.adsPortCloseEx(port);
if (err != 0) {
System.out.println("Error: Close Communication: 0x" + Long.toHexString(err));
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}