Post by jackbrady on Function Blocks and arrays of function blocks
CODESYS Forge
talk
(Post)
Hello, I am new to Codesys and PLC programming in general (please go easy ha!) I'm not looking for code to be written for me just some help and pointing in the right direction. I am writing some code to send commands to a relay based on input values (to put it simply). Quite basic stuff. I have wrote a function block that takes a global variable (Open_command:BOOL) and outputs to another global variable (Opened : BOOL). The function block is simulating a device so I'll eventually get the globals from that. I now need to create multiple versions of this function block/ device (lets say 100) but I need each iteration of that function block to reference it's own relevant global variable. I think that the best way of doing this would be to use arrays, although I could be wrong. I am aware that for up to 100 instances I could very well manually assign everything but that seems rather time consuming and I want a fancier way of doing it. Here is a very basic example of what I am looking to do, please note I have not written this in proper code it's just to show what I mean. Global Variables V[0-100] int Open_command [0-100] Bool Opened [0-100] Bool Function Block var input x : BOOL Var output y : BOOL if x then y = TRUE ELSE y = FALSE The input to my function block will be Open_command, output will be Opened Example code. If V[x] > 10 then Open_command [x] = TRUE ELSE Open_command [x] = FALSE (So when V1 goes above 10 I need Open_command1 = TRUE therefore initiating FB1 output. V2 > 10, open_command2 = True > FB2 output V3 > 10, open_command3 = True > FB3 output ... ... ) What I can't seem to figure out is how to tie all this together, I have read through the codesys documentation and if anything it has confused me more! ha. Apologies for the poorly written post but hopefully you understand what I am trying to get at. Thanks, Jack
Last updated: 2024-02-14
Post by aniket-b on Multiple function blocks are not executing at the same time in ladder logic
CODESYS Forge
talk
(Post)
I have two ethernet Ip drives and created Function Blocks for different motions tasks. I am using same FB for both the drives. When I try to execute the relative move start command on FB for both the drives it is not working. However, if I add 1ms second delay between the execution of each drive it is working. Also when I change the rung order it is working for the first drive in the rung. what could be the wrong here?
Last updated: 2024-03-12
Post by schnepper on Error building Extension SDK Linux code
CODESYS Forge
talk
(Post)
I'm installed the CODESYS Control for Linux SL package and am trying to use the Extension API to call a simple C function. When I get to the step to run "make all" on the Linux machine, I get the error: build interface header: out/CmpFirstTestItf.h from CmpFirstTestItf.m4 ERROR: This functionname does not contain _cext (this is mandatory, see help for details): DEF_API(void',CDECL',external_struct__fb_init',(external_struct_fb_init_struct *p)',1,0x1F77E075,0x00000001) Why does "Generate Runtime System Files" create a function that does not have cext in the name? What am I missing?
Last updated: 2024-04-01
Post by gseidel on Discontinuity of A/B/C axis movement.
CODESYS Forge
talk
(Post)
Hi jonasz, you already solved it, I'm answering here for the sake of others with a similar question. You can provide the slope of the A/B/C axis with the U/V/W word. See example 3 here: https://content.helpme-codesys.com/en/CODESYS%20SoftMotion/_sm_cnc_din66025_additional_axis.html If you don't want to change the G-Code, the function block SMC_RecomputeABCSlopes can compute the slopes automatically. https://content.helpme-codesys.com/en/libs/SM3_CNC/Current/SM_CNC_POUs/SoftMotion-CNC/SoftMotion-Function-Blocks/SMC_RecomputeABCSlopes.html Best regards, Georg
Last updated: 2024-04-30
Post by breiter on Frustration-Fueled Feedback on Project File Management and Git Integration
CODESYS Forge
talk
(Post)
Hi, supporting a text based storage format is on our roadmap, see https://www.codesys.com/the-system/releases-updates-lifecycle/release-plan-roadmap.html It will be an Add-On feature called "File Based Storage" for the professional developer edition. Structured text POUs will be stored as plain text. Other graphical languages will remain in an xml format. You will be able to switch the storage type for projects. Certain workflows will become easier this way. Nevertheless restrictions will remain because of CODESYS specific storage logic (for example how methods below function blocks are stored as file). So merging using our Git Integration Add-On remains the recommended workflow. A workflow involving Visual Studio Code as the main IDE is not supported. Simply because many topics like library management, task configuration or fieldbus configurators are not available for VS Code. A PLC project is a lot more than just some ST POUs. Best Regards
Last updated: 2024-10-16
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 pernockham on Pointer/reference to Codesys trend recording object?
CODESYS Forge
talk
(Post)
I have a Hmi that acts as an interface for many (mostly identical) units. This is managed by a sort of "mux" where you select which unit that should be presented on the HMI. Backbone is solved by a HMI-gvl defined as reference/pointer to "unit-data", which then can be set to the individual units. While this works for most data I still have not sorted how to solve this for the trend recordings. One solution would be to have already "mux:ed" data values as source for the/one trend. However then the trend would contain data from different units/sources which could/will cause confusion. If its possible to "clear" this can be mitigated. Possibly let the trend have its own "mux-selector" (ie, the hmi are focusing on unit#3 however trend data is locked on unit#5), that could also work.. Or, let each unit have its own trend recording, which is focused if the unit is "selected". Can I reach the trend recording objects programmatically (those defined in the device tree)? Ie, can I use a "reference/pointer to these trend recording objects"? There is a field "data source" in the trend properties dialog which seems to resemble what Im looking for? But Im not sure if I can use it in some way, I cannot change anything in this field it only says <local application="">. </local>
Last updated: 2025-09-16
Post by gustavocsw on MQTT memory leak problem
CODESYS Forge
talk
(Post)
Hello everyone, I'm using the IoT Library to implement the MQTT communication with my local broker server in order to publish and subscribe at specifics topics to share and consume information about my application. But, it seems that are occurring some memory leak problem in a "high" frequency (more than 10 Hz) subscribe process. I follow the same method as in IoT Lib exemples, and at first looks perfect but my PLC was rebooting frequently and when I check its memory usage that was increasing as fast as the subscribe massage was sent. I'm using a WEG PLC410 and a WEG PLC500, and this error occurred in both of them (including in CODESYS Control Win x64). The application sends to the system a message JSON with the float payload Ex. {"data" : 0.8500}, but this happens with a INT, or BOL as well. I use the follow code in my application to find the value: //FindFirstValueByKey VARs PROGRAM JSON_VELO VAR //------Setting the JSON Subscriber to Set the Relay Value jsonDataVelo : JSON.JSONData; jsonByteArrayReaderVelo : JSON.JSONByteArrayReader; xST1okVelo : BOOL; FindFirstValueByKeyVelo : JSON.FindFirstValueByKey; jsonElementVelo : JSON.JSONElement; xDoneReaderVelo : BOOL; xDoneFindVelo : BOOL; //STRING and WSTRING for Subscribe the massage sPayloadJsonVelo : STRING := 'opa'; psPayloadJsonVelo : POINTER TO BYTE := ADR(sPayloadJsonVelo); //wsPayloadJsonRelaySet : WSTRING := "opa"; wsPayloadJsonVelo : WSTRING := STRING_TO_WSTRING('opa'); pwsPayloadJsonVelo : POINTER TO WORD := ADR(wsPayloadJsonVelo); lrVelo : LREAL; xKeepAliveVelo : BOOL; xSetVelo : BOOL; RSSet : RS; LIMPAR : STRING; //Find the msg end sFindVelo : STRING := '}'; psFindVelo : POINTER TO STRING := ADR(sFindVelo); iLenVelo : INT; iSizeVelo : INT := 12; udiContMsg : UDINT; END_VAR // FindFirstValueByKey CODE // Relay Set configuration xSetVelo := MQTT_SUBSCRIBER.RSVelo.Q1; IF xSetVelo THEN xKeepAliveVelo := TRUE; END_IF IF xKeepAliveVelo THEN udiContMsg := udiContMsg + 1; iLenVelo := TO_INT(StrLenA(psPayloadJsonVelo)); iSizeVelo := iLenVelo - TO_INT(MQTT_SUBSCRIBER.udiPayloadSizeVelo); StrDeleteA(psPayloadJsonVelo,iSizeVelo,iLenVelo); wsPayloadJsonVelo := STRING_TO_WSTRING(sPayloadJsonVelo); pwsPayloadJsonVelo := ADR(wsPayloadJsonVelo); //MQTT.ConvertUTF8toUTF16(sourceStart:= ADR(sPayloadJsonVelo), targetStart:= ADR(wsPayloadJsonVelo), dwTargetBufferSize:= TAM, bStrictConversion:= 1); //Reset jsonByteArrayReader jsonByteArrayReaderVelo ( xExecute := TRUE, pwData := pwsPayloadJsonVelo, jsonData := jsonDataVelo, xDone => xDoneReaderVelo ); FindFirstValueByKeyVelo( xExecute := xDoneReaderVelo, wsKey := "data", diStartIndex:= 0, jsonData := jsonDataVelo, jsonElement => jsonElementVelo, xDone => xDoneFindVelo ); IF xDoneFindVelo THEN lrVelo := jsonElementVelo.value.lrValue; //Reset jsonByteArrayReader jsonByteArrayReaderVelo ( xExecute := FALSE, pwData := pwsPayloadJsonVelo, jsonData := jsonDataVelo, xDone => xDoneReaderVelo ); FindFirstValueByKeyVelo( xExecute := FALSE, wsKey := "data", diStartIndex:= 1, jsonData := jsonDataVelo, jsonElement => jsonElementVelo, xDone => xDoneFindVelo ); xKeepAliveVelo := FALSE; GVL.xSetVeloRead := TRUE; END_IF END_IF And this to subscribe at the topic: //SUBSCRIBE VAR: //----------------- Subscribe Velocity ----------------------- MQTTSubscribeVelo : MQTT.MQTTSubscribe;//Variable MQTTSubscriber block -X - function-X wsTopicSubscribeVelo : WSTRING(1024) := "CORE/odometry/GET/data/simp"; // Topic to publish a message sSubscribeMassageVelo : STRING; udiPayloadSizeVelo : UDINT; xSDoneVelo : BOOL; xSErrorVelo : BOOL; xReceiveVelo : BOOL; eSTypeVelo : MQTT.MQTT_ERROR; eSMQTTErrorVelo : MQTT.MQTT_ERROR; RSVelo : RS; udiCont : UDINT; //SUBSCRIBE CODE: MQTTSubscribeVelo( xEnable:= MQTT_CLIENT.xConnection_Broker AND NOT xSErrorVelo AND NOT JSON_VELO.xKeepAliveVelo, pbPayload:= JSON_VELO.psPayloadJsonVelo, udiMaxPayloadSize:= SIZEOF(JSON_VELO.sPayloadJsonVelo), udiPayloadSize => udiPayloadSizeVelo, mqttClient:= MQTT_CLIENT.ClientMQTT, wsTopicFilter:=wsTopicSubscribeVelo, xDone => xSDoneVelo, xError=> xSErrorVelo, xReceived => xReceiveVelo, eMQTTError=> eSMQTTErrorVelo ); RSVelo(SET := xReceiveVelo, RESET1 := JSON_VELO.xKeepAliveVelo);
Last updated: 2024-09-09
Post by sven01 on Documentation / Usage Help For Scripting Engine Libraries
CODESYS Forge
talk
(Post)
Hi, I am still not able to figure out how to use the the classes and their functions. π Let's say I would like to use the function "importfile()" from the class "ScriptTextListObject.ScriptTextListMarker". I would be grateful for an additional example. Thanks! π
Last updated: 2023-08-21
Post by timvh on Detect "Cancel" Press in FileOpenSave Dialog
CODESYS Forge
talk
(Post)
Maybe there is a better way, but a long time ago I created a test application that worked like this: With a button I opened the dialog and I added a "Input configuration - OnDialogClosed" "Execute ST-Code" action to this same button which called the following Function when the dialog was closed: F_OnFileDialogClosed(pClientData); Below this Function which handled the result: // This function is called from the visualization when the dialog is closed. FUNCTION F_OnFileDialogClosed : BOOL VAR_INPUT pClientData : POINTER TO VisuElems.VisuStructClientData; END_VAR VAR dialogMan : VisuElems.IDialogManager; FileOpenCloseDialog : VisuElems.IVisualisationDialog; result : VisuElems.Visu_DialogResult; _sFileName : STRING(255); END_VAR // the DialogManager is provided via the implicitly available VisuManager dialogMan := VisuElems.g_VisuManager.GetDialogManager(); IF dialogMan <> 0 AND pClientData <> 0 THEN FileOpenCloseDialog := dialogMan.GetDialog('VisuDialogs.FileOpenSave'); // gets the FileOpenSave dialog IF FileOpenCloseDialog <> 0 THEN result := FileOpenCloseDialog.GetResult(); // gets the result (OK, Cancel) of the dialog IF result = VisuElems.Visu_DialogResult.OK THEN // Original code gvlFile.FileListProvider(); _sFileName := CONCAT(gvlFile.FileListProvider._stDirectory, gvlFile.FileListProvider.stFile); // do something with this file name... END_IF END_IF END_IF
Last updated: 2023-09-19
Post by sedoerr on Check For Open Dialogs On Client
CODESYS Forge
talk
(Post)
FUNCTION CheckDialogOpen : BOOL VAR_INPUT sDialogName : STRING; END_VAR VAR pstClientData : POINTER TO VisuElems.VisuStructClientData; itfDialogManager : VisuElems.IDialogManager; itfMyDialog : VisuElems.IVisualisationDialog; END_VAR VisuElems.g_ClientManager.BeginIteration(); WHILE (pstClientData := VisuElems.VisuElemBase.g_ClientManager.GetNextClient()) <> 0 DO itfDialogManager := VisuElems.g_VisuManager.GetDialogManager(); itfMyDialog := itfDialogManager.GetDialog(sDialogName); CheckDialogOpen := VisuDialogs.VisuDlgUtil_IsDialogOpen(itfMyDialog,pstClientData,itfDialogManager); IF CheckDialogOpen THEN EXIT; END_IF END_WHILE
Last updated: 2023-09-26
Post by snhatton on Can't open online view of FB instance from code editor, only from Device/POU windows
CODESYS Forge
talk
(Post)
Good morning, Yes, this is a known bug that has been reported. For now, the only workaround is to open the function block instances from the device tree. Regards, -Shawn
Last updated: 2023-11-08
Post by voffi on documentation in function block
CODESYS Forge
talk
(Post)
Using < br > did it for me in CODESYS 3.5.19 // 2023-12-05 Line 1<br> // 2023-12-06 Line 2<br> shows up in Library Manager with line breaks.
Last updated: 2023-12-07
Post by mucleus on What is the solution for "Application stopped on recovery switch request"?
CODESYS Forge
talk
(Post)
Component ID 10 is my own log message by LogAdd Function. I want to know in what cases the application stops.
Last updated: 2024-07-09
Post by rmaas on How to use/create SOTU in LD program
CODESYS Forge
talk
(Post)
You can use the R_TRIG and F_TRIG function blocks to generate a pulse in Rising or Falling edge of your signal. Have a look here: https://content.helpme-codesys.com/en/libs/Standard/Current/Trigger/R_TRIG.html
Last updated: 2024-07-11
Post by ljg007 on Variable assignments
CODESYS Forge
talk
(Post)
That is an output of the Function Block ModbusMasterRTU example: xIsConnected=> xIsConnected In this line the VAR ModbusMasterRTU.xIsConnected is written to VAR xIsConnected xError=> is writing to nothing here.
Last updated: 2024-07-22
Post by jens on Using the Wago 750-658 CAN Gateway
CODESYS Forge
talk
(Post)
Is there any solution for this ? or do you need to use wago runtime and use the function blocks for the CanOpen ?
Last updated: 2024-07-23
Post by grant32 on RAMP_REAL FB is retaining my output value when i try to re use the FB
CODESYS Forge
talk
(Post)
Hello, I'm relatively new to PLC programming. I am trying to creat a ramp down function, I have an example here of what I am using. I can get the function to work, the issue is that the OUT (variable3) value is being held by the FB so after I use it once it no longer works. In this example i set variable3 to 100 and the rest is as seen, over the course of a minute it ramped down to 10 (as desired). But when I deenergize TEST_START, set variable3 back to 100, and then re-energize TEST_START it immediately jumps back to the previously held value 10. The reset on this block just pauses the function and holds the last OUT. In my case I will need the function to start OUT at a set value, ramp down to the IN (variable2) value, and then accept a new OUT value to ramp down next time the block is energized. Hopefully this made sense, if anyone has any advice that would be awesome!
Last updated: 2024-07-29
Post by robert-o on Converting hex bytes to float
CODESYS Forge
talk
(Post)
Try OSCAT_BASIC and Function DW_TO_REAL. DWORD_OF_BYTE my although help. The Lib is open and free. It is not necessary to add this Lib, you can use/copy the source code just to get an idea.
Last updated: 2024-08-05
Post by installwhat on Add Event Handler -> Login/Logout Event Handlers
CODESYS Forge
talk
(Post)
Old question but since I stumbled on it others might. He probably added the function he wants to be called before using the "add event handler". If you don't add it first they will be created with the correct params.
Last updated: 2024-08-12
Post by dkugler on Calculate Time Between Two Events Using RTC
CODESYS Forge
talk
(Post)
a few seconds later with google search... https://stackoverflow.com/a/61986234 SYS_TIME is definitely an ABB AC500 specific function, included in library SysInt_AC500_V10.lib.
Last updated: 2024-08-14
Post by ralfki on User management
CODESYS Forge
talk
(Post)
Hello CodeSYS community, Is there a CodeSys function with which you can activate user management or is this only possible with the CodeSYS development environment? Thanks for the support
Last updated: 2024-09-02
Post by timvh on Help with DynamicTextGetTextW
CODESYS Forge
talk
(Post)
First of all you need to enable "Use unicodestrings" in the Visualization Manager. This function returns a pointer to a WSTRING (not STRING). To get this wstring value, do something like this: VAR myWstringVariable : WSTRING(255); END_VAR myWstringVariable := myResult^; // this is dereferencing the pointer to the WSTRING.
Last updated: 2024-09-03
Post by timvh on Array of Program
CODESYS Forge
talk
(Post)
You cannot create an array of Programs. Create a Function Block for this purpose instead of a program. You can create an array of FB instances and call each instance in a loop.
Last updated: 2024-09-03
Post by ph0010421 on Stack overflow with really simple function
CODESYS Forge
talk
(Post)
Hello I wouldn't call an FB from inside a FUN; it feels wrong to me. I have had something similar. Try declaring the FB instances as GlobaVars rather than the instance memory.
Last updated: 2024-09-17
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.