Post by ruobian on Analog Input Delay Timer
CODESYS Forge
talk
(Post)
Hello there, I am new here and in programming. I need help with the basics. I am trying to do what I mentioned in the title. I have an analog input. So I have a real or integer data type value. I want to delay it. TON and TOF only work with bool. I think there is a function block that has two inputs, 1 for real or int and 1 for bool. And if bool is true, it will give the output as real or int. I don't know but I need something like this. Actually, it is not exactly like that. In other words, it will not show the real value at the input at the output after a certain period of time. I want it to show the real value from 2 seconds ago continuously. The purpose of doing this is to compare the real value I received with the value from 2 seconds ago and find out whether it went up or down. I am using only FBD. Please help me with this. Thanks in advance.
Last updated: 2024-08-20
Post by mondinmr on First IO address of a CAADiagDeviceDefault.
CODESYS Forge
talk
(Post)
I have a device CAADiagDeviceDefault: IoConfig_Globals.Axis_A In our library, we perform introspection of the Etc_SlaveDiag. In that case, we have connectors, and by searching for them by address, I can find them in the IO mapping using the offset and size provided by EtherCAT. However, a Lenze i700 drive, instead of placing the IO mapping in the Etc_SlaveDiag device, places it in a sub-device CAADiagDeviceDefault. So, when I perform introspection, I cannot find the IO correspondences. Yet, in the CAADiagDeviceDefault, I do not find the connectors and cannot do the matching. Is there a way with a pointer or reference to a CAADiagDeviceDefault to obtain the address of the first input and the address of the first output? This is because we have our own motion library with many EtherCAT devices that automatically configure the mappings, but I can't manage to do so with the Lenze i700.
Last updated: 2024-08-22
Post by fless on Von SNMP auf IIoT wechseln
CODESYS Forge
talk
(Post)
Wie gesagt ich hatte noch keinen Kontakt mit SNMP. Um die Beispiele zu verstehen hier ein paar Tips: SetEngineId und CreateSNMPV3User sind Funktionsbausteine. Klicke rechts auf den Namen, Symbol suchen - Gehe zu Definition Dann sieht du entweder den Quelltext oder landest in der Bibliothek und kannst dir die Dokumentation ansehen. In deinen Fall siehst du den Quelltext. Die Funktionsbausteine sind in den Projekt POUs gespeichert weil das Projekt aus mehreren Applikationen besteht die alle diese FBs nutzen. sOID (drei Balken)oid → was wird da gemacht? In die Stringvariable sOID (String old ID?) wird der Inhalt von oid geschrieben. oid ist Member der Strukturvariable snmpVarBindings. Dem SNMP_SET Aufruf wird snmpVarBindings übergeben und geändert. Und da müsste doch irgendwo eine Verschlüsselung eingetragen werden oder? Beim Anlegen der SMNP-User wird ein Passwort vergeben, siehe CreateSNMPV3User. Dem SNMP_SET Aufruf wird nur der User übergeben, hier "readwrite". Die Bibliothek sucht sich die Einstellung des Users selbst.
Last updated: 2024-09-01
Post by julianramirez on ModbusFB write update
CODESYS Forge
talk
(Post)
Hello everyone, I am testing the ModbusFB library tcp server and so far I am able to create holding registers successfully, however, I am trying to identify after each write which registers got updated (i.e. function code, write value). I can even see the var udiNumWriteRequests, which increases with every write. I noticed that there is logging with the LogStatusInfo method. After I call it I am able to read in the console stuff that I want. Nevertheless, this is only available at the logs and is not easy to decode because it consists on several messages, I would like to know if there is a way for me to retrieve this information from the function itself with pointers or if there is any way to copy the logs messages (assuming that I can filter them with the LoggingOptions to only show what I need) inside the runtime code and not in the console. Thanks for your help :)
Last updated: 2024-09-16
Post by salvadegianluca on List files in a directory with SysDiropen And SysDirRead
CODESYS Forge
talk
(Post)
Good morning; I'm facing an issue that seems being caused by the library itself. I'm trying to create the list of all the files that are stored inside a psecific directory. Unluckily the first file is allways hidden. VAR CONSTANT arysEmptyArray:ARRAY[iArrayMinDimension..iArrayMAXDimension] OF STRING := [(iArrayMAXDimension - iArrayMinDimension)('')]; iArrayMinDimension:INT := 1; iArrayMAXDimension:INT := 99; END_VAR VAR_INPUT sDirectoryToInspect:STRING; sSearchFilter:STRING; END_VAR VAR_IN_OUT xCheckFileInsideDirectory:BOOL; END_VAR VAR arysListOfFoundFiles:ARRAY[iArrayMinDimension..iArrayMAXDimension] OF STRING; sNullString:STRING; iNullIndex:INT := 0; libInfoAboutThePath:DirInfo; libResultOfThePathMonitoring:CmpErrors.RTS_IEC_RESULT; libInstanceToMonitorThePath:CmpErrors.RTS_IEC_HANDLE; sEntityToSearch:STRING; dMaxEntityDimension:DINT := SIZEOF(sEntityToSearch); libFileInfo:DirInfo; sFilteredFileName:STRING; iIndexToScrollArrays:INT; END_VAR IF xCheckFileInsideDirectory THEN arysListOfFoundFiles:=arysEmptyArray; iIndexToScrollArrays:=iArrayMinDimension; libInstanceToMonitorThePath:= SysDirOpen(szDir:= sDirectoryToInspect,szDirEntry:=sNullString,diMaxDirEntry:= iNullIndex,pDirInfo:= ADR(libInfoAboutThePath),pResult:= ADR(libResultOfThePathMonitoring)); WHILE libResultOfThePathMonitoring = Errors.ERR_OK AND iIndexToScrollArrays <= iArrayMAXDimension DO sEntityToSearch:= ''; libResultOfThePathMonitoring:=SysDirRead(hDir:=libInstanceToMonitorThePath,szDirEntry:=sEntityToSearch,diMaxDirEntry:=dMaxEntityDimension,pDirInfo:=ADR(libFileInfo)); sFilteredFileName:= FUN_06_00_FindItemInString_0(sFilter:=sSearchFilter,sSource:=sEntityToSearch); IF sFilteredFileName <> '' THEN arysListOfFoundFiles[iIndexToScrollArrays]:=sFilteredFileName; iIndexToScrollArrays:=iIndexToScrollArrays + 1; END_IF IF libResultOfThePathMonitoring <> Errors.ERR_OK THEN libResultOfThePathMonitoring:= Errors.ERR_OK; END_IF END_WHILE libResultOfThePathMonitoring:=SysDirClose(hDir:= libInstanceToMonitorThePath); xCheckFileInsideDirectory:=FALSE; END_IF How is possible to solve this issue? Any known work around?
Last updated: 2024-09-17
Post by salvadegianluca on List files in a directory with SysDiropen And SysDirRead
CODESYS Forge
talk
(Post)
Good morning; I'm facing an issue that seems being caused by the library itself. I'm trying to create the list of all the files that are stored inside a psecific directory. Unluckily the first file is allways hidden. VAR CONSTANT arysEmptyArray:ARRAY[iArrayMinDimension..iArrayMAXDimension] OF STRING := [(iArrayMAXDimension - iArrayMinDimension)('')]; iArrayMinDimension:INT := 1; iArrayMAXDimension:INT := 99; END_VAR VAR_INPUT sDirectoryToInspect:STRING; sSearchFilter:STRING; END_VAR VAR_IN_OUT xCheckFileInsideDirectory:BOOL; END_VAR VAR arysListOfFoundFiles:ARRAY[iArrayMinDimension..iArrayMAXDimension] OF STRING; sNullString:STRING; iNullIndex:INT := 0; libInfoAboutThePath:DirInfo; libResultOfThePathMonitoring:CmpErrors.RTS_IEC_RESULT; libInstanceToMonitorThePath:CmpErrors.RTS_IEC_HANDLE; sEntityToSearch:STRING; dMaxEntityDimension:DINT := SIZEOF(sEntityToSearch); libFileInfo:DirInfo; sFilteredFileName:STRING; iIndexToScrollArrays:INT; END_VAR IF xCheckFileInsideDirectory THEN arysListOfFoundFiles:=arysEmptyArray; iIndexToScrollArrays:=iArrayMinDimension; libInstanceToMonitorThePath:= SysDirOpen(szDir:= sDirectoryToInspect,szDirEntry:=sNullString,diMaxDirEntry:= iNullIndex,pDirInfo:= ADR(libInfoAboutThePath),pResult:= ADR(libResultOfThePathMonitoring)); WHILE libResultOfThePathMonitoring = Errors.ERR_OK AND iIndexToScrollArrays <= iArrayMAXDimension DO sEntityToSearch:= ''; libResultOfThePathMonitoring:=SysDirRead(hDir:=libInstanceToMonitorThePath,szDirEntry:=sEntityToSearch,diMaxDirEntry:=dMaxEntityDimension,pDirInfo:=ADR(libFileInfo)); sFilteredFileName:= FUN_06_00_FindItemInString_0(sFilter:=sSearchFilter,sSource:=sEntityToSearch); IF sFilteredFileName <> '' THEN arysListOfFoundFiles[iIndexToScrollArrays]:=sFilteredFileName; iIndexToScrollArrays:=iIndexToScrollArrays + 1; END_IF IF libResultOfThePathMonitoring <> Errors.ERR_OK THEN libResultOfThePathMonitoring:= Errors.ERR_OK; END_IF END_WHILE libResultOfThePathMonitoring:=SysDirClose(hDir:= libInstanceToMonitorThePath); xCheckFileInsideDirectory:=FALSE; END_IF How is possible to solve this issue? Any known work around?
Last updated: 2024-09-17
Post by salvadegianluca on List files in a directory with SysDiropen And SysDirRead
CODESYS Forge
talk
(Post)
Good morning; I'm facing an issue that seems being caused by the library itself. I'm trying to create the list of all the files that are stored inside a psecific directory. Unluckily the first file is allways hidden. VAR CONSTANT arysEmptyArray:ARRAY[iArrayMinDimension..iArrayMAXDimension] OF STRING := [(iArrayMAXDimension - iArrayMinDimension)('')]; iArrayMinDimension:INT := 1; iArrayMAXDimension:INT := 99; END_VAR VAR_INPUT sDirectoryToInspect:STRING; sSearchFilter:STRING; END_VAR VAR_IN_OUT xCheckFileInsideDirectory:BOOL; END_VAR VAR arysListOfFoundFiles:ARRAY[iArrayMinDimension..iArrayMAXDimension] OF STRING; sNullString:STRING; iNullIndex:INT := 0; libInfoAboutThePath:DirInfo; libResultOfThePathMonitoring:CmpErrors.RTS_IEC_RESULT; libInstanceToMonitorThePath:CmpErrors.RTS_IEC_HANDLE; sEntityToSearch:STRING; dMaxEntityDimension:DINT := SIZEOF(sEntityToSearch); libFileInfo:DirInfo; sFilteredFileName:STRING; iIndexToScrollArrays:INT; END_VAR IF xCheckFileInsideDirectory THEN arysListOfFoundFiles:=arysEmptyArray; iIndexToScrollArrays:=iArrayMinDimension; libInstanceToMonitorThePath:= SysDirOpen(szDir:= sDirectoryToInspect,szDirEntry:=sNullString,diMaxDirEntry:= iNullIndex,pDirInfo:= ADR(libInfoAboutThePath),pResult:= ADR(libResultOfThePathMonitoring)); WHILE libResultOfThePathMonitoring = Errors.ERR_OK AND iIndexToScrollArrays <= iArrayMAXDimension DO sEntityToSearch:= ''; libResultOfThePathMonitoring:=SysDirRead(hDir:=libInstanceToMonitorThePath,szDirEntry:=sEntityToSearch,diMaxDirEntry:=dMaxEntityDimension,pDirInfo:=ADR(libFileInfo)); sFilteredFileName:= FUN_06_00_FindItemInString_0(sFilter:=sSearchFilter,sSource:=sEntityToSearch); IF sFilteredFileName <> '' THEN arysListOfFoundFiles[iIndexToScrollArrays]:=sFilteredFileName; iIndexToScrollArrays:=iIndexToScrollArrays + 1; END_IF IF libResultOfThePathMonitoring <> Errors.ERR_OK THEN libResultOfThePathMonitoring:= Errors.ERR_OK; END_IF END_WHILE libResultOfThePathMonitoring:=SysDirClose(hDir:= libInstanceToMonitorThePath); xCheckFileInsideDirectory:=FALSE; END_IF How is possible to solve this issue? Any known work around?
Last updated: 2024-09-17
Post by salvadegianluca on List files in a directory with SysDiropen And SysDirRead
CODESYS Forge
talk
(Post)
Good morning; I'm facing an issue that seems being caused by the library itself. I'm trying to create the list of all the files that are stored inside a psecific directory. Unluckily the first file is allways hidden. VAR CONSTANT arysEmptyArray:ARRAY[iArrayMinDimension..iArrayMAXDimension] OF STRING := [(iArrayMAXDimension - iArrayMinDimension)('')]; iArrayMinDimension:INT := 1; iArrayMAXDimension:INT := 99; END_VAR VAR_INPUT sDirectoryToInspect:STRING; sSearchFilter:STRING; END_VAR VAR_IN_OUT xCheckFileInsideDirectory:BOOL; END_VAR VAR arysListOfFoundFiles:ARRAY[iArrayMinDimension..iArrayMAXDimension] OF STRING; sNullString:STRING; iNullIndex:INT := 0; libInfoAboutThePath:DirInfo; libResultOfThePathMonitoring:CmpErrors.RTS_IEC_RESULT; libInstanceToMonitorThePath:CmpErrors.RTS_IEC_HANDLE; sEntityToSearch:STRING; dMaxEntityDimension:DINT := SIZEOF(sEntityToSearch); libFileInfo:DirInfo; sFilteredFileName:STRING; iIndexToScrollArrays:INT; END_VAR IF xCheckFileInsideDirectory THEN arysListOfFoundFiles:=arysEmptyArray; iIndexToScrollArrays:=iArrayMinDimension; libInstanceToMonitorThePath:= SysDirOpen(szDir:= sDirectoryToInspect,szDirEntry:=sNullString,diMaxDirEntry:= iNullIndex,pDirInfo:= ADR(libInfoAboutThePath),pResult:= ADR(libResultOfThePathMonitoring)); WHILE libResultOfThePathMonitoring = Errors.ERR_OK AND iIndexToScrollArrays <= iArrayMAXDimension DO sEntityToSearch:= ''; libResultOfThePathMonitoring:=SysDirRead(hDir:=libInstanceToMonitorThePath,szDirEntry:=sEntityToSearch,diMaxDirEntry:=dMaxEntityDimension,pDirInfo:=ADR(libFileInfo)); sFilteredFileName:= FUN_06_00_FindItemInString_0(sFilter:=sSearchFilter,sSource:=sEntityToSearch); IF sFilteredFileName <> '' THEN arysListOfFoundFiles[iIndexToScrollArrays]:=sFilteredFileName; iIndexToScrollArrays:=iIndexToScrollArrays + 1; END_IF IF libResultOfThePathMonitoring <> Errors.ERR_OK THEN libResultOfThePathMonitoring:= Errors.ERR_OK; END_IF END_WHILE libResultOfThePathMonitoring:=SysDirClose(hDir:= libInstanceToMonitorThePath); xCheckFileInsideDirectory:=FALSE; END_IF How is possible to solve this issue? Any known work around?
Last updated: 2024-09-17
Post by lbartik on J1939 TX/RX PDU1
CODESYS Forge
talk
(Post)
Is it possible to transmit a PDU1 PGN using the J1939 manager and local device? What if I need to transmit a PGN RQST via 0xEA00 (PGN 59904)? How would I do this P2P (Destination < 0xFF) or broadcast (Destination 0xFF)? I don't think this is possible for any destination type. I don't think it's possible to receive broadcast PDU1 messages either. For example, an address claim PGN 60928 (0x18EEFF80) is addressed to all nodes (0xFF) and not any specific local device so it will be filtered out. These are major oversights in the IoDrvJ1939 library to not support every PDU1 RX/TX scenario. IoDrvJ1939 supported scenario: 1. Receive (RX) PDU1 (P2P) destination-specific (PDU-specific < 255) to local device with matching address IoDrvJ1939 unsupported scenarios: 1. Receive (RX) PDU1 (P2P) global (PDU-specific = 255) 2. Transmit (TX) PDU1 (P2P) global (PDU-specific = 255) 3. Transmit (TX) PDU1 (P2P) destination-specific (PDU-specific < 255)
Last updated: 2024-09-23
Post by bjarne-pagaard on Communication between applications on same device/controller/runtime (Win RTE 3.5.20.20)
CODESYS Forge
talk
(Post)
Thanks for this - I have now been looking in to just having an extra (non-RTE) runtime on the same machine, as you suggest. I will probably proceed this way. Even though it still seems very odd to me, that variable exchange to a different runtime is easier than between applications on the same controller. There will be some fun with the licensing, it seems. Does anyone know if it is possible to specify which license container/specific license the runtime is going to use at runtime. Let's say I have two available licenses with different resources available, for example one license allows multicore and multiple EtherCAT channels, but not many visu tags (for the RTE). Another with less resources but a lot of visu tags (for the Visu controller). Let's say the program in one of the controllers could be fully licensed by either of the two available licenses, but picks the 'largest' first. A bit later, the larger application starts, but is left with the smaller license.. How can I make sure that the 2 runtimes select the right license at startup?
Last updated: 2024-10-01
Post by egau on Hard shutdown: no code on device after power on
CODESYS Forge
talk
(Post)
This explanation aligns with the issues we’re experiencing with our machines. The scenario I described is happening with one of them (let’s call it Machine A). This machine is identical to another one (Machine B), except for some custom code that facilitates communication with an external Beckhoff PLC for MES integration in the production line. Machine B has been powered on and off daily for at least three months and has never had this problem. Given that, I highly doubt the MES custom code is the cause of the code corruption. This being said, your explanation does seem plausible. However, if faulty EtherCAT cables were the issue, why wouldn't the error occur during normal operation? Why would bad cables only cause problems during a hard shutdown? One last question: When you encountered this behavior, did you see a similar error in your logs? i.e, an "AccessViolation" exception in the EtherCAT Task?
Last updated: 2024-10-03
Post by codesysbeginner on Eaton XC303 - USB Mounting / Trend manager
CODESYS Forge
talk
(Post)
Hi, For a project I am using the trendmanager functionality, I changed the placeholder filepath to which the SQL database is saved to: home/disk_usb, $trend$. Which only works as long as the usb was mounted to the PLC at boot. However, I'd like to be able to switch the USB's out if they break or for data analysis. However when a new (or the same) USB is plugged back in the shortcut doens't exist on the device anymore. Also in the device directory under root/mnt/ a new folder appears SDB1 in addition to SDA1 to which the Trendmanager was originally writing. The SDA1 folder is empty/unreachable while the new SDB1 folder has the contents of the USB drive. I tried disabling the trendmanger while unplugging the USB's however this doesn't work. My question, how do I make it so that when I plug a USB drive back in, it will be mounted to SDA1 instead of SDB1? Kind Regards
Last updated: 2024-10-09
Post by struccc on Bibliothek: floatingpointutils
CODESYS Forge
talk
(Post)
The issue s the byte order typically in this case. Can be especially problematic with floating point numbers - even more tricky if transferred with a word based protocol. It is a peasant way to try out the alternatives, dword order can be a-b-c-d, b-a-d-c, c-d-a-b, d-c-b-a where a is the most significant, d is the least significant byte. So all you need is to swap the bytes in your dword, until you get the expected result. If you don't want to mess writing code for this, I'd recommend CAA_Memory library for that: MEM.ReverseBYTEsInDWORD and MEM.ReverseWORDsInDWORD functions would definitively do the trick. Otherwise, can do like this: VAR dwIn : DWORD := 16#11223344; dwOut : DWORD; rOut : REAL; pIN : POINTER TO BYTE; pOUT : POINTER TO BYTE; END_VAR pIN := ADR(dwIn); //pOUt := ADR(dwOut); pOUt := ADR(rOut); pOut[0] := pIN[3]; pOut[1] := pIN[2]; pOut[2] := pIN[1]; pOut[3] := pIN[0]; Ugly, but does the job...
Last updated: 2024-11-19
Post by etienneneu on Trend x-axis description incorrect display
CODESYS Forge
talk
(Post)
Hello everyone, maybe someone can help me with the following problem. I wanted to insert a trend element in my visualization. The problem is that I have set fixed fonts with a scaling of 1.5 for the individual languages via the visualization manager. This setting means that I have this scaling in every element, which has been quite comfortable so far because I didn't have to set the individual properties in the text fields. But in the trend element, even if I select other font sizes or fonts in the element itself, this font is also overwritten and I get a label on the x-axis that is no longer displayed correctly. Is there a way to prevent the overwriting of the font properties in this element or similar behavior? I mean, I could change the font size of each element manually, but the Visu app is a bit larger and it would be easier to have another option. Best regards Etienne
Last updated: 2024-11-28
Post by sean-barton on Ambiguous namespace in library dependencies
CODESYS Forge
talk
(Post)
I am trying to install the MQTT Client SL in an existing project I have been working on for years. After adding the library to the project, and without adding any other code, upon building I get a C0180: Ambiguous namespace 'MBM' error between the memory block manager (MBM) in the NetBaseSrv dependency of the MQTT Client SL library and the memory block manager (MBM) in the CAA CanL2 dependency of the 3S CANopen stack library. I have tried: * setting "Only allow qualified access to all identifiers." in the properties for both the parent libraries. * deleting the 3S CANopen stack library. Upon (re)building the error simply points to another conflicting library - there are many. * deleting the Library Manager and rebuilding it. * adding the memory block manager library (used in the NetBaseSrv) manually and changing its namespace to MBM3S. None of the above allow me to access the MQTT library through its namespace (MQTT). Adding the memory block manager manually removes the C0180 error, but the MQTT library is not accessible - i.e. mqttClient : MQTT.MQTTClient; highlights the mqttClient as "Identifier 'MQTT.MQTTClient' not defined". Is there anything else I can try?
Last updated: 2025-01-09
Post by mubeta on Strange problem with the ‘MC_SetPosition’ function
CODESYS Forge
talk
(Post)
Hi gseidel, before moving to HW implementation, I had created the same program in simulation mode with virtual drives and, as far as I remember, everything worked fine simulating process and the few useful inputs. So it does not seem to be a SoftMotion library problem, but rather a problem with dynamics or physical axis adjustments. What escapes me, however, is the fact that this function is supposed to perform a position shift virtually, in fact without interfering with the axis itself, thus independent of its adjustments. MC_SetPosition() is not a homing function, in fact it is clearly intended to be executed on the fly with the axis moving. Now I'll see if I can reduce the program, although I don't like it very much. In my life I have learned that problem searches should be done on the part, and not in a more or less similar way.
Last updated: 2025-01-10
Post by timvh on STRING conversions to DWORD
CODESYS Forge
talk
(Post)
I guess that the printer expects to receive an array of byte values. So where it is described that it expects to receive: Hercules String : 1B4F513030311B7532626C61636B04 it actually expects to receive an array of bytes with the values 1B,4F,51,30,30, etc. So what you can do is create an array of bytes and assign the byte value to each item in the array: VAR abyToSend : ARRAY[0..99] OF BYTE; END_VAR abyToSend[0] := 16#1B; // ASCII Escape character, hexadecimal representation uses 16# as prefix abyToSend[1] := 16#4F; // ASCII 'O' abyToSend[2] := 16#51; // ASCII 'Q' abyToSend[3] := 16#30; // ASCII '0' // you can do the rest yourself // maybe could be created a lot smarter, but gives you an indication how to handle this. Then with the serial communication (or TCP/IP?) you can send a message with the reference to the array (abyToSend) and the number of bytes to send (15 bytes for the string you gave as example).
Last updated: 2025-02-02
Post by timvh on Device diagnosis ( EtherCAT IO card )
CODESYS Forge
talk
(Post)
You can get the state by just using the name of your node (same name as in device tree): VAR etcState: IoDrvEthercatDriverLib.ETC_SLAVE_STATE; END_VAR etcState := EJ1100.wState; Alternatively, you can iterate through the device tree to get the status of all (Ethercat) nodes. See here an example (no guarantee it works, just give as suggestion): PROGRAM P_IO_State VAR CONSTANT uiMAX_NR_OF_TERMINALS : UINT := 100; END_VAR VAR // general device diagnosis // can only be used when the Device - PLC Settings - Advanced settings - enable diagnosis for devices is enabled // this will add the DED library coupler: DED.INode; terminal: DED.INode; aDeviceState: ARRAY[0..uiMAX_NR_OF_TERMINALS - 1] OF DED.DEVICE_STATE; uiTerminalCount : UINT; uiIndex : UINT; // for each terminal check if it implements device diagnostics xQueryResult: BOOL; itfDevice : DED.IDevice2; xDiagAvailable: BOOL; eError: DED.ERROR; xEverythingOK: BOOL; END_VAR uiTerminalCount := 0; // start at the top of the device tree with the first EtherCAT coupler coupler := EtherCAT_Master.FirstChildNode; WHILE coupler <> 0 DO // for each coupler that is found start at the first terminal terminal := coupler.FirstChildNode; WHILE terminal <> 0 AND uiTerminalCount < uiMAX_NR_OF_TERMINALS - 1 DO // for each terminal that is found get the status through the device diagnosis interface xQueryResult := __QUERYINTERFACE(terminal, itfDevice); IF xQueryResult THEN aDeviceState[uiTerminalCount] := itfDevice.GetDeviceState(xDiagnosisInfoAvailable => xDiagAvailable, eError => eError); uiTerminalCount := uiTerminalCount + 1; END_IF terminal := terminal.NextSiblingNode; END_WHILE coupler := coupler.NextSiblingNode; END_WHILE uiIndex := 0; xEverythingOK := TRUE; WHILE uiIndex < uiTerminalCount DO IF aDeviceState[uiIndex] <> DED.DEVICE_STATE.RUNNING THEN xEverythingOK := FALSE; EXIT; END_IF uiIndex := uiIndex + 1; END_WHILE
Last updated: 2025-02-06
Post by george32 on TCP Server
CODESYS Forge
talk
(Post)
Thank you for your advice Rinie, I have tried to follow this example but found one problem.When I disconnect with Hercules the system does not acknowledge the lost of its connection this could result in critical errors. Because of this error I am trying to implement the Syssocket library. With this library I am having a problem which I could not solve. I have the following code: ip_adres : STRING :='0.0.0.0'; port : WORD := 5000; iStep : INT := 1; // Socket information Socket_handler : SysSocket_Interfaces.RTS_IEC_HANDLE; Socket_handler_result : SysSocket_Interfaces.RTS_IEC_RESULT; Socket_adress : SysSocket_Interfaces.SOCKADDRESS; Addres_Convert : SysSocket_Implementation.RTS_IEC_RESULT; // Bind information Bind_handler : SysSocket_Interfaces.RTS_IEC_RESULT; // Listener Information Listener_handler : SysSocket_Interfaces.RTS_IEC_RESULT; Addres_Convert := SysSocket_Implementation.SysSockInetAddr(szIPAddress:= ip_adres,pInAddr:= ADR(Socket_adress.sin_addr)); Socket_adress.sin_family:= SysSocket_Interfaces.SOCKET_AF_INET; Socket_adress.sin_port := SysSocket_Implementation.SysSockHtons(usHost:= port); CASE iStep OF 1: // Create Socket Socket_handler :=SysSockCreate( iAddressFamily :=SysSocket_Interfaces.SOCKET_AF_INET, diType:=SysSocket_Interfaces.SOCKET_STREAM, diProtocol:=SysSocket_Interfaces.SOCKET_IPPROTO_TCP, pResult:=ADR(Socket_handler_result)); IF Socket_handler = SysSocket_Interfaces.RTS_INVALID_HANDLE THEN iStep := 1; ELSE iStep := 2; END_IF 2: Bind_handler := SysSocket_Implementation.SysSockBind( hSocket:=Socket_handler, pSockAddr :=ADR(Socket_adress), diSockAddrSize:=SIZEOF(Socket_adress) ); 3: Listener_handler := SysSocket_Implementation.SysSockListen( hSocket :=Socket_handler, diMaxConnections :=1); END_CASE When I am trying to get this working, the SysSockBind function gives a value of 16#207 which means adress already in use. I find this weird because of the IP-adress of 0.0.0.0. I think I am converting the Ip-adress in the wrong way, but the code does not give a error arround this. So therefore I cannot find the solution to this problem. I hope someone could help me with this problem. Thanks in advance George
Last updated: 2025-02-20
Post by fabiodasilveira on PLC Shell commands via ST Code
CODESYS Forge
talk
(Post)
Hello Everybody, I have created a project for an Eaton XC303 that sends lots of data to a router via UDP. It works fine. However, when there is more than one product connected to the router, then it is necessary to change the IP address of the Ethernet port 0, from e.g. 192.168.2.11 to 192.168.2.12 (second product). It is easily done via PLC Shell (setipaddr 0 192.168.2.12), but the people in production is struggling with the PLC Shell commands and I would like to create a Visualization page that will hide that. I used the instruction: eChangeIPResult:= SysSockSetIPAddress(strEthernetPort, strIPAddress); and it works, until the PLC resets. I already read some posts and it appears that I need to stop the Ethernet 0 port and Reconfigure it, but I am really struggling to find the right way to do it. Any help will be much appreciated.
Last updated: 2025-02-28
Post by pernockham on Inheritence of struct,
CODESYS Forge
talk
(Post)
Im looking for a way to define predefined version of the same structures through "extends"/inheritance. What I want to do is best shown with an example: TYPE log_item_val_type : ( BOOL_ := 0, INT_, REAL_, STRING_ ); END_TYPE TYPE LOG_DATA_BASE STRUCT val_type : log_item_val_type; (* value, name etc *) ENDSTRUCT ENDTYPE (* this/below is not possible as I understand from the compiler?? *) TYPE LOG_DATA_BOOL extends LOG_DATA_BASE : STRUCT val_type : log_item_val_type := log_item_val_type.BOOL_; END_STRUCT END_TYPE TYPE LOG_DATA_INT extends LOG_DATA_BASE : STRUCT val_type : log_item_val_type := log_item_val_type.INT_; END_STRUCT END_TYPE etc. for LOG_DATA_REAL and ..STRING. The system will not allow me to "re-define" "val_type" however. Instead I must do the work-around of defining four different types with all fields individually defined. The benefit if I could extend the base item would be that Im (more) sure the structures are identical. In usage I can call in a specific type rather use the base type and assign which type. Usage by pointer/ref to log_data_base would also be easier.. (* Usage: *) log_data : log_data_int := (name, value etc.) (* Instead of: *) log_data : log_data_base := (name, value, val_type).. Is this possible to achieve in some way that I have missed?
Last updated: 2025-03-05
Post by imdatatas on Auto Declare window disappears by itself in the Ladder editor
CODESYS Forge
talk
(Post)
Hello Everyone, The "Auto Declare" window disappears by itself in the Ladder editor. For example, a new function block is wanted to be added to the Ladder editor. (For example; MC_Jog block and instance name will be fbMcJog). To do this, "Empty box with EN/ENO" is added to the ladder line from the Toolbox on the right and when you type MC_Jog in the empty box and press enter, normally the "Auto Declare" window appears and you are expected to be asked to write the instance name here. However, this "Auto Declare" window closes itself immediately, it does not wait for the user to enter a value or close the window. I often encounter this situation in many IDE versions. Does this seem like a bug? If anyone has encountered a similar problem while creating a new program name, function or function block instance name regarding the "Auto Declare" window and knows a solution, I would be glad if you could share it. Best wishes Imdat
Last updated: 2025-03-06
Post by ojz0r on Assignment Efficiency - Repetitive Assignment vs IF statement
CODESYS Forge
talk
(Post)
Its important that you know the difference between the two. Example 1: Coils[0] := Coils[0] OR (Buttons[0] AND Sensors[0] > 6); In this case the statements will be evaluated every scan and result in either true or false for Coils[0]. Example 2: IF NOT Coils[0] AND Buttons[0] AND (Sensors[0] > 6) THEN Coils[0] := TRUE; END_IF In this example Coils[0] will latch the result in a true evaluation, if you want it to behave the same way as example 1 then you need to do it like example 3 below: IF NOT Coils[0] AND Buttons[0] AND (Sensors[0] > 6) THEN Coils[0] := TRUE; ELSE Coils[0] := FALSE; END_IF However back to the real question. There is no problem using either example 1 or example 3, if im not requiring a latch i usually go with example 1 as it is more compact.
Last updated: 2025-03-07
Post by pikebuster on Help for a newbie
CODESYS Forge
talk
(Post)
Can somebody help me with this? I have problem with the button! This task must be solved using Sequential Function Chart (SFC), IEC 61131-3. TASK Create an SFC program to control a traffic light at an intersection. Description: You will program a traffic light that has three phases: Green, Yellow, and Red. The traffic light must follow these rules: Green light is on for 10 seconds. Yellow light is on for 3 seconds. Red light is on for 10 seconds. If the pedestrian button is pressed, the system must keep the red light on for 20 seconds during the next cycle. After the pedestrian has “crossed,” the system should return to its normal cycle. Basic Steps: Initialization: Start by setting the traffic light to Red. Green Phase: After 10 seconds, switch to Green. Yellow Phase: After 10 seconds in the Green phase, switch to Yellow. Red Phase: After 3 seconds in the Yellow phase, switch back to Red. Loop: Repeat the cycle. Use, for example, lamp symbols in the visualization module to simulate the traffic light. You may also add a simple pedestrian light if desired.
Last updated: 2025-03-11
Post by egau on Enable and Disable Project IO programmatically
CODESYS Forge
talk
(Post)
Hi @eschwellinger, I tried this with Modbus COM slaves. I was able to disable them (slave becomes greyed out in the device tree), but the DED.Reconfigure "eError" output shows "NOT_SUPPORTED". After this, when I tried to re-enable the slave, it did not work (device stayed greyed out in the device tree), and the DED.Reconfigure "eError" output also showed "NOT_SUPPORTED". Is there something to do about this, or the device just doesn't support reconfiguration? P.S: I tried this running locally on my computer (not in simulation mode). So of course I was not physically connected to the devices. I have two similar projects, but one of them doesn't have the Modbus_COM devices. I know I can "Exclude from build" the devices for that project, but I would really prefer not to do this if possible. I would prefer to dynamically toggle a configuration variable that would enable or disable the slaves.
Last updated: 2025-03-14
To search for an exact phrase, put it in quotes. Example: "getting started docs"
To exclude a word or phrase, put a dash in front of it. Example: docs -help
To search on specific fields, use these field names instead of a general text search. You can group with AND or OR.