Post by gseidel on CAM Motion Recover after STO
CODESYS Forge
talk
(Post)
Dear Mr. Kolev, I'm not sure I understood correctly. But this is my take on your question: When the STO of the slave is triggered, store the current master position (e.g. 225 units) After the reset of the slave error, call MC_SetPosition on the virtual master and reset it to the stored position (225 units) Optionally, before MC_CamIn is restartet, move the slave back to the slave position corresponding to the stored master position. (If you do this, no ramping in will be necessary) Restart MC_CamIn, with absolute master position and absolute slave position. Choose the StartMode that is appropriate for your machine. Best regards, Georg Seidel
Last updated: 2026-02-16
Post by poliautomacao on Absolute movement controlled by an external encoder.
CODESYS Forge
talk
(Post)
Hello, I made this configuration, I'm moving the encoder value to SM_Driver_PosControl.in.wActPosition. When I make the absolute movement of my PosControl axis, my physical drive axis rotates perfectly, but I noticed that the movement is not followed by the encoder. That is, if I hold the encoder and keep it in position 0, the PosControl axis makes the absolute movement of 314 mm and stops, which is strange because the encoder is at 0. Theoretically, the PosControl axis should accelerate to try to compensate for the movement error. I haven't yet achieved perfect functionality.
Last updated: 2026-03-24
Post by egr99 on Modbus TCP Server connection is ESTABLISHED but all holding registers are value 0?
CODESYS Forge
talk
(Post)
You're absolutely right. Sorry for that. In the meantime I wrote a Function block to handle the reads and writes to the different attached RTU-devices. It processes the parameter like (str_Modbus:=(usiSlave:=1, uiFC:=5, uiLEN:=1, uiOFFSET:=0, uiInterval:=500)) and the corresponding output, waits for the response and processes next request in a 5-state procedure. It's working for 2 gateways (stable without errors, although error recovery is included). But nevertheless it should be possible with the Channel definitions of Codesys. Much easier to maintain :)
Last updated: 2026-04-08
Post by vstrom on Codesys v3.5.22.10 - Fail to create a project Archive
CODESYS Forge
talk
(Post)
Hi to all, I've created a project using the File->New Project-> Standard Project command. Then I've add the object "Visualization Manager" and then tried to create a project archive (File->Project Archive->Save Archive), but it fails with the error "Access to the path 'C:\Program Files\CODESYS 3.5.22.10\CODESYS\Common\3hxi4iod.put' is denied". The idicated file don't exist. First time of use of the new Codesys versionĂą, I've reinstalled the developement software but nothing change. If I don't add the Visualization part, the archive is created, it's seems to be a problem with the HMI part. Any ideas? Thanks
Last updated: 2026-04-22
Post by jorenbeyl on library inside library
CODESYS Forge
talk
(Post)
I am currently developing a library that contains real‑time data. To handle this real‑time data, I am using additional libraries called SysTime and SysTypes Interfaces. When I compile my library on its own, no errors occur. However, when I use this library in a project and compile the project, I get an error indicating that the SysTime data type is not recognized. This happens even though the SysTime library is visible as a dependency under my library. Does anyone know how to correctly include a library within another library so that the project recognizes the sub‑library without causing compilation errors?
Last updated: 2026-04-23
Post by cd-tt on cannot connect ot linux runtime: device does not answer the scanrequest
CODESYS Forge
talk
(Post)
I have the following setup: Proxmox PC with a debian 13 VM running CODESYS Control Linux SL and Edge Gateway. Installation method was through the Deploy Control SL and went rather smoothly. In my Device Tab I find the gateway and when scanning my network I also find my runtime. I want to connect and get promted that I should add a user. After setting up the user I get an error saying, that the device is not responding my scanrequest. Deploy Control SL Operation saying everythings up and running. I can confirm that from the terminal on the VM with "systemctl status codesyscontrol" and "systemctl status codesysgateway". I am running out of ideas how to fix that issue. Can anybody help? Screenshots attached.
Last updated: 2026-06-11
Post by dmb-fan on Hilscher cards CoDeSys Control RTE
CODESYS Forge
talk
(Post)
Now it sounds not so good anymore... I don't get it. The help-site is a joke. Is there anywhere manuals or docs? Or maybe somebody show me a working CODESYSControl.cfg with CIFX50E-DP and CIFX50E-CO ? Are there 1 or 2 entry for componentnes in the gui? Is slot no. this no. in the gui or any other number? What is the Device-No. ? When I tried Win hang, or PLC hang. Log not writing or not telling me the problem. Is 2026 and for this basic things I have to do trial and error?
Last updated: 2026-10-20
Post by yannickasselin on MQTT QoS 1 & 2
CODESYS Forge
talk
(Post)
Hello, After some more tests, here is what I found out. It seems we have to increase the uiKeepAlive and tPingInterval parameters. If I increase the uiKeepAlive value to 60s and the tPingInterval to 30s, then if I disconnect the ethernet cable from Codesys and publish some messages to which Codesys subscribes to and then reconnect within 30s, I will get the messages. If I don't reconnect the cable within 30s (ping interval), the client goes in error with "ACKNOWLEDGE_TIMEOUT". When this happens, it will not automatically reconnect after reconnecting the cable. I have to disable and re-enable the client but I will not get the published messages. I need to do more tests because there are a lot of weird things happening when playing with the ping interval and the keep alive. It is not clear to me what does what. I even ended up not receiving messages anymore, even if I disabled and re-enabled the mqtt client. The client did not give any error. The only way I was able to get messages again was by modifying my client ID. After that, if I try to re-use one of the old client IDs, nothing works (publish, subscribe) and I get a TCP_INIT_ERROR and sometimes a TCP_READ_ERROR. I need more explanation/documentation about these weird behaviors. Maybe it is the way I use it, maybe it is related to the broker (I am using Mosquitto with default parameters). When using a Node-Red client, everything works perfectly. I am trying to achieve the same behavior with Codesys but it seems impossible so far.
Last updated: 2024-10-30
Post by s1ack on Wago PFC200 Ethernet / IoDrvEthernet Issue?
CODESYS Forge
talk
(Post)
CODESYS Control for PFC200 4.13.00 CODESYS IIoT Libraries SL 1.11.0.0 Application Based License: CODESYS Control Standard M I have (2) projects with similar code base and both using Wago PFC200. On the second project I am seeing 2 things that I have not been able to resolve: 1) Errors in the log under the Ethernet Item: IoDrvEthernet: [PCI\E1Q51CE62] Could not be found on target! Please check the Ethernet settings. 2) Exception for CPU Load. "Processorload watchdog: plcload=100, maxplcload=95" I have slowed down cyclic tasks on this project, even though on the first project there is actually more code - and it does not exhibit this behavior. In looking at the CPU loading via Linux 'TOP' command there appears to be 20% idle. So plenty of headroom (my opinion). In an effort to troubleshoot I have duplicated the target hardware on my bench. It ran overnight without a CPU load exception. On the test system, I have tried (3) version of the ethernet device. 3.5.16.0 3.5.17.0 and 4.2.0.0 Presently the log does not show the error, but status says the module reports an error. I really do not know if this issue is related to the CPU load exception. The issue does not appear to effect ethernet communications (ModbusTCP or SNMP or Webvisu or PuTTy into Linux Shell). On my test bench I have ModbusTCP slave simulators for all ModbusTCP slaves, but only (1) of the (5) SNMP devices present.
Last updated: 2025-01-21
Post by trusty-squire on SysProcessCreate2 on Linux runtime
CODESYS Forge
talk
(Post)
Hi, I'm trying to launch a continuously running python script from Codesys and monitor the script status inside the Codesys runtime (running on a Linux enviroment). For now I'm testing with the below to emulate a continuously running Python script: #test.py i = 0 while True: i += 1 I'm able to successfully run the script using SysProcessExecuteCommand2 (I can see the Python process running in the task manager). However, this "freezes" the Codesys execution of the task - it sits on that command and will not continue until the Python script ends. I've proven this works by using the task monitor to kill the process, then Codesys continues on happily through the task. What I want to do is use SysProcessCreate2 to set up the Python script as a background task and monitor the process using SysProcessGetState. This always results in the error "ERR_OPERATION_DENIED". I know that I'm able to execute commands (as above), so my config should be correct. Is SysProcessCreate2 functional on a Linux environment? Is there something in the config file I'm missing? Here's my "working" code that uses SysProcessExecuteCommand2: VAR bTest : BOOL; sCommand : STRING := '/usr/bin/python3 /var/opt/codesys/PlcLogic/Application/test.py'; refCommand : REFERENCE TO STRING REF= sCommand; sOutput : STRING; refOutput : REFERENCE TO STRING REF= sOutput; result : RTS_IEC_RESULT; END_VAR IF bTest THEN SysProcessExecuteCommand2( pszCommand:= refCommand, pszStdOut:= refOutput, udiStdOutLen:= SIZEOF(sOutput), pResult:= ADR(result) ); bTest:= FALSE; END_IF And here's the code that always results in the ERR_OPERATION_DENIED error: VAR bTest : BOOL; sApp : STRING := '/usr/bin/python3'; sCommand : STRING := '/var/opt/codesys/PlcLogic/Application/test.py'; refApp : REFERENCE TO STRING REF= sApp; refCommand : REFERENCE TO STRING REF= sCommand; hResult : SysProcess.RTS_IEC_RESULT; hHandle : SysProcess.RTS_IEC_HANDLE; END_VAR IF bTest THEN hHandle := SysProcessCreate2( pszApplication:= refApp, pszCommandLine:= refCommand, ulFlags:=SYSPROCESS_CREATEFLAG_HIDDEN, pResult:= ADR(hResult) ); bTest:= FALSE; END_IF Here's the relevant section from the config file at /etc/codesyscontrol/CODESYSControl.cfg: [SysProcess] Command=AllowAll Appreciate any support or ideas. Thanks!
Last updated: 2025-03-16
Post by timvh on From target start Win OnScreenKeyboard
CODESYS Forge
talk
(Post)
Check the CODESYS log. Do you see something like this?: 2026-10-28T14:27:50.602Z: Cmp=SysFile, Class=2, Error=39, Info=4, pszInfo=!!!! Access denied to 'C:/Windows/System32/osk.exe' due to ForceIecFilePath 2026-10-28T14:27:50.602Z: Cmp=SysFile, Class=1, Error=0, Info=0, pszInfo= To grant access, this path may be configured as a PlaceholderFilePath PS, if you give an irritating, or annoying or blaming answer, I will never try to help you again. Some additional info... do you run the Control Win as user, or as service. Test it first by running it as a user, else check the info that Claude gave me as suggestion (not tested): Watch out: the keyboard may not appear CODESYS Control Win normally runs as a Windows service. Windows keeps services in a separate, invisible session (session 0). The command then succeeds, but nobody sees the keyboard. You can check this in Task Manager: if osk.exe runs under the user SYSTEM, this is the cause. A reliable workaround uses the Windows Task Scheduler: Create a task named ShowOSK that starts C:\Windows\System32\osk.exe with “Run only when user is logged on” checked. That option makes it open on the user’s desktop. Have the PLC start that task instead of osk.exe: iecst sApp := 'C:\Windows\System32\schtasks.exe'; sArgs := 'schtasks /run /tn "ShowOSK"'; The command line usually repeats the program name as the first argument. 3. Whitelist it in the config: Command.1=C:\Windows\System32\schtasks.exe
Last updated: 2026-10-28
Post by hhermsen on Codesys v3.5.22.10 - Internal error:System.AggregateException...Value cannot be null...Parameter name: expLValue
CODESYS Forge
talk
(Post)
Internal compiler error in SP22.x (expLValue null) — SP21 unaffected — need help isolating root cause I'm hitting the same internal compiler crash reported here. Same exact stack trace (AssignmentStatementReplacer → CreateAssignmentExpression → ArgumentNullException: Value cannot be null. Parameter name: expLValue), but in my case triggered by a self-written library, not a Visualization object — so this looks like a general SP22.x codegen regression rather than something tied to one specific language feature. What I've confirmed: Reverting to SP21 — no issue, builds clean SP22.x — internal compiler crash during Build > Application, code generation phase, with zero useful location info (no POU, no line number) check_for_errors/precompile-only passes cleanly; the crash only happens on a real full build, meaning static analysis never sees it coming What I've tried to isolate the cause (without success): Removed a suspected pattern involving a VAR_IN_OUT parameter used directly as a FOR-loop control variable, combined with early RETURN inside the loop — crash persisted identically afterward Confirmed no Visualization Manager or similar object in the project (ruling out the trigger in the linked report) Used an AI coding assistant (Claude Code) to search for other suspicious patterns — no luck pinpointing the exact statement Question @codesys-com Since the compiler gives no location info at all, is there any way to get more diagnostic output from the SP22.x codegen phase (verbose/debug build flags, log level settings, etc.)? Without that, isolating this in a large library means blind bisection — cutting the codebase in half repeatedly until the crash disappears, which is slow and error-prone without official tooling support. Happy to share the affected project or a minimal repro if that helps CODESYS engineering track it down.
Last updated: 2026-07-11
Post by timvh on VisuElems.CurrentUserGroupId is not stable
CODESYS Forge
talk
(Post)
I'm not sure what you are trying to do, but getting the CurrentUserGroupID like this will not work, because there could be multiple Visualization Clients and each can have a different user that is logged in. Also when you go online with CODESYS and open an Visualization, this is counted as a client. Probably this is the reason you see it changing. What you can to is "iterate" over all clients and then see which user is logged in on which visualization Client. For this you need to add the Visu Utils library to the project and call the FbIterateClients. See https://content.helpme-codesys.com/en/libs/Visu%20Utils/4.4.0.0/VisuUtils/VisuActionUtilities/Function-Blocks/FbIterateClients.html fbClientIteration( xExecute := x_Execute, itfClientFilter := VU.Globals.AllClients, itfIterationCallback := fbIterator, xDone => x_Done, xBusy => x_Busy, xError => x_Error, eError => e_Error); The fbIterator, in the example above, should be an instance of an FB which you have created yourself and this must implement VU.IVisualizationClientIteration. For example: FUNCTION_BLOCK FB_ITERATOR IMPLEMENTS VU.IVisualizationClientIteration Then automatically the corresponding methods will be called. In the HandleClient Method, you will get an interface to the client(s) and then you can get the current user through this interface: itfClient.UserGroupId You can also get the UserName: itfClient.UserName
Last updated: 2023-11-14
Post by timvh on How to implement an interface (IElement)?
CODESYS Forge
talk
(Post)
See: https://forge.codesys.com/prj/codesys-example/element-collect/home/Home/ This contains an application "OnlineChangeSafeLinkedListExample". What you should do is create a new interface which has your "Priority" property. Then your FB should extend the base element function block and implement your own interface: E.g. FUNCTION_BLOCK MyElement EXTENDS COL.LinkedListElementBase IMPLEMENTS I_MyInterface Then the __QUERYINTERFACE does the magic to check if your "element" also implements your interface. Something like this: // Compares this element with itfElement. // Returns 0 if the elements are equal, < 0 if the element is less than itfElement, // > 0 if the element is greater than itfElement. // This method will be called from sorted collections (e.g. |COL.SortedList|) to sort the elements. // IMPORTANT: The underlying value to be compared with MUST NOT be changed during the lifecycle of the object. METHOD ElementCompareTo : INT VAR_INPUT (* The element to compare*) itfElement : COL.IElement; END_VAR VAR itfIntElement : I_MyInterface; xResult : BOOL; END_VAR // We use integer iInt1 for sorting. xResult := __QUERYINTERFACE(itfElement, itfIntElement); IF xResult THEN IF iInt1 < itfIntElement.Priority THEN ElementCompareTo := -1; ELSIF iInt1 > itfIntElement.Priority THEN ElementCompareTo := 1; ELSE ElementCompareTo := 0; END_IF ELSE ElementCompareTo := -1; END_IF
Last updated: 2024-07-22
Post by mecmag on gear over gear (2 masters,1 slave) - how to do it?
CODESYS Forge
talk
(Post)
Hello, i need to create an application that uses 2 masters, with 2 different ratios, and it outputs in one single slave. I explain better: Imagine axis A, B and C. -Axis A is the slave. -Axis B is master of A, with a specific ratio. -Axis C is master of A, with a specific ratio. the result motion from B and C should be executed by A, proportionally in position and ratios from B and C. With standard softmotion libraries (MC_...) it is not possible (i couldn't) because it is allowed only one master with its ratio. I have made a similiar application in past, using MoveOverGear in order to synch gears before engage. Instead this time, i need to do a gear over gear application, using 2 different masters. The position have to be the sum of both masters (considering their ratios). Any clue about how to do it? Or were to find some FB that can do it?
Last updated: 2024-08-16
Post by hprog on Codesys 3.5.20/21 Import Geräterepository bzw. Bibliothen Repository funktioniert nicht
CODESYS Forge
talk
(Post)
Hallo, Ich habe schon mehrfach Treiber für I2C Geräte geschrieben und keine Probleme mit dem Einbinden gehabt, aber derzeit komme ich auf keinen grünen Zweig. Der Import des Geräterepository (xml) funktioniert, der Import ins Bibliothekenrepository funktioniert auch, aber wenn ich dann das Gerät an den I2C MAster anfüge funktioniert der Import in das Projektbibiothek nicht und somit wird auch der entsprechende FB nicht instanziert und ich bekomme folgende Fehlermeldungen ------ Übersetzungslauf gestartet: Applikation: Device.Application ------- Code typisieren... [FEHLER] I2C_Test_Examples: MCP23008_X81 [Device: I²C: I2C_master]: Bibliothek Raspberry I2C MCP23008_X81, 1.1.0.1 (3S - Smart Software Solutions GmbH) konnte nicht eingefügt werden: [FEHLER] I2C_Test_Examples: C0035: Programmname, Funktion oder Funktionsbausteinstanz an Stelle von 'MCP23008_X81.AfterReadInputs' erwartet [FEHLER] I2C_Test_Examples: C0046: Bezeichner 'MCP23008_X81' nicht definiert [FEHLER] I2C_Test_Examples: C0035: Programmname, Funktion oder Funktionsbausteinstanz an Stelle von 'MCP23008_X81.BeforeWriteOutputs' erwartet [FEHLER] I2C_Test_Examples: C0046: Bezeichner 'MCP23008_X81' nicht definiert Kompilierung abgeschlossen -- 5 Fehler, 0 Warnungen Übersetzung abgeschlossen -- 5 Fehler, 0 Warnungen : Kein Download möglich Als Device habe ich Name: CODESYS Control for Raspberry Pi SL Hersteller: CODESYS Kategorien: SoftMotion Steuerungen Version: 4.13.0.0 Bestellnummer: 2302000009 Beschreibung: Eine Soft-SPS nach IEC 61131-3 für Raspberry Pi. CODESYS Control basiert auf CODESYS SDK 3.5.20.20, Release . Das ganze unabhängig von der Codesys Version
Last updated: 2025-10-06
Post by hprog on Codesys 3.5.21 Import Geräterepository bzw. Bibliothen Repository funktioniert nicht
CODESYS Forge
talk
(Post)
Hallo, Ich habe schon mehrfach Treiber für I2C Geräte geschrieben und keine Probleme mit dem Einbinden gehabt, aber derzeit komme ich auf keinen grünen Zweig. Der Import des Geräterepository (xml) funktioniert, der Import ins Bibliothekenrepository funktioniert auch, aber wenn ich dann das Gerät an den I2C MAster anfüge funktioniert der Import in das Projektbibiothek nicht und somit wird auch der entsprechende FB nicht instanziert und ich bekomme folgende Fehlermeldungen ------ Übersetzungslauf gestartet: Applikation: Device.Application ------- Code typisieren... [FEHLER] I2C_Test_Examples: MCP23008_X81 [Device: I²C: I2C_master]: Bibliothek Raspberry I2C MCP23008_X81, 1.1.0.1 (3S - Smart Software Solutions GmbH) konnte nicht eingefügt werden: [FEHLER] I2C_Test_Examples: C0035: Programmname, Funktion oder Funktionsbausteinstanz an Stelle von 'MCP23008_X81.AfterReadInputs' erwartet [FEHLER] I2C_Test_Examples: C0046: Bezeichner 'MCP23008_X81' nicht definiert [FEHLER] I2C_Test_Examples: C0035: Programmname, Funktion oder Funktionsbausteinstanz an Stelle von 'MCP23008_X81.BeforeWriteOutputs' erwartet [FEHLER] I2C_Test_Examples: C0046: Bezeichner 'MCP23008_X81' nicht definiert Kompilierung abgeschlossen -- 5 Fehler, 0 Warnungen Übersetzung abgeschlossen -- 5 Fehler, 0 Warnungen : Kein Download möglich Als Device habe ich Name: CODESYS Control for Raspberry Pi SL Hersteller: CODESYS Kategorien: SoftMotion Steuerungen Version: 4.13.0.0 Bestellnummer: 2302000009 Beschreibung: Eine Soft-SPS nach IEC 61131-3 für Raspberry Pi. CODESYS Control basiert auf CODESYS SDK 3.5.20.20, Release . Das ganze unabhängig von der Codesys Version
Last updated: 2025-10-06
Post by hprog on Codesys 3.5.20/21 Import Geräterepository bzw. Bibliothen Repository funktioniert nicht
CODESYS Forge
talk
(Post)
Hallo, Ich habe schon mehrfach Treiber für I2C Geräte geschrieben und keine Probleme mit dem Einbinden gehabt, aber derzeit komme ich auf keinen grünen Zweig. Der Import des Geräterepository (xml) funktioniert, der Import ins Bibliothekenrepository funktioniert auch, aber wenn ich dann das Gerät an den I2C MAster anfüge funktioniert der Import in das Projektbibiothek nicht und somit wird auch der entsprechende FB nicht instanziert und ich bekomme folgende Fehlermeldungen ------ Übersetzungslauf gestartet: Applikation: Device.Application ------- Code typisieren... [FEHLER] I2C_Test_Examples: MCP23008_X81 [Device: I²C: I2C_master]: Bibliothek Raspberry I2C MCP23008_X81, 1.1.0.1 (3S - Smart Software Solutions GmbH) konnte nicht eingefügt werden: [FEHLER] I2C_Test_Examples: C0035: Programmname, Funktion oder Funktionsbausteinstanz an Stelle von 'MCP23008_X81.AfterReadInputs' erwartet [FEHLER] I2C_Test_Examples: C0046: Bezeichner 'MCP23008_X81' nicht definiert [FEHLER] I2C_Test_Examples: C0035: Programmname, Funktion oder Funktionsbausteinstanz an Stelle von 'MCP23008_X81.BeforeWriteOutputs' erwartet [FEHLER] I2C_Test_Examples: C0046: Bezeichner 'MCP23008_X81' nicht definiert Kompilierung abgeschlossen -- 5 Fehler, 0 Warnungen Übersetzung abgeschlossen -- 5 Fehler, 0 Warnungen : Kein Download möglich Als Device habe ich Name: CODESYS Control for Raspberry Pi SL Hersteller: CODESYS Kategorien: SoftMotion Steuerungen Version: 4.13.0.0 Bestellnummer: 2302000009 Beschreibung: Eine Soft-SPS nach IEC 61131-3 für Raspberry Pi. CODESYS Control basiert auf CODESYS SDK 3.5.20.20, Release . Das ganze unabhängig von der Codesys Version
Last updated: 2025-10-06
Post by axilleas on SMC_Interpolator + SMC_controAxislbyPos
CODESYS Forge
talk
(Post)
dear all I am working on a very generic gantry system (virtual drives + win v3 control) reading gcode from external file. In order to stop the interpolator function from running when gaps are detected, SMC_controlAxisByPos FB has the bStopIpo output which according to the manual is connected to the Interpolator's bEmergencyStop. Lets assume that the axis are parked in position X1000 Y1000 and the initial G code movement is G00 X500 Y500. The normal behavior is to travel from the actual x1000 y1000 to G00 X500 Y500. The SMC_Interpolator always gets the X0 Y0 as the initial position, meaning that the bStopIpo is active until the axis are in X0 Y0 and the release the interpolator to set the new positions to X500 Y500. Is there a suggested method to solve this behavior? bonus question: I get a lot of bStopIpo during standard interpolation movements (not gaps). While working with virtual axis this is not a problem but when real axis are installed this will be an issue. What exactly triggers the bStopIpo output? Slow axis accelerations compare to Gcode defaults? Kind Regards
Last updated: 2024-02-05
Post by alexgooi on Modbus writing on value change
CODESYS Forge
talk
(Post)
Hi Duvan, You could make this in 1 single object (FB), Indeed don't use a function for this beacuse you need some memory to keep the old value. For i := 0 TO 200 BY 1 DO //Check if the value has been changed IF Old_Value[i] <> Value[i] THEN //Set the trigger to TRUE Trigger[i] := TRUE; Old_Value[i] := Value[i]; END_IF END_FOR If you define the Value array as an In_Out and the Trigger as an In_Out you arn't claiming any aditional memory to your system. You ofcourse then need to add some code arround it that does something with the trigger and writes it back to FALSE again. If you want more flexability you also could use pointers instead of using the IN_OUT FOR i := 0 TO 200 BY 1 DO address := address_Input + i * SIZEOF(*Put type here); IF Address^ <> Old_Value[i] THEN Trigger[i] := TRUE; Old_Value[i] := Address^; END_IF END_FOR
Last updated: 2024-04-02
Post by mxj262 on FB having single input but initialized with Array
CODESYS Forge
talk
(Post)
I am adding elements of an ARRAY using pointer to access each element inside a FOR loop and the FOR loop does not stop! What is the right way to use pointers in such case?? I have another loop that is not using pointer and it stops but the loop using pointer keep on adding. METHOD FB_Init: BOOL VAR_INPUT bInitRetains: BOOL; // TRUE: the retain variables are initialized (reset warm / reset cold) bInCopyCode: BOOL; // TRUE: the instance will be copied to the copy code afterward (online change) END_VAR VAR_IN_OUT // basically REFERENCE TO window_buffer: ARRAY [*] OF INT; // array of any size END_VAR THIS^.windowPtr := ADR(window_buffer[0]); THIS^.windowSize := UPPER_BOUND(window_buffer, 1) - LOWER_BOUND(window_buffer, 1) + 1; FUNCTION_BLOCK FB500 VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR windowPtr: POINTER TO INT; windowSize: DINT; currentIndex: UINT; element1:INT; element2:INT; i:INT; j:INT; sum:DINT:=0; END_VAR element1:=windowPtr[0]; // read the first element of the Array dynamic memorry element2:=windowPtr[1]; FOR i:=0 TO (TO_INT(windowSize-1)) BY 1 DO // this loop does not stop Sum:=sum + windowPtr[i]; END_FOR FOR j:=0 TO 5 BY 1 DO // this loop stops j:=j+1; END_FOR https://ibb.co/k3DhkZT
Last updated: 2024-05-06
Post by paro on Modbus Client Request Not Processed
CODESYS Forge
talk
(Post)
Hi, Problem in your code is that you are not calling the ClientFb cyclic. Please look at the Example from CODESYS: https://forge.codesys.com/prj/codesys-example/modbus/home/Home/ Your code works if the client fb is called cyclic! IF NOT initDone THEN initDone := TRUE; // configure clientTcp clientTcp(aIPaddr:=Ethernet.IPAddress, uiPort:=502); // configure clientSerial clientSerial(iPort:=SysCom.SYS_COMPORT2, dwBaudRate:=SysCom.SYS_BR_115200, byDataBits:=8, eParity:=SysCom.SYS_EVENPARITY, eStopBits:=SysCom.SYS_ONESTOPBIT, eRtuAscii:=ModbusFB.RtuAscii.RTU); // configure clientRequestReadCoils_1 clientRequestReadCoils_1(rClient:=clientTcp, uiUnitId:=42, udiTimeout:=TO_UDINT(T#10MS)); // configure clientRequestWriteSingleRegister clientRequestWriteSingleRegister(rClient:=clientTcp, uiUnitId:=43, udiTimeout:=TO_UDINT(T#10MS)); // configure clientRequestReadCoils_2 clientRequestReadCoils_2(rClient:=clientTcp, uiUnitId:=44, udiTimeout:=TO_UDINT(T#10MS)); // configure clientRequestReadInputRegisters clientRequestReadInputRegisters(rClient:=clientTcp, uiUnitId:=44, udiTimeout:=TO_UDINT(T#10MS)); END_IF // call the client FB's clientTcp(); clientSerial(); // call client request FB's clientRequestReadCoils_1(rClient:=clientTcp, xExecute:=TRUE, uiStartItem:=2, uiQuantity:=3, pData:=ADR(aDataCoils_1[0])); // for more details see Example_TCP, especially ClientRequest control (xExecute, xDone, xError). IF clientRequestReadCoils_1.xDone THEN // get data from aDataCoils_1 ... END_IF clientRequestWriteSingleRegister(rClient:=clientTcp, xExecute:=TRUE, uiItem:=3, uiValue:=123); clientRequestReadCoils_2(rClient:=clientTcp, xExecute:=TRUE, uiStartItem:=2, uiQuantity:=3, pData:=ADR(aDataCoils_2[0])); clientRequestReadInputRegisters(rClient:=clientTcp, xExecute:=TRUE, uiStartItem:=16, uiQuantity:=3, pData:=ADR(aDataInputRegisters[0]));
Last updated: 2024-05-29
Post by charleskirkland on Connect to Azure IoT Hub
CODESYS Forge
talk
(Post)
It sounds like your TLS setup is basically correct, since the handshake works via OpenSSL, so the issue is likely on the CODESYS side rather than the certificates themselves. From what I’ve seen with the Azure IoT Hub Client SL library, you should double-check that the SAS token is actually being generated and passed correctly to the function blocks (especially wsDeviceSaS) and that the MQTT/HTTPS FB is really triggered cyclically-otherwise the controller won’t initiate the connection at all. Also, make sure DNS, time (NTP), and full certificate chain trust are properly configured on the controller, since IoT Hub authentication depends on them even when using SAS tokens. Another thing worth checking is the library/runtime version-there are reports that certain versions changed behavior and caused connection issues. I’d recommend starting with the official demo project (AzureMQTTDemo) and comparing it step by step with your setup to see what’s missing or not triggered. Speed Stars
Last updated: 2026-04-27
Post by timvh on USB Game Controller with Raspberry Pi
CODESYS Forge
talk
(Post)
I'm not sure it will work, but you could try it with the CmpCharDevice library. You could create a function block that looks something like this: As input for the filename, you have to use your Linux device, e.g.: '/dev/input/event0' '/dev/input/by-path/platform-button@23-event' Off course you must also pass the pointer to the memory where the data can be written to and the size (count in number of bytes) of the buffer. FUNCTION_BLOCK FB_CharDevice VAR_INPUT szFilename: STRING; pbyBuffer : POINTER TO BYTE; udCount : UDINT; END_VAR VAR_OUTPUT iState : INT := 0; nrBytesRead : DINT; END_VAR VAR xInit : BOOL := TRUE; dFlags: DINT := CmpCharDevice.ACCESS_MODE.O_RDONLY + DINT#4000; // see details for flags: http://linux.die.net/man/2/open, + DINT#4000 is for non-blocking hDevice: CmpCharDevice.CmpCharDevice_Implementation.RTS_IEC_HANDLE := -1; Result : CmpCharDevice.CmpCharDevice_Implementation.RTS_IEC_RESULT; END_VAR IF xInit THEN hDevice := CmpCharDevice.CDOpen(szFilename, dFlags ,Result); // if it would not succeed, the result is -1 (Invalid handle) IF hDevice <> 16#FFFFFFFF AND Result = 0 THEN iState := 5; END_IF xInit := FALSE; END_IF IF iState = 5 THEN nrBytesRead := CmpCharDevice.CDRead(hDevice, pbyBuffer, udCount, Result); ELSE nrBytesRead := 0; END_IF Make sure you close the connection properly, maybe by overwriting the default FB_Exit method of the FB: // Clean up device IF hDevice <> 16#FFFFFFFF THEN __TRY CmpCharDevice.CDClose(hDevice,Result); __CATCH ; __ENDTRY iState := 0; END_IF
Last updated: 2026-05-01
Post by mondinmr on Direct Pointers in IOMapping for EtherCAT with IoDrvEthercatLib.ETCSlave_Dia
CODESYS Forge
talk
(Post)
I have found a very interesting solution using: IoConfigTaskMap IoConfigConnectorMap IoConfigChannelMap The first is the list of IO tasks. The second is the connector for each IO module in the IOMap. The third is the individual input or output on the IOMap. One of the properties of the connector is another pointer to a connector, which corresponds with the connector of the EtherCAT slave. Through this information, it is possible to understand to which EtherCAT slave an IO connectormap corresponds. I am attaching an FB that allows for the construction of an IO map and finding the pointer to the actual IOs in the IOMap based on the bitoffset. FUNCTION_BLOCK IOExplorer VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR inputChannels: COL.LinkedList; outputChannels: COL.LinkedList; ulintFactory: COL.UlintElementFactory; END_VAR METHOD inputAtBitOffsetOfConnector : POINTER TO BYTE VAR_INPUT conn: POINTER TO IoConfigConnectorMap; bitOffset: UDINT; END_VAR VAR it: COL.LinkedListIterator; itf: COL.IElement; elem: COL.iUlintElement; channelInfo: POINTER TO ADVChannelInfo; bitOffsetR: UDINT; END_VAR inputChannels.ElementIterator(it); WHILE it.HasNext() DO it.Next(itfElement => itf); __QUERYINTERFACE(itf, elem); {warning disable C0033} channelInfo := TO___UXINT(elem.UlintValue); {warning restire C0033} IF channelInfo^.connectorField = conn THEN IF bitOffsetR = bitOffset THEN inputAtBitOffsetOfConnector := channelInfo^.addr; RETURN; END_IF bitOffsetR := bitOffsetR + channelInfo^.size; ELSE bitOffsetR := 0; END_IF END_WHILE inputAtBitOffsetOfConnector := 0; END_METHOD METHOD outputAtBitOffsetOfConnector : POINTER TO BYTE VAR_INPUT conn: POINTER TO IoConfigConnectorMap; bitOffset: UDINT; END_VAR VAR it: COL.LinkedListIterator; itf: COL.IElement; elem: COL.iUlintElement; channelInfo: POINTER TO ADVChannelInfo; bitOffsetR: UDINT; END_VAR outputChannels.ElementIterator(it); WHILE it.HasNext() DO it.Next(itfElement => itf); __QUERYINTERFACE(itf, elem); {warning disable C0033} channelInfo := TO___UXINT(elem.UlintValue); {warning restire C0033} IF channelInfo^.connectorField = conn THEN IF bitOffsetR = bitOffset THEN outputAtBitOffsetOfConnector := channelInfo^.addr; RETURN; END_IF bitOffsetR := bitOffsetR + channelInfo^.size; ELSE bitOffsetR := 0; END_IF END_WHILE outputAtBitOffsetOfConnector := 0; END_METHOD METHOD scanIO VAR_INPUT END_VAR VAR numTasks: DINT := IoConfig_Globals.nIoConfigTaskMapCount; tType: WORD; ioTask: POINTER TO IoConfigTaskMap; numCon: WORD; connector: POINTER TO IoConfigConnectorMap; numCh: DWORD; channelInfo: POINTER TO ADVChannelInfo; iTsk: DINT; iCon: WORD; iCh: DWORD; i: DINT; _tmpConnList: COL.IList; elem: COL.IUlintElement; itf: COL.IElement; tmpCh: POINTER TO ADVChannelInfo; lastE: DINT; e: COL.COLLECTION_ERROR; e1: Error; END_VAR VAR_INST lF: COL.ListFactory; END_VAR IF outputChannels.CountElements() > 0 OR inputChannels.CountElements() > 0 THEN RETURN; END_IF _tmpConnList := lF.CreateDynamicList(16, 16); //Iterate through all IO tasks FOR iTsk := 0 TO numTasks - 1 DO ioTask := ADR(IoConfig_Globals.pIoConfigTaskMap[iTsk]); //Store the type of the task (Input or Output) tType := ioTask^.wType; numCon := ioTask^.wNumOfConnectorMap; //Iterate through all connectors of the task FOR iCon := 0 TO numCon - 1 DO connector := ADR(ioTask^.pConnectorMapList[iCon]); numCh := connector^.dwNumOfChannels; //Iterate through all channels of the connector FOR iCh := 0 TO numCh - 1 DO //Create a new channel info object and fill it with the address, connector and size of the channel //Connectors is address of field connector in this case like EtherCAT slave //Address is the address of the IOMap //Size is the size of channel data in bits in IOMap channelInfo := __NEW(ADVChannelInfo); channelInfo^.addr := connector^.pChannelMapList[iCh].pbyIecAddress; channelInfo^.connectorField := connector^.pConnector; channelInfo^.size := connector^.pChannelMapList[iCh].wSize; //We put the channel info a temporary ordered list //Order is based on the address of IOMap lastE := TO_DINT(_tmpConnList.CountElements()) - 1; FOR i := 0 TO lastE DO _tmpConnList.GetElementAt(udiPosition := TO_UDINT(i), itfElement => itf); __QUERYINTERFACE(itf, elem); {warning disable C0033} tmpCh := TO___UXINT(elem.UlintValue); {warning restire C0033} //If the address of the channel is smaller than the address of the channel in the list IF tmpCh^.addr > channelInfo^.addr THEN //Insert the channel in the list at the current position _tmpConnList.InsertElementAt(TO_UDINT(i), ulintFactory.Create(TO_ULINT(channelInfo))); //Clear the channel info pointer channelInfo := 0; //Exit the loop i := lastE + 1; END_IF END_FOR //If the channel info is not 0, it means that the channel was not inserted in the list IF channelInfo <> 0 THEN //Add the channel to the end of the list elem := ulintFactory.Create(TO_ULINT(channelInfo)); _tmpConnList.AddElement(elem); END_IF END_FOR //Iterate temporary list and add the channels to the input or output list lastE := TO_DINT(_tmpConnList.CountElements()) - 1; FOR i := 0 TO lastE DO _tmpConnList.GetElementAt(udiPosition := TO_UDINT(i), itfElement => itf); __QUERYINTERFACE(itf, elem); {warning disable C0033} tmpCh := TO___UXINT(elem.UlintValue); {warning restire C0033} //If type is input, add the channel to the input list IF tType = TaskMapTypes.TMT_INPUTS THEN e := inputChannels.AddElement(ulintFactory.Create(TO_ULINT(tmpCh))); //If type is output, add the channel to the output list ELSIF tType = TaskMapTypes.TMT_OUTPUTS THEN e := outputChannels.AddElement(ulintFactory.Create(TO_ULINT(tmpCh))); ELSE __DELETE(tmpCh); END_IF END_FOR //Clear the temporary list _tmpConnList.RemoveAllElements(); END_FOR END_FOR END_METHOD
Last updated: 2024-02-13
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.