From 8ce7b3826702e11d05bf2f2f7831aa0684b3f288 Mon Sep 17 00:00:00 2001 From: Matteo-Cartieri Date: Fri, 23 Aug 2024 11:18:01 +0200 Subject: [PATCH 1/5] add new samples Linux-supported --- .../adslib/03_WriteByVariableName/Main.java | 123 ++++++++++++++++ .../04_EventDrivenReading/AdsListener.java | 27 ++++ .../adslib/04_EventDrivenReading/Main.java | 133 ++++++++++++++++++ 3 files changed, 283 insertions(+) create mode 100644 samples/adslib/03_WriteByVariableName/Main.java create mode 100644 samples/adslib/04_EventDrivenReading/AdsListener.java create mode 100644 samples/adslib/04_EventDrivenReading/Main.java diff --git a/samples/adslib/03_WriteByVariableName/Main.java b/samples/adslib/03_WriteByVariableName/Main.java new file mode 100644 index 0000000..c0a3297 --- /dev/null +++ b/samples/adslib/03_WriteByVariableName/Main.java @@ -0,0 +1,123 @@ +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 + * @author Matteo Cartieri + * + */ +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 + + // ./adslib_for_linux/build/AdsTool/AdsTool addroute + // --addr= --netid= --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(); + // addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE! + addr.setNetIdStringEx("172.18.236.194.1.1"); + 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. + AdsCallDllFunction.adsAddLocalRoute(addr.getNetId(), "192.168.59.215"); // 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"); + } + } +} diff --git a/samples/adslib/04_EventDrivenReading/AdsListener.java b/samples/adslib/04_EventDrivenReading/AdsListener.java new file mode 100644 index 0000000..0d125c1 --- /dev/null +++ b/samples/adslib/04_EventDrivenReading/AdsListener.java @@ -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"); + } +} diff --git a/samples/adslib/04_EventDrivenReading/Main.java b/samples/adslib/04_EventDrivenReading/Main.java new file mode 100644 index 0000000..292ea0f --- /dev/null +++ b/samples/adslib/04_EventDrivenReading/Main.java @@ -0,0 +1,133 @@ +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 + * @author Matteo Cartieri + * + */ +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 + + // ./adslib_for_linux/build/AdsTool/AdsTool addroute + // --addr= --netid= --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(); + // addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE! + addr.setNetIdStringEx("172.18.236.194.1.1"); + 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. + AdsCallDllFunction.adsAddLocalRoute(addr.getNetId(), "192.168.59.215"); // 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()); + } + } +} From bc4a02a5ab5abfd73c1daef1a3170984be33267f Mon Sep 17 00:00:00 2001 From: Matteo-Cartieri Date: Fri, 23 Aug 2024 11:46:14 +0200 Subject: [PATCH 2/5] correct netId and ip strings --- samples/adslib/03_WriteByVariableName/Main.java | 3 +-- samples/adslib/04_EventDrivenReading/Main.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/samples/adslib/03_WriteByVariableName/Main.java b/samples/adslib/03_WriteByVariableName/Main.java index c0a3297..b3082e8 100644 --- a/samples/adslib/03_WriteByVariableName/Main.java +++ b/samples/adslib/03_WriteByVariableName/Main.java @@ -37,7 +37,6 @@ public static void main(String[] args) { AmsAddr addr = new AmsAddr(); // addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE! - addr.setNetIdStringEx("172.18.236.194.1.1"); addr.setPort(851); // Uncomment and adjust if automatic AMS NetId deduction is @@ -50,7 +49,7 @@ public static void main(String[] args) { // 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. - AdsCallDllFunction.adsAddLocalRoute(addr.getNetId(), "192.168.59.215"); // TODO ADJUST THIS VALUE! + AdsCallDllFunction.adsAddLocalRoute(addr.getNetId(), "X.X.X.X"); // TODO ADJUST THIS VALUE! // Get handle by symbol name JNILong lengthReturn = new JNILong(); diff --git a/samples/adslib/04_EventDrivenReading/Main.java b/samples/adslib/04_EventDrivenReading/Main.java index 292ea0f..db2d7eb 100644 --- a/samples/adslib/04_EventDrivenReading/Main.java +++ b/samples/adslib/04_EventDrivenReading/Main.java @@ -37,7 +37,6 @@ public static void main(String[] args) { AmsAddr addr = new AmsAddr(); // addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE! - addr.setNetIdStringEx("172.18.236.194.1.1"); addr.setPort(851); // Uncomment and adjust if automatic AMS NetId deduction is @@ -50,7 +49,7 @@ public static void main(String[] args) { // 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. - AdsCallDllFunction.adsAddLocalRoute(addr.getNetId(), "192.168.59.215"); // TODO ADJUST THIS VALUE! + AdsCallDllFunction.adsAddLocalRoute(addr.getNetId(), "X.X.X.X"); // TODO ADJUST THIS VALUE! // Get handle by symbol name JNILong lengthReturn = new JNILong(); From 4013035b7343ba30325ff99cdfba3e9399dde42a Mon Sep 17 00:00:00 2001 From: Matteo-Cartieri Date: Fri, 23 Aug 2024 11:52:32 +0200 Subject: [PATCH 3/5] uncomment netId settings --- samples/adslib/03_WriteByVariableName/Main.java | 2 +- samples/adslib/04_EventDrivenReading/Main.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/adslib/03_WriteByVariableName/Main.java b/samples/adslib/03_WriteByVariableName/Main.java index b3082e8..4e35be7 100644 --- a/samples/adslib/03_WriteByVariableName/Main.java +++ b/samples/adslib/03_WriteByVariableName/Main.java @@ -36,7 +36,7 @@ public static void main(String[] args) { } AmsAddr addr = new AmsAddr(); - // addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE! + addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE! addr.setPort(851); // Uncomment and adjust if automatic AMS NetId deduction is diff --git a/samples/adslib/04_EventDrivenReading/Main.java b/samples/adslib/04_EventDrivenReading/Main.java index db2d7eb..5908562 100644 --- a/samples/adslib/04_EventDrivenReading/Main.java +++ b/samples/adslib/04_EventDrivenReading/Main.java @@ -36,7 +36,7 @@ public static void main(String[] args) { } AmsAddr addr = new AmsAddr(); - // addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE! + addr.setNetIdStringEx("X.X.X.X.1.1"); // TODO ADJUST THIS VALUE! addr.setPort(851); // Uncomment and adjust if automatic AMS NetId deduction is From 20f1143537d57457d0e38de4aa00aa7d0de548b4 Mon Sep 17 00:00:00 2001 From: Matteo-Cartieri Date: Mon, 26 Aug 2024 14:47:43 +0200 Subject: [PATCH 4/5] add comments for setup --- samples/adslib/03_WriteByVariableName/Main.java | 6 ++++-- samples/adslib/04_EventDrivenReading/Main.java | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/samples/adslib/03_WriteByVariableName/Main.java b/samples/adslib/03_WriteByVariableName/Main.java index 4e35be7..fa84000 100644 --- a/samples/adslib/03_WriteByVariableName/Main.java +++ b/samples/adslib/03_WriteByVariableName/Main.java @@ -10,8 +10,8 @@ /** * Sample - write PLC variable by its name * - * @author Fabio Richeri - * @author Matteo Cartieri + * @author Fabio Richeri (fabio.richeri@sinolo.it) + * @author Matteo Cartieri (matteo.cartieri02@gmail.com) * */ public class Main { @@ -36,6 +36,7 @@ public static void main(String[] args) { } 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); @@ -49,6 +50,7 @@ public static void main(String[] args) { // 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 diff --git a/samples/adslib/04_EventDrivenReading/Main.java b/samples/adslib/04_EventDrivenReading/Main.java index 5908562..35c53ba 100644 --- a/samples/adslib/04_EventDrivenReading/Main.java +++ b/samples/adslib/04_EventDrivenReading/Main.java @@ -10,8 +10,8 @@ /** * Sample - add event listener for PLC variable * - * @author Fabio Richeri - * @author Matteo Cartieri + * @author Fabio Richeri (fabio.richeri@sinolo.it) + * @author Matteo Cartieri (matteo.cartieri02@gmail.com) * */ public class Main { @@ -36,6 +36,7 @@ public static void main(String[] args) { } 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); @@ -49,6 +50,7 @@ public static void main(String[] args) { // 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 From 4b5452422cee05d9ae9ef7b274689682f57af48a Mon Sep 17 00:00:00 2001 From: Matteo-Cartieri Date: Mon, 26 Aug 2024 14:52:14 +0200 Subject: [PATCH 5/5] add comments for setup --- samples/adslib/03_WriteByVariableName/Main.java | 2 +- samples/adslib/04_EventDrivenReading/Main.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/adslib/03_WriteByVariableName/Main.java b/samples/adslib/03_WriteByVariableName/Main.java index fa84000..3be9031 100644 --- a/samples/adslib/03_WriteByVariableName/Main.java +++ b/samples/adslib/03_WriteByVariableName/Main.java @@ -17,7 +17,7 @@ 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 + // the program. Usually is plus .1.1 // ./adslib_for_linux/build/AdsTool/AdsTool addroute // --addr= --netid= --password= diff --git a/samples/adslib/04_EventDrivenReading/Main.java b/samples/adslib/04_EventDrivenReading/Main.java index 35c53ba..6fc0122 100644 --- a/samples/adslib/04_EventDrivenReading/Main.java +++ b/samples/adslib/04_EventDrivenReading/Main.java @@ -17,7 +17,7 @@ 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 + // the program. Usually is plus .1.1 // ./adslib_for_linux/build/AdsTool/AdsTool addroute // --addr= --netid= --password=