VAR_IN_OUT, POINTER TO and REFERENCE TO
CODESYS Forge
talk
(Thread)
VAR_IN_OUT, POINTER TO and REFERENCE TO
Last updated: 2021-11-16
Post by eaglealex on Length of string and Array of bytes
CODESYS Forge
talk
(Post)
Browser's bug... Sorry
Last updated: 2025-04-02
Post by ihatemaryfisher on Sorting array of any-sized structure
CODESYS Forge
talk
(Post)
In my machine's operation, I need to display multiples tables containing arrays of structured variables. The arrays change during operation, and my supervisor has advised me to write a new bubble-sort for each array. I think I can make a function to sort an array of any data type. This was my own project, and I'm a relatively new coder. I want to know the weaknesses in my approach, and a better method, if one exists. As far as I can test, the function accepts an array of a structured variable of any size, and sort it by any VAR in that structure. But it relies heavily on pointers, which I've heard are bad practice? Function call: // SORT BY BYTE-SIZED VAR IF xDoIt[6] THEN FUNBubbleSortSansBuffer( IN_pbySourcePointer := ADR(astArray[1]), // address of first byte in first element of array IN_pbyComparePointer:= ADR(astArray[1].byCompByte), // points to first byte of the comparing variable (variable you sort by) IN_uiStructureSize := SIZEOF(TYPE_STRUCTURE), // size, in bytes, of the structured variable IN_uiCompareSize := SIZEOF(astArray[1].byCompByte), // size, in bytes, of the comparing variable (variable you sort by) diArrayElements := UPPER_BOUND(astArray,1), // number of elements in array IN_xSmallToLarge := xSortOrder // whether to sort by small2large or large2small ); END_IF Function: FUNCTION FUNBubbleSortSansBuffer : BOOL VAR_INPUT IN_pbySourcePointer : POINTER TO BYTE; // points to beginning of array (first byte of first element) IN_pbyComparePointer: POINTER TO BYTE; // points to first byte of the comparing variable (variable you sort by) IN_uiStructureSize : UINT; // size, in bytes, of the structured variable IN_uiCompareSize : UINT; // size, in bytes, of the comparing variable (variable you sort by) diArrayElements : DINT; // number of elements in array IN_xSmallToLarge : BOOL; // whether to sort by small2large or large2small END_VAR VAR j : DINT; // repeat iteration over array until array ends i : DINT; // iterarte over array, swapping when necesary k : DINT; // iterator from 1 to size of structure (stepping 'through' a single element in array) dwSize : DWORD; // internal var for use in MEMUtils.MemCpy(<size>) // FOR SORTING BY BYTE VAR pbySourcePointer : POINTER TO BYTE; pbySourcePointer2 : POINTER TO BYTE; pbyComparePointer : POINTER TO BYTE; pbyComparePointer2 : POINTER TO BYTE; pbyPointerToBuffer : POINTER TO BYTE; // pointer to single byte buffer byBufferByte : BYTE; // single byte buffer END_VAR dwSize := UINT_TO_DWORD(IN_uiStructureSize); // get structure size (number of bytes) pbyPointerToBuffer := ADR(byBufferByte); // assign pointer to address of buffer byte (because MEMUtils.MemCpy requires a pointer input) CASE IN_uiCompareSize OF // depending on the size of the VAR to sort by (current functionality for BYTE and WORD/INT 1: // BYTE (8 BIT) FOR j := 1 TO diArrayElements DO // for number of elements in array FOR i := 1 TO (diArrayElements-1) DO // same thing, but row[i+1] row is included in swap logic pbySourcePointer := IN_pbySourcePointer + dwSize*(i-1); // point at #1 byte in array element[i] pbySourcePointer2 := pbySourcePointer + dwSize; // point at #1 byte in array element[i+1] // NOTE: because of memory locations, each array element is offset from one another by a number of bytes equal to the size of the structure // We can "walk" from array[i] to array[i+1] via steps equal to the size of the structure // e.g., ADR(array[i+1]) == ADR(array[i]) + SIZEOF([array datatype]) pbyComparePointer := IN_pbyComparePointer + dwSize*(i-1); // point to sorting variable in array element[i] pbyComparePointer2 := pbyComparePointer + dwSize; // point to sorting variable in array element[i+1] // using sort order (small -> large/large -> small) IF SEL(IN_xSmallToLarge, (pbyComparePointer2^ > pbyComparePointer^),(pbyComparePointer2^ < pbyComparePointer^)) THEN // This is where it gets tricky. We've identified pointers for the starting bytes of aArray[i] and aArray[i+1] // and we know the size of aArray[i]. We are going to swap individual bytes, one at a time, from aArray[i] and aArray[i+1] // this allows us to use only a single byte var as a buffer or temporary data storage // e.g., consider a structure consisting of a word, a byte, and a string. it is stored like this // |------WORD-------| |--BYTE-| |STRING------...| // astArray[1] == 1000 0100 0010 0001 1100 0011 1010 1010.... etc // astArray[2] == 0001 0010 0100 1000 0011 1100 0101 0101.... etc // performing a single swap (copy into a buffer, etc.) of the first byte of each array element creates this // astArray[1] == 0001 0100 0010 0001 1100 0011 1010 1010.... etc // astArray[2] == 1000 0010 0100 1000 0011 1100 0101 0101.... etc // incrementing the pointer adresses for the swap by 1 and swapping again swaps the next byte in each array element // astArray[1] == 0001 0010 0010 0001 1100 0011 1010 1010.... etc // astArray[2] == 1000 0100 0100 1000 0011 1100 0101 0101.... etc // continuing this from k to SIZEOF(TYPE_STRUCTURE) results in a toally swapped row FOR k := 1 TO IN_uiStructureSize DO // copy single byte[k] of array element 1 to buffer MEMUtils.MemCpy(pbyDest := (pbyPointerToBuffer), pbySrc := (pbySourcePointer+k-1), dwSize := 1); // copy single byte[k] of array element 2 to 1 MEMUtils.MemCpy(pbyDest := pbySourcePointer+k-1, pbySrc := (pbySourcePointer2+k-1), dwSize := 1); // copy buffer to byte[k] array element 2 MEMUtils.MemCpy(pbyDest := (pbySourcePointer2+k-1), pbySrc := pbyPointerToBuffer, dwSize := 1); END_FOR END_IF END_FOR END_FOR
Last updated: 2023-08-17
Post by thn-power on How to change OPC NodeId IdentifierType
CODESYS Forge
talk
(Post)
Hi Yet another OPC UA question. When setting up a OPC server using "Communcation manager" (Symbol set and information model) in Codesys the NodeId is always given as "opaque" type. At least when browsing using UAExpert. Other standard OPC objects use numeric (or string) identifier, but for some reason my variables seems to get opaque/binary type. See attached photo. How can I change this? I can't see that this is a parameter in the CodesysControl.cfg. Can this be specified in the information model nodeset? And is it possible to specify the exact numeric or string NodeId for each instance? And on a related topic, is there a way to export the OPC server nodeId's with variable name so that it can be imported in a OPC Client? The .xml files in the project folder does not seem to contain the NodeId.
Last updated: 2024-09-20
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 smartcoco on Opaque NodeId in the OPC UA server
CODESYS Forge
talk
(Post)
This seems to be because when creating 'OPC UA' with 'Communication Manager', the 'IdentifierType' of 'NodeId' cannot be configured as' String 'type. This issue is not an isolated case. For this issue, CODESYS seems to have not provided guidance to users on how to proceed. We can provide feedback on this issue in the 'My Question' section of the 'CODESYS Store' to make CODESYS take it seriously.
Last updated: 2025-01-10
Post by durallymax on VAR_INFO from inside of a FB to get info on the instance.
CODESYS Forge
talk
(Post)
The help link appears to be broken. When I implemented something similar I had to add {attribute 'reflection} above the declaration of the FB with {attribute 'instance-path'} above the string VAR that would contain the path. Then wrote a function to trim off however much I wanted removed by searching for periods, then formatting it with spaces at the periods and removing brackets on arrays while also breaking up the PascalCase to present it a bit nicer for the end-users.
Last updated: 2025-12-12
Post by peterkcontrols on Copying 2 byte word to output
CODESYS Forge
talk
(Post)
Hello. I am using codesys 3.5. I would like to know if it is possible to set a variable to an output without declaring in. I have defined a STRUCT and within this struct I have a Struct for inputs called I and a struct for outputs called O. I have declared a variable of the type of this Struct, I would like to set or alias the value in this variable to an input/output value of an IO block that has a module on the ethernet tree. Is it possible to copy the contents of %IW0 -> STRUCT.I ? The size of both of these is 2 bytes. I understand that I can declare a variable with the input like Input01 AT %IX0.0 : BOOL; However how can I make STRUCT.I.D00 AT %IX0.0? Is this possible? Thanks
Last updated: 2025-03-03
Post by ellcap on Symbol Configuration, I'm doing it wrong
CODESYS Forge
talk
(Post)
if you're here because you are making the same mistake as me, I just resolved it. I mistakenly thought I didn't need to write the word attribute in the column labeled attribute. changed this 'symbol' := 'read' to this attribute 'symbol' := 'read' The last two in this clip are still wrong: I recongize this is probably a big "duh". That's ok. I like to fail out loud in hopes it helps someone else from looking silly.
Last updated: 2023-08-31
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 captaincookie on increase default string length in queue
CODESYS Forge
talk
(Post)
I solved it by creating a new element of IElement according to the ElementExample (MyElement) in the ElementCollectionsExamples project. The variables in this element can then be defined in any properties as needed.
Last updated: 2023-10-11
Post by opineiro on How to manage variable types larger than 64 bits - Ethernet/IP
CODESYS Forge
talk
(Post)
Thanks, that's what I thought initially. The point is that I can't select a String type variable. See the attached image
Last updated: 2024-09-23
Post by nano on FB string and naming
CODESYS Forge
talk
(Post)
inside the fb, use the reflection-attribute and get the instancename includibg whole path.when im right, the applicationname will also reflected, if yes. you have to trim it. https://content.helpme-codesys.com/en/CODESYS%20Development%20System/_cds_pragma_attribute_instance_path.html
Last updated: 2024-10-02
Post by ph0010421 on Converting each character to a string into ASCII
CODESYS Forge
talk
(Post)
So the printer wants an ASCII conversion of the hex equivalent of ASCII characters?? They don't make it easy for us
Last updated: 2024-11-11
Post by thn-power on Opaque NodeId in the OPC UA server
CODESYS Forge
talk
(Post)
I'm wondering the same. Using the old symbol configurator opc ua server gave the node id using a string. Must be a way to specify this at build time?
Last updated: 2024-12-16
Post by paro on OPCUA array max length?
CODESYS Forge
talk
(Post)
I think the amount of data is already relatively high and maybe it has something to do with that? Maybe also the CPU load of your device? an array with string(5000)? and have you tested with how many array elements it still works?
Last updated: 2024-02-17
Post by damian177 on Visualization - table element
CODESYS Forge
talk
(Post)
Hi, In my application I use table elemnt with filled by STRING ARRAY. I would like to implement the following functionality : When I click on second row, that this row will be cleared. Anyone can help me?
Last updated: 2024-04-25
Post by scrollman on Attribute FB for comment
CODESYS Forge
talk
(Post)
Hello, I can use {attribute 'reflection'} FUNCTION_BLOCK POU VAR {attribute 'instance-path'} {attribute 'noinit'} str: STRING; END_VAR to get name of FB. How I can get the comment of FB, in the same way in the FB? Thank you for your time!
Last updated: 2025-12-31
Post by kevinl on RevPi Connect RS485
CODESYS Forge
talk
(Post)
I figured this out on my own with this logic: usually the Serial port on a Raspberry pi is on /dev/ttyUSB0 then you need to set linux.DeviceFile=/dev/ttyUSB in codesys you then must set com port to 1 so i assumed codesys subtracts 1 from the number and adds this to the filename... (in code it would look like this: var comPort : byte := '1'; linuxDevice : string := '/dev/ttyUSB'; filename : string; end_var filename := concat(linuxDevice, (to_string(comPort-1)); filaname then is /dev/ttyUSB0 RevPi uses ttyRS485 as Serial port so you must remove the last number from the name and set the com port to this number +1 i hope this is understandable ;-)
Last updated: 2023-12-11
Post by jari-koivuluoma on Problem trying Net Base Services 3.5.15.0 TCP connection
CODESYS Forge
talk
(Post)
I have a need to send messages between 2 PLCs and I cant use network variables (because of size limit) so I tried writing this simple test program. This seems to work fine. I can send messages back and forth when a first "Start server" and then "Connect client". See the attached image. However, if I disconnect the client by setting ClientConnect to false and try to re-connect then the TCP_Client just gives me TIMEOUT error. When I stop and start the server again, then Im able to reconnect. How is this supposed to work? Why reconnecting wont work. There is not other way of disconnecting the client than setting xEnable of the TCP_Client to false. This is just a testing program and I will try it on 2 seperate devices once this works. PROGRAM PLC_PRG VAR CONSTANT mySize : UDINT := 255; END_VAR VAR Server: NBS.TCP_Server; ServerIpStr: STRING := '127.0.0.1'; ServerIP: NBS.IP_ADDR; ServerPort: UINT := 50000; ServerConnection: NBS.TCP_Connection; Client: NBS.TCP_Client; ServerRead: NBS.TCP_Read; ServerWrite: NBS.TCP_Write; ServerSend: STRING(mySize); ServerReceive: STRING(mySize); ServerConnect: BOOL; bServerSend: BOOL; IP: NBS.INADDR; ConnectedClientIP: STRING; ClientPort: UINT := 50000; ClientIpStr: STRING := '192.168.1.49'; ClientIP: NBS.IP_ADDR; ClientRead: NBS.TCP_Read; ClientWrite: NBS.TCP_Write; ClientSend: STRING(mySize); ClientReceive: STRING(mySize); ClientConnect: BOOL; bClientSend: BOOL; Error: BOOL; Message: BOOL; END_VAR // Server ServerIP.sAddr := ServerIpStr; Server( ipAddr := ServerIP, uiPort := ServerPort ); ServerConnection( xEnable := Server.xEnable, hServer := Server.hServer, ); IP := ServerConnection.IPAddress; ConnectedClientIP := F_Concat7( BYTE_TO_STRING(IP.S_un_b.s_b1),'.', BYTE_TO_STRING(IP.S_un_b.s_b2),'.', BYTE_TO_STRING(IP.S_un_b.s_b3),'.', BYTE_TO_STRING(IP.S_un_b.s_b4)); ServerRead( xEnable := ServerConnection.xActive, hConnection := ServerConnection.hConnection, szSize := SIZEOF(ServerReceive), pData := ADR(ServerReceive) ); IF ServerRead.xReady AND ServerRead.szCount > 0 THEN Message := TRUE; END_IF IF ServerRead.eError > 0 THEN Error := TRUE; END_IF ServerWrite( xExecute := ServerConnection.xActive AND bServerSend, hConnection := ServerConnection.hConnection, szSize := LEN(ServerSend)+1, pData := ADR(ServerSend) ); IF ServerWrite.xDone THEN bServerSend := FALSE; END_IF IF ServerWrite.eError > 0 THEN Error := TRUE; END_IF // Client ClientIP.sAddr := ClientIpStr; Client( xEnable := ClientConnect, ipAddr := ClientIP, uiPort := ServerPort, udiTimeOut := 10000000 ); ClientRead( xEnable := Client.xActive, hConnection := Client.hConnection, szSize := SIZEOF(ClientReceive), pData := ADR(ClientReceive) ); IF ClientRead.xReady AND ClientRead.szCount > 0 THEN Message := TRUE; END_IF IF ClientRead.eError > 0 THEN Error := TRUE; END_IF ClientWrite( xExecute := Client.xActive AND bClientSend, hConnection := Client.hConnection, szSize := LEN(ClientSend)+1, pData := ADR(ClientSend) ); IF ClientWrite.xDone THEN bClientSend := FALSE; END_IF IF ClientWrite.eError > 0 THEN Error := TRUE; END_IF
Last updated: 2024-10-03
Post by arwie on Use MC_Home without enabling the drive for homing method 35
CODESYS Forge
talk
(Post)
This is a homing routine which is controlled by setting mode of operation and started by setting a bit in the control word. If MC_Home is not usable for this homing method then I need to implement the same functionality. But how?
Last updated: 2025-06-25
Post by talhaali on Adding a variable from text list into ST code
CODESYS Forge
talk
(Post)
Hi, can I use a entry of a text list as variable in structured text? for example in attach picture, if i use want to use data of first row. I am trying to write: A : STRING := TextList.Default.0; but it is not workings
Last updated: 2023-12-07
Post by talhaali on Adding a variable from text list into ST code
CODESYS Forge
talk
(Post)
Hi, can I use a entry of a text list as variable in structured text? for example in attach picture, if i want to use data of first row. I am trying to write: A : STRING := TextList.Default.0; but it is not workings
Last updated: 2023-12-07
Post by williamjmak1 on Current Visu name without Current Visu Variable
CODESYS Forge
talk
(Post)
Hello everyone, I was just wondering if anybody knows if there's a way to pull the string name of the current visualization without using the current visu variable. I'm working on a project where we don't want web clients to change the current visualization on the HMI of the machine. Thanks!!
Last updated: 2025-08-07
Post by george32 on CSV file and string manipulation.
CODESYS Forge
talk
(Post)
Dear folks, I think I have a rather simple question but I could not find the right answer to my question: I have made with Excel a CSV file where I would like to have some general data regarding my program variables. I have made an program what let me read the file. The string I am currently get is at follows: 'IP_Adres;192.168.45.12$R$NPort_number;2000$R$NCycle_time;43$R$NStart_Standard_IO;20$R$N' Now I want to split the string in multiple part, which I later would connect to the right variable. By Google and experimenting I have reached to the following code for the first part of the splitting proces: // Splitting the BOM of the string: Received_string := FileReadString; IF LEFT(STR:=New_string,3)= '' THEN Received_string_without_BOM :=RIGHT(STR:= Received_string,SIZE:= (LEN(STR:= Received_string))-3); END_IF //Splitting the remaining string in part for later declaration. WHILE index = 0 DO index_split_part := FIND(STR1:= Received_string_without_BOM,STR2:= '$R$N'); Part_of_String[index]:=LEFT(STR:=Received_string_without_BOM, SIZE:= index_split_part); index := index + 1; END_WHILE However in the splitting proces I could not understand what is really happening. I understand that the Find() function returns the first value the $R$N in the Received_string_without_BOM. This would mean that the index_split_part := 23 I|P| _ |A |d|r|e|s|;|1_|9 |2 |. |1 |6 |8 |. |4 |5 |. |1 |2 |$ |R |$ |N |P | 1|2| 3 |4 |5|6|7|0|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27| So the next part is to read the first 23 characters of the Received_string_without_BOM with the LEFT() function. I expected that the outcome the following was: 'IP_Adres;192.168.45.12$'. However the outcome is: 'IP_Adres;192.168.45.12$R'. I do not understand where the R after the $ sign comes from, because its place is 24 so it would not be added to the part_of the_string[index]. If I hard coded value 24 for the size it gives me the following return: 'IP_Adres;192.168.45.12$R$N'. I would expect everything till the R but the code adds the $N also to the string. I hope someone could explain to my what I am seeing wrong in my point of view? With kind regards, George
Last updated: 2024-09-27
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.