Post by elektron785 on GPIO mit Codesys Virtual Control for Linux ARM64 SL
CODESYS Forge
talk
(Post)
Hallo zusammen, ich möchte an einem Entwicklungsboard auf dem der i.MX 8M Plus von NXP aufgesteckt ist die vier zur Verfügung gestellten GPIOs als Ausgänge verwenden. Ich habe mir dazu die Readme-Datei des GPIO-Beispiels von "C:\Program Files\CODESYS 3.5.20.40\CODESYS\CODESYS Control SL Extension Package\4.14.0.0\Examples\GPIO" angeschaut Die Übersicht der verfügbaren GPIOs sieht folgendermaßen aus - wobei ich das auf die reduziert habe, die für mich von Interesse sind: gpiochip0: GPIOs 0-31, parent: platform/30200000.gpio, 30200000.gpio: gpio-0 (SODIMM206 ) gpio-1 (SODIMM208 ) gpio-2 ( ) gpio-3 ( ) gpio-4 ( |sd-vsel ) out hi gpio-5 (SODIMM210 ) gpio-6 (SODIMM212 ) gpio-7 (SODIMM216 ) gpio-8 (SODIMM218 ) gpio-9 ( ) gpio-10 ( ) gpio-11 (SODIMM16 ) gpio-12 (SODIMM155 |regulator-usb1-vbus ) out lo gpio-13 (SODIMM157 ) gpio-14 (SODIMM185 |regulator-usb2-vbus ) out hi gpio-15 (SODIMM91 )** Füge ich nun das GPIO (1 Bit)-Gerät in meinem Codesys-Programm hinzu funktioniert der Bus solange bis ich die Richtung in den GPIO-Parametern von "not used" auf "Output" stelle (siehe Bild gpio_parameter). Dann funktioniert nach Download der Bus nicht mehr. Gibt es noch eine andere Möglichkeit das zu steuern oder muss ich noch Einstellungen tätigen? Für die Zeile mit dem echo (export/unexport) aus dem Beispiel fehlen mir trotz sudo die Zugriffsrechte. "The Kernel Linux has deprecated GPIO user space SysFS. However, the kernel config CONFIGGPIOSYSFS is still enabled on Toradex's BSP to support customers using it in their legacy applications. You can check the configuration by running zcat /proc/config.gz | grep CONFIGGPIOSYSFS. For GPIO access from userspace, the new char device API, also known as libgpiod, must be used." Dies steht in der Verwendung der GPIOs - eine Ausführung des zcat-Kommandos liefert ein =y zurück.
Last updated: 2025-03-17
Post by dnordenberg on BOOL variable in OPC UA and modbus simultaneously
CODESYS Forge
talk
(Post)
How can I have an BOOL variable that is read/write in both modbus TCP server and from OPC UA at the same time? Variables with %MX.n %QX.n addressing which is used for BOOL/coils in modbus server is not allowed in OPC UA symbol list on Schneider M251 controllers. I have already asked on Schneiders forum but there are not a lot of codesys experts over there :( So OPC symbols can't have a address and the modbus TCP server needs a address. So how should I do it then? It seems like an impossible combination. Since I want read/write access from both ways I can't just simply make a second variable and assign it the value of another since it would be a one way assignment. I also tried using VAR_CONFIG which then makes the address syntax %Q or %M in my main variable list and that fools OPC UA Symbol Configuration to allow it and then I add the complete %MX.n address of it in the VAR_CONFIG list. This semi works, I can toggle the BOOL from modbus but the OPC UA symbol seems to be read only. It displays symbol status but nothing happens when I toogle it. I think I need another way to have the variables and symbols pointing to the same bits in memory... My plan B is to write a BOOL array compare FB that saves a history bit from previous cycle and if that does not match current status at next cycle for either the OPC symbol or the modbus variable then it copies the new status over to the other. Maybe ugly but it's like my last alternative. Kind regards David
Last updated: 2025-07-14
Post by timvh on Get Alarm status in Codesys
CODESYS Forge
talk
(Post)
You are right, that you can use the GetState method, but it is not that simple. You first have to get a list of (filtered) alarms from the AlarmManager. You can find an example in Forge how to do this. See https://forge.codesys.com/prj/codesys-example/alarm-manager/home/Home/ Then you can go through this list to get the state of all the (filtered) alarms. See below the code which you could use. This is all based on the example from forge. Create a program: // This example shows how to access alarms via structured text. PROGRAM PLC_PRG VAR xInit : BOOL := TRUE; udiResult : UDINT; fbAlarmFilterCriteriaAll : FB_AlarmFilterCriteriaAll; fbAlarmManagerClient : FB_AlarmManagerClient; itfAlarmManagerClient : IAlarmManagerClient := fbAlarmManagerClient; xAlarm1 : BOOL; xAlarm2 : BOOL; xWarning : BOOL; iNrOfAlarmsInAlarmList : INT; iNrOfActiveAlarmsInAlarmList : INT; paitfAlarm: POINTER TO ARRAY [0..0] OF AlarmManager.IAlarm; iAlarmIndex : INT; eAlarmState: AlarmManager.AlarmState; END_VAR IF xInit THEN xInit := FALSE; fbAlarmManagerClient.itfAlarmFilterCriteria := fbAlarmFilterCriteriaAll; // register alarm client to get updated about alarm status / changes udiResult := AlarmManager.g_AlarmHandler.RegisterClient(itfAlarmManagerClient, 0, 0); END_IF // Polling the number of alarms udiResult := AlarmManager.g_AlarmHandler.GetActiveAlarms(itfAlarmManagerClient, parritfActiveAlarms => paitfAlarm, iCountActiveAlarms => iNrOfAlarmsInAlarmList); iAlarmIndex := 0; iNrOfActiveAlarmsInAlarmList := 0; WHILE iAlarmIndex < iNrOfAlarmsInAlarmList DO eAlarmState := paitfAlarm^[iAlarmIndex].GetState(); IF eAlarmState = AlarmManager.AlarmState.Active OR eAlarmState = AlarmManager.AlarmState.ActiveAcknowledged THEN iNrOfActiveAlarmsInAlarmList := iNrOfActiveAlarmsInAlarmList + 1; END_IF iAlarmIndex := iAlarmIndex + 1; END_WHILE See below some details about the function blocks: One function block should implement the IAlarmFilterCriteria interface. This can be empty except a few methods. FUNCTION_BLOCK FB_AlarmFilterCriteriaAll IMPLEMENTS AlarmManager.IAlarmFilterCriteria Method implementation (others related to interface are empty) METHOD AreAllAlarmClassesSelected : BOOL AreAllAlarmClassesSelected := TRUE; METHOD AreAllAlarmGroupsSelected : BOOL AreAllAlarmGroupsSelected := TRUE; METHOD GetPriorityFrom : USINT GetPriorityFrom := 0; METHOD GetPriorityTo : USINT GetPriorityTo := 255; The other function block should implement IAlarmManagerClient and get a reference to the FB which implements the IAlarmFilterCriteria FUNCTION_BLOCK FB_AlarmManagerClient IMPLEMENTS AlarmManager.IAlarmManagerClient VAR_INPUT itfAlarmFilterCriteria: AlarmManager.IAlarmFilterCriteria; END_VAR Method implementation (others related to the interface are empty) METHOD GetFilterCriteria : AlarmManager.IAlarmFilterCriteria // see VAR_INPUT for filter GetFilterCriteria := itfAlarmFilterCriteria; Off course you have to add the AlarmManager to your application and add some alarms to it.
Last updated: 2025-09-02
Post by john-robinson on Limiting Memory Access of an Array to Within its Bounds
CODESYS Forge
talk
(Post)
Recently we had an issue regarding some simple code to calculate a rolling average. The code indexes from zero to 199 to properly store the current input into a circular buffer which then allows us to calculate a rolling average: VAR input_5s : REAL; outs_arr : ARRAY[0..199] OF REAL; i : USINT := 0; END_VAR ___ //this code runs every five seconds, calculating a rolling average outs_arr[i] := input_5s; i := i + 1; output := OSCAT_BASIC.ARRAY_AVG(ADR(outs_arr), SIZEOF(outs_arr)); IF i >= SIZEOF(outs_arr) THEN i := 0; END_IF There is a simple bug in this code where the index will be set to 0 when it has surpassed the length of the array in bytes (800 in this case) rather than larger than the number of reals in the array (200). The solution here is simple, replacing i >= SIZEOF(outs_arr) with i >= SIZEOF(outs_arr)/SIZEOF(outs_arr[0]). In this example when the index increased to 201 and the line outs_arr[201] := input_5s was called, codesys arbitrarily wrote to the address in memory that is where outs_arr[201] would be if the array was that long. I would like to find a way to wrap the codesys array inside of a wrapper class that checks if an input is within the bounds of an array before writing to that value. I know how I would implement that for a specific array, I could create a method or class that takes an input of an array of variable length, ie. ARRAY[*] OF REAL, but I don't know how to make this for any data type. I am wondering if anyone has ever done anything similar to this, or has any better suggestions to ensure that none of the programmers on this application accidentally create code that can arbitrarily write to other locations in memory.
Last updated: 2024-03-05
Post by mp9876 on Device logon problem following fresh install
CODESYS Forge
talk
(Post)
All screenshots are enclosed in MS Word document. NOTE; 4 questions features at the end. Any assistance would be greatly appreciated! Hi everyone, I am still having device logon problem following a fresh install Here are the STEPS I went through following a FRESH CODESYS Win 64 3.5.19.60 install on a different computer. ‘Gateway not configured properly’ when attempting to REFRESH from the Users and Groups. Then did Gateway manage and confirmed it was ok: This message popped out as it was a fresh install: YES then: Initially went with Administrator twice (user & password) but it did not like it. No device is responding to …: Continued by setting a new user Pressed OK and obtained the following message: Stopped and Restarted PLC at that point: Obtained the following: Attempted to login a 2nd time without success. Then I scanned the network to see if matching device can be detected: Only way to get it detected was to remove the tick in the ‘Hide non-matching devices…’ Attempted a WINK but got a return like this one: REFRESH either @ Users and Groups or @ Access Rights returns: Then created user ‘mp’ at Project level ang logged in: Understandably device user mp9876 was not valid for the Project. Device information A few questions comes to my mind following these connection attempts: 1- Gateway not configured properly message pops out because of a non-compatible device ? 2- Why would the device not be compatible ? 3- Any way to make the device compatible ? 4- Any ideas on how to get this connectivity problem to the device solved ?
Last updated: 2024-03-17
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 open on How to create a stopwatch?
CODESYS Forge
talk
(Post)
Hi @ph0010421, I tried the program the TimeTaken is calculated when stop is triggered. I want the TimeTaken to be continuously calculated and counting when a BOOL variable is true. I tried to program this way: Declaration: PROGRAM PLC_PRG VAR bStartStop: BOOL := FALSE; // Start/Stop button bReset: BOOL := FALSE; // Reset button bRunning: BOOL := FALSE; // Flag indicating whether the stopwatch is running tStartTime: TIME; // Variable to store the start time tElapsedTime: TIME; // Variable to store the elapsed time END_VAR Implementation: // Main program logic IF bReset THEN // Reset button pressed, reset the stopwatch bRunning := FALSE; tElapsedTime := T#0s; ELSIF bStartStop THEN // Start/Stop button pressed, toggle the running state IF bRunning THEN // Stop the stopwatch bRunning := FALSE; ELSE // Start the stopwatch bRunning := TRUE; tStartTime := tElapsedTime; END_IF; END_IF // Update the elapsed time when the stopwatch is running IF bRunning THEN tElapsedTime := tElapsedTime + T#1s; // Adjust the time increment as needed END_IF However counting of the seconds is not accurate. I tried changing the main task cycle time interval to 1000ms. The counting of seconds become slower. (see attached) Please help
Last updated: 2023-12-08
Post by pouyavakili on Execute Codesys Tests with python
CODESYS Forge
talk
(Post)
Thank you for your input! What I'm ultimately trying to achieve is automated test execution as part of a CI/CD pipeline (e.g. in GitLab or Azure DevOps). For this, I need to: Open a CODESYS project via script Build the project Run the Test Manager tests from a .TestRepository.xml Collect test results (e.g., pass/fail + a report) Exit with a proper return code (for pipeline success/failure) To integrate this into automation, I’m using the CODESYS scripting engine via Python (headless), but the issue is that the get_testmanager() function isn't available on the project object — even though Test Manager is installed, licensed, and works interactively in the IDE. Are you suggesting that I should: Use the Test Manager GUI to script the logic with its internal scripting language? Or is there a way to launch the Test Manager in headless/scripted mode, while still being able to control things via Python? If there's a supported way to automate tests with the Test Manager using scripting, especially from pipelines or headless environments, I’d really appreciate any pointers or example workflows. Thanks again!
Last updated: 2025-07-24
Post by imdatatas on MC_MoveAbsolute: C0138: No matching 'FB_Init' method found for instantiation of SMC_MoveAbsRelPerformerImpl [ERROR]
CODESYS Forge
talk
(Post)
Dear @gseidel, Thank you for your reply. The exact version of Codesys and its compiler was 3.5.21.20. The compiler version was fixed and could not be changed in project settings. Since I couldn't continue due to this compilation error, I temporarily overcame this issue as follows. -- I completely uninstalled Codesys 3.5.21.20 and completely deleted the Codesys folder in the C:\ProgramData folder. -- I restarted my computer and installed Codesys 3.5.19.70. -- I updated the Codesys Installer and all its add-ons to the latest versions. -- The project that was giving me the compilation error I mentioned before is now open with Codesys 3.5.19.70, compiled it, and successfully downloaded it on the device. -- I haven't encountered the same problem anymore. I think this issue is related to SP21 and its compiler. Frankly, I'd expect a project created with an older version to compile without errors after opening it with the latest Codesys version and updating all libraries. Regards, imdatatas
Last updated: 2025-09-26
Post by jrsantab on Remote connection to ifm PLC & HMI
CODESYS Forge
talk
(Post)
We have finally solved the problem. The version of the Gateway in the computer that worked (3.5.11.0) and the one that didn't (3.5.17.30) was different. We have three different Codesys 3.5 versions installed because we work with different controllers. I believe that, depending on the sequence you follow to install the versions you get a different Gateway version. To solve the problem you first have to disable the "obsolete" services. Open services, serach for (in our case) CODESYS Gateway V3 Version 3.5.11.0 CODESYS ServiceControl Version 3.5.11.0 I stopped the services and changed to Manual Start. Then you have to create the new services. In our case, from a Command Prompt session (cmd): SC CREATE "Codesys GatewayService Rigual" binpath="C:\Program Files\CODESYS 3.5.17.30\GatewayPLC\GatewayService.exe" and then SC CREATE "CODESYS ServiceControl Version 3.5.17.30" binpath="C:\Program Files\CODESYS 3.5.17.30\GatewayPLC\CODESYSControlService.exe" remember also to set them as Automatic Start!
Last updated: 2024-04-22
Post by struccc on Inheritence of struct,
CODESYS Forge
talk
(Post)
Strangely reminds me to my struggles... Want to do something "Elegant", reusable, universal, practical... In CODESYS??? 🙃 First of all, before you get too deep into this: If you could find a way, to make a "universal" log entry object, containing the variable length data itself, you wouldn't be able to store them in an array, or access them like an array, or pass them by value as a type. (please correct me, if I'm wrong, incorrect, or not precise). Because... Basically you can't declare a type with variable memory footprint. This is a very deeply embedded characteristic of CODESYS, and all IEC 61131-3 systems, and it has many reasons behind. And yes, it is a very common trap / mistake, to forget about. So, with a log entry - I guess - it's pretty much the purpose: store data and metadata together, and then handle it in a uniform way. There are ways to handle this, really depends on what is the purpose. For example: 1. Entries with fixed length (Maybe it is not as evil as it looks for the first time. Depends on the situation, but definitely the fastest and easiest code) You can have your base object, with an internal, fixed length string or byte array variable. I would go with a string, and call it _Data.; And then you can make properties, like As_Bool, As_Int, As_Real... In the 'set' accessors, you can do like: pReal := ADR(_Data); // POINTER TO REAL As_Real := pReal^; In the 'get' accessors, evidently: pReal := ADR(_Data); // POINTER TO REAL pReal^ := AS_Real; Or, can use ANY type, if you are not obsessed with variable / property like access: 2. Fixed length, but nicer First, some disadvantage to any values: - You can only assign values with write access. No literals, constants, etc... - Can only be used as input variable of function or function_block - Therefore, stg you could reach: LogEntry.Initialize (stVariable|rVariable|iVariable|xVariable); Just a quick example (it's funny to play with ANY): Be careful it was not tested. I'm sure can be done better, please feel free to comment FUNCTION_BLOCK FB_LogEntry VAR_INPUT MsgClass : UDINT; // Like DEBUG, WARN, ERR... MsgCode : UDINT; // Like Errors.ERR_FAILED MsgTS : DT; // The timestamp END_VAR VAR _Data : STRING(80); // Our data container... _Descr : __SYSTEM.AnyType; // A standard descriptor for our data, containing TYPE_CLASS, address and size END_VAR METHOD SET_Value : BOOL VAR_INPUT anyValue : ANY; END_VAR VAR I : DINT; diSize : DINT; pStr : POINTER TO STRING; END_VAR // Check what did we receive in anyValue. diSize := anyValue.diSize; // We use constant __SYSTEM.TYPE_CLASS to identify the received data type CASE anyValue.TypeClass OF // Maybe we don't want to store references, pointers... and who knows what else... __SYSTEM.TYPE_CLASS.TYPE_REFERENCE, __SYSTEM.TYPE_CLASS.TYPE_POINTER : SET_Value := FALSE; // For the planned types we will be just fine. TYPE_CLASS.TYPE_BOOL, TYPE_CLASS.TYPE_INT, TYPE_CLASS.TYPE_REAL : SET_Value := TRUE; // Optionally string can be handled separately, maybe we have received STRING(255), but practically it is shorter than 80 bytes... TYPE_CLASS.TYPE_STRING : pStr := anyValue.pValue; diSize := MIN(anyValue.diSize, LEN(pStr^) + 1); // Get the actual size, and rewrite the received structure member diSize := MIN(SIZEOF(_Data), diSize); // Can chop down the received string to our length... SET_Value := TRUE; // Maybe want to play a little bit more here, to narrow down or convert datatypes, etc... // Or just reject any other datatype ELSE SET_Value := FALSE; RETURN; END_CASE // Fail, if the received value is still larger than our container... IF diSize > SIZEOF(_Data) THEN SET_Value := FALSE; END_IF // Here we should be ok, just set up the _DataType structure, and copy store the data IF SET_Value THEN THIS^._Descr.TypeClass := anyValue.TypeClass; // The typeclass is already filtered THIS^._Descr.diSize := diSize; // Set the (adjusted) size THIS^._Descr.pValue := ADR(_Data); // This will not change, just to be sure {IF defined (pou:SysMem.SysMemCpy)} SysMem.SysMemCpy(_DataType.pValue, anyValue.pValue, TO_UDINT(anyValue.diSize)); {ELSE} // An ugly replacement MemCpy FOR I:=0 TO diSize - 1 DO _Descr.pValue[I] := anyValue.pValue[i]; END_FOR {END_IF} // Otherwise, in case of failure maybe better set an empty value (overwrite the former data descriptor) ELSE THIS^._Descr.TypeClass := TYPE_CLASS.TYPE_NONE; THIS^._Descr.pValue := ADR(_Data); THIS^._Descr.diSize := 0; END_IF METHOD GET_Value : BOOL VAR_INPUT anyValue : ANY; END_VAR VAR I : DINT; END_VAR // We just have to serve the data, using the __System.AnyType structure received // Roughly we can say: IF anyValue.TypeClass = _Descr.TypeClass AND anyValue.pValue <> 0 // This should not be possible, already taken care of by Codesys (?) THEN {IF defined (pou:SysMem.SysMemCpy)} SysMem.SysMemCpy(anyValue.pValue, _DataType.pValue, TO_UDINT(MIN(anyValue.diSize, _Descr.diSize))); {ELSE} // An ugly replacement MemCpy FOR I:=0 TO MIN(anyValue.diSize -1, _Descr.diSize - 1) DO anyValue.pValue[I] := _Descr.pValue[I]; END_FOR {END_IF} // Just to make sure, that our string is terminated... IF anyValue.TypeClass = TYPE_CLASS.TYPE_STRING THEN anyValue.pValue[anyValue.diSize -1] := 0; END_IF GET_Value := TRUE; RETURN; END_IF // ... But can play more CASE anyValue.TypeClass OF TYPE_CLASS.TYPE_WSTRING : ; // Could do conversion TYPE_CLASS.TYPE_XSTRING : ; // Wow, I have to figure this out TYPE_CLASS.TYPE_PARAMS : ; // BTW, what is this, how to use? TYPE_CLASS.TYPE_ANYNUM : ; // ... END_CASE Be careful it was not tested. I'm sure can be done better, please feel free to comment 3. If you really want to do entries with variable size In a standard environment, it would be similar to the previous, except you dont have the container variable _Data, just use a pointer, practically _Descr.pValue At Initialize (SET_Value), you have to allocate the memory, would be easy with SysMem.SysMemAlloc - nowadays with SysMem.SysMemAllocData -, and you make sure to release it after use with SysMem.SysMemFreeData... SysMemAlloc was already hidden. The problem with this, that sooner or later your application will totally fragment the dynamic memory, and fail... So should look for some form of dynMaybe MemUtils.MemoryManager (I am not sure what is the status and the future of it). 4. You will end up by a LogEntry Factory ... 5. You could still have a look at this IEC Snippets BTW, Standard Codesys Logger is not a bad choice either. If you are really interested, I share some more code / library.
Last updated: 2025-03-09
Post by struccc on Application failing to boot after system reboot
CODESYS Forge
talk
(Post)
I started to experience the same issue, after upgrading to 3.5.19 , and still persists with 3.5.20.3 , using CodesysControlWinV3 x64 on Windows. Unfortunately, this is a live application, normally it is running for months without interruption - so it was a surprise at the last cold start... It was not possible to go online with the original version, so I couldn't see the application, or system status, just the log message. First time I manually clean the Application from the PlcLogic directory (there was no coredump file in there), then I could start the runtime service, and do a fresh download, and set the bootproject. I could not try a cold system reboot - it's in a 24/7 production environment, and I was under heavy pressure to start... What I did, I have created a backup from the * complete * runtime directory, from the failed, and fixed version - before and after download. This directory in my case C:\ProgramData\CODESYS\CODESYSControlWinV3x64\55096128 - At the next shutdown, it was sufficient to copy back this backup completely, and could start the runtime service afterwards. Ugly, but local staff with some skills can do it without programming tool... I don't store any live data, configuration, log files, persistent data in this directory - the only reason I need this is to edit the CodesysControl... .cfg file.... And to see the logfiles in emergencies like this. The application concerned doesn't use any retain area. - exactly for these reasons - Maybe that is causing the problem with the newer runtime versions As far as I see, this problem occurs only if the power of the Windows PLC is interrupted without a proper shutdown. Unfortunately, this can happen sometimes. The newer versions, seems tp modify CodesysControl.cfg on the fly, and register the applications, and bootproject information after download. (I don't really see CodesysControl.cfg a proper location for this... but that's just my feeling) So now I had a look at CodesysCotrol.cfg on my laptop and I found: [CmpRetain] ;Retain.SRAM.Size=0x200200 ;Retain.SRAM.Address=0xFA3C5776 ;SimulateSRAM=1 [CmpApp] ;Bootproject.CreateOnDownload=0 ;Bootproject.StoreOnlyOnDownload=0 ;Bootproject.InvalidateByRename=1 ;Bootproject.InvalidateBySetting=1 ;Bootproject.InvalidateNever=0 ;PersistentForce=0 ;RetainType.Applications=InSRAM ;RetainType.Applications=OnPowerfail ;RetainType.Applications=None ;Exception.Hardware.GlobalStop=1 Application.1=MyTestAppNoRetain The last line appeared after download and boot project creation. Maybe... Should set RetainType.Applications=None? I wonder about all these settings, but... Will write separately about it. I hope this helps a little...
Last updated: 2024-11-21
Post by patrik on Wish: CODESYSControl.cfg - again
CODESYS Forge
talk
(Post)
Really good post. I hope that it gets seen by CoDeSys staff. I often find the documentation lacking when it comes to using CoDeSys in more complex ways. If using standard "basic PLC functionality", then it's fine and functions are documented in a sufficient way. Once you go outside of that bubble then I find the documentation not enough. CODESYSControl.cfg is a good example of this. And why isn't more of this integrated in the IDE. like changing port of the webserver. Why is it hidden in this file and not accessible through the IDE. It feels like a layer of complexity purposely left in so you don't change it if you don't know what you are doing. Like the argument is if you have the know-how to find the file you have the know-how to edit it. I find the documentation lacking when it comes to more complex libraries too. Like the element collections library. there is parameters I still don't quite know what they do. I can't find any documentation about them. There is an example project to download from CoDeSys so you can see how you are supposed to set your factories up. I leave some parameters like it is in the example. Should I? I don't know. Does it work. Yes. But I could perhaps create memory leaks if I get something wrong and I don't see that until way later. In the create method of your element factory you have a function called __vfinit and you just have to accept that it works. Why can't I get insight in what it does through documentation? Don't CoDeSys want us to know how these work so we can't use them to accidentally break something? I find the error logging lacking too. I've had the CoDeSys service crash but it doesn't say why. I've seen windows noticing the crash but no error code was sent or error message. Also in my current issue where the application fails to start after power outage. I can see in the log that it fails to load retain in the application as one log entry and application failing to start as another. But why? Why does loading the retain fail? give me more information! Is it just a skill issue with me? I don't know. If it is then I'd still want CoDeSys to step up their game when it comes to documentation. I'm sorry if a lot of frustration comes though in this post. I really like the product and what I can do with it compared to other PLC brands.
Last updated: 2024-11-21
Post by bertus on Can't get SMC_SmoothPath to work
CODESYS Forge
talk
(Post)
Hello all, I am trying to run a XY trajectory from a static G-Code file. Everything works except the smoothing/blending of the corners. My setup: Codesys v3.5sp18 Raspberry Pi 4 CODESYS Control for Raspberry Pi SL, using demo license. Zero axes (only using the interpolator). The order of processing for my decoding is: SMC_NCDecoder (ok) SMC_SmoothMerge (ok) SMC_SmoothPath (not ok) SMC_LimitDynamics SMC_CheckVelocities I created following instances and buffers: fbNCDecoder: SMC_NCDecoder; fbSmoothMerge: SMC_SmoothMerge; fbSmoothPath: SMC_SmoothPath; fbLimitDynamics: SMC_LimitDynamics; fbCheckVelocities: SMC_CheckVelocities; aNCDecoderBuffer: ARRAY[0..49] OF SMC_GeoInfo; // buffer stage 1 (fbNCDecoder) aSmoothMergeBuffer: ARRAY[0..19] OF SMC_GeoInfo; // buffer stage 2 (fbSmoothMerge) aSmoothPathBuffer: ARRAY[0..99] OF SMC_GeoInfo; // buffer stage 3 (fbSmoothPath) aLimitDynamicsBuffer: ARRAY[0..39] OF SMC_GeoInfo; // buffer stage 4 (fbLimitDynamics) My original G-Code file has a lot of short G1 elements but this example, I reduced it to a simple square: N000 G51 D10 N010 G38 O1 N020 G00 X0 Y0 F50 E1000 E-1000 N030 G01 X0 Y-37.5 N040 G01 X-75 Y-37.5 N050 G01 X-75 Y37.5 N060 G01 X0 Y37.5 N070 G01 X0 Y0 N080 G50 N090 G39 O1 In the Codesys CNC settings, I have these instances activated: SMC_SmoothMerge SMC_SmoothPath SMC_LimitDynamics SMC_CheckVelocities And with those settings (and the path-preprocessing button actived), the G-Code viewer shows the square with nicely blended corners (see attached picture). However, when running it on the PLC, it doesn't blend the corners at all. Below the relevant part of my code. The process is started with bDecode. // stage 1: decoding G-code fbNCDecoder( ncprog := square, bExecute:= bDecode, bAbort:= NOT bDecode, nSizeOutQueue := SIZEOF(aNCDecoderBuffer), pbyBufferOutQueue := ADR(aNCDecoderBuffer) ); // stage 2: merge short linear segments fbSmoothMerge( bExecute := bDecode, poqDataIn := fbNCDecoder.poqDataOut, nSizeOutQueue := SIZEOF(aSmoothMergeBuffer), pbyBufferOutQueue := ADR(aSmoothMergeBuffer), piMaxDifference := PI_MAX_DIFFERENCE, usiMaxDegree := 5, wFeatureFlag := 1, wAdditionalParamNumber := 0, dMinimumCurvatureRadius := D_MIN_CURVATURE_RADIUS ); // stage 3: smooth corners fbSmoothPath( bExecute := bDecode, bAbort := NOT bDecode, poqDataIn := fbSmoothMerge.poqDataOut, eMode := SMC_SMOOTHPATHMODE.SP_SPLINE5_MIN_CURVATURE, eAddAxMode := SMC_SMOOTHPATHADDAXMODE.SPAA_NONE, nSizeOutQueue := SIZEOF(aSmoothPathBuffer), pbyBufferOutQueue := ADR(aSmoothPathBuffer), dAngleTol := D_ANGLE_TOL, bSymmetricalDistances := TRUE, bImprovedSymmetricCuts := TRUE ); // stage 4: keep acc/dec and velocity within limits fbLimitDynamics( bExecute := bDecode, bAbort := NOT bDecode, poqDataIn := fbSmoothPath.poqDataOut, wAxis := 16#07, nSizeOutQueue := SIZEOF(aLimitDynamicsBuffer), pbyBufferOutQueue := ADR(aLimitDynamicsBuffer), bIncludePathSettings := TRUE, dMaxVel := 2500, dMaxAccDec := 10000 ); // stage 5: check the path speed fbCheckVelocities( bExecute := bDecode, bAbort := NOT bDecode, poqDataIn := fbLimitDynamics.poqDataOut, dAngleTol := D_ANGLE_TOL); pathQueue := fbCheckVelocities.poqDataOut; // repeat until MaxDuration ... Any idea what I'm doing wrong? Is smooth path supposed to work at all when using a demo license? Thanks.
Last updated: 2025-12-17
Post by sushela on Temu coupon code "$100 off" â‹™ [acq615756] Extra 30% Discount
CODESYS Forge
talk
(Post)
Shopping online has become more exciting with the emergence of Temu, offering a wide range of products at competitive prices. With our Temu coupon code $100 off, you can save even more on your purchases from this popular e-commerce platform. Get ready to explore amazing deals and discounts that will make your shopping experience truly rewarding. Temu coupon code "$100 off" â‹™ [acq615756] Extra 30% Discount Temu is currently offering an enticing $100 off coupon code for new users, specifically [acq615756], valid for September 2024. This promotion requires a minimum purchase of $250 and is aimed at enhancing the shopping experience for first-time customers. Additionally, there's another code "acq615756", that provides a $100 coupon bundle applicable multiple times, along with an extra 30% discount on select items for both new and existing users. To redeem these offers, users should create an account, shop for eligible products, and apply the respective codes at checkout to enjoy substantial savings on their purchases. The [[acq615756] or [acq615756]] coupon code is designed to provide maximum benefits for shoppers in the USA, Canada, and European nations. This exclusive code unlocks a world of savings, allowing you to enjoy substantial discounts on your favourite items while shopping on Temu. Don't miss out on this incredible opportunity to save big with our Temu coupon $100 off offer. Whether you're a new or existing customer, the Temu 100 off coupon code is your ticket to unbeatable savings across a wide range of products available on the platform. What Is The Coupon Code For Temu $100 Off? Both new and existing customers can enjoy fantastic benefits by using our $100 coupon code on the Temu app and website. The Temu coupon $100 off offer is designed to provide substantial savings on your purchases, making it easier than ever to shop for your favourite items. With the $100 off Temu coupon, you'll be able to stretch your budget further and get more value for your money. Here are the key benefits of using our [[acq615756] or [acq615756]] coupon code: [[acq615756] or [acq615756]]: Flat $100 off on your purchase [[acq615756] or [acq615756]]: $100 coupon pack for multiple uses [[acq615756] or [acq615756]]: $100 flat discount for new customers [[acq615756] or [acq615756]]: Extra $100 promo code for existing customers [[acq615756] or [acq615756]]: $100 coupon for USA/Canada users Temu Coupon Code $100 Off For New Users In 2024 New users can unlock the highest benefits by using our coupon code on the Temu app. The Temu coupon $100 off offer is specifically tailored to welcome first-time shoppers with incredible savings. Don't miss out on this Temu coupon code $100 off opportunity to make your first Temu experience even more rewarding. Here are the exclusive benefits for new users with our [[acq615756] or [acq615756]] coupon code: [[acq615756] or [acq615756]]: Flat $100 discount for new users [[acq615756] or [acq615756]]: $100 coupon bundle for new customers [[acq615756] or [acq615756]]: Up to $100 coupon bundle for multiple uses [[acq615756] or [acq615756]]: Free shipping to 68 countries [[acq615756] or [acq615756]]: Extra 30% off on any purchase for first-time users How To Redeem The Temu Coupon $100 Off For New Customers? Redeeming your Temu $100 coupon is quick and easy. Follow this step-by-step guide to use the Temu $100 off coupon code for new users and start saving: Download the Temu app or visit the Temu website Create a new account or sign in if you already have one Browse through the wide selection of products and add items to your cart Proceed to checkout when you're ready to make a purchase Look for the "Promo Code" or "Coupon Code" field Enter the code [[acq615756] or [acq615756]] in the designated field Click "Apply" to see the discount reflected in your total Complete your purchase and enjoy your savings! Temu Coupon $100 Off For Existing Customers Existing users can also benefit from our coupon code on the Temu app. We value loyal customers, which is why we offer Temu $100 coupon codes for existing users to ensure you continue to enjoy great savings. Take advantage of the Temu coupon $100 off for existing customers free shipping offer to maximise your shopping experience. Here are the exclusive benefits for existing users with our [[acq615756] or [acq615756]] coupon code: [[acq615756] or [acq615756]]: $100 extra discount for existing Temu users [[acq615756] or [acq615756]]: $100 coupon bundle for multiple purchases [[acq615756] or [acq615756]]: Free gift with express shipping all over the USA/Canada [[acq615756] or [acq615756]]: Extra 30% off on top of the existing discount [[acq615756] or [acq615756]]: Free shipping to 68 countries How To Use The Temu Coupon Code $100 Off For Existing Customers? Using the Temu coupon code $100 off as an existing customer is simple. Follow these steps to apply the Temu coupon $100 off code to your purchase: Open the Temu app or visit the Temu website Log in to your existing account Add your desired items to the shopping cart Proceed to checkout when you're ready Look for the "Promo Code" or "Coupon Code" field Enter the code [[acq615756] or [acq615756]] in the provided space Click "Apply" to see the discount applied to your total Complete your purchase and enjoy your savings! Latest Temu Coupon $100 Off First Order Customers can enjoy the highest benefits by using our coupon code during their first order. The Temu coupon code $100 off first order is designed to give you an incredible start to your Temu shopping experience. Whether you're using the Temu coupon code first order or taking advantage of the Temu coupon code $100 off first time user offer, you're in for some fantastic savings. Here are the exclusive benefits for your first order with our [[acq615756] or [acq615756]] coupon code: [[acq615756] or [acq615756]]: Flat $100 discount for the first order [[acq615756] or [acq615756]]: $100 Temu coupon code first order [[acq615756] or [acq615756]]: Up to $100 coupon for multiple uses [[acq615756] or [acq615756]]: Free shipping to 68 countries [[acq615756] or [acq615756]]: Extra 30% off on any purchase for the first order How To Find The Temu Coupon Code $100 Off? Finding the latest Temu coupon $100 off deals is easier than you might think. While some shoppers search for Temu coupon $100 off Reddit threads, there are more reliable ways to access verified and tested coupons. Here's how you can stay updated on the best Temu deals: Sign up for the Temu newsletter to receive the latest coupons and promotions directly in your inbox. Follow Temu's official social media pages on platforms like Facebook, Instagram, and Twitter for exclusive offers and flash sales. Visit trusted coupon websites that regularly update their Temu discount codes and verify their validity. Check the Temu app or website frequently for ongoing promotions and seasonal sales. Join Temu's loyalty program to earn points and access member-exclusive discounts. By using these methods, you'll always have access to the most current and valuable Temu coupon codes, ensuring you never miss out on great savings. Is Temu $100 Off Coupon Legit? Yes, the Temu $100 Off Coupon Legit offer is absolutely genuine. Our Temu coupon code [[acq615756] or [acq615756]] is 100% legitimate and safe to use. You can confidently apply this Temu 100 off coupon legit code to get $100 off on your first order and subsequent purchases. We regularly test and verify our coupon code to ensure its validity and effectiveness. The [[acq615756] or [acq615756]] code is not only legitimate but also offers consistent savings for Temu shoppers worldwide. It's important to note that our Temu coupon code is valid globally and doesn't have an expiration date, allowing you to use it whenever you're ready to make a purchase. H2: How Does Temu $100 Off Coupon Work? The Temu coupon code $100 off first-time user offer works by providing a direct discount on your purchase total. When you apply the Temu coupon codes 100 off at checkout, the system automatically deducts $100 from your order amount, instantly reducing your overall spending. This coupon is designed to encourage new customers to try Temu's vast product range while offering significant savings. The discount is applied before taxes and shipping, maximising your savings on the actual product costs. It's a straightforward process that allows you to enjoy premium products at a fraction of their original price, making your first Temu experience even more rewarding. How To Earn Temu $100 Coupons As A New Customer? Earning a Temu coupon code $100 off as a new customer is simple and rewarding. The easiest way to get your hands on a 100 off Temu coupon code is by signing up for a new account on the Temu platform. Upon registration, Temu often provides new users with welcome bonuses, which can include substantial discount coupons like the $100 off offer. Additionally, you can earn more coupons by referring friends, participating in Temu's promotional events, or following their social media accounts for exclusive deals. Keep an eye out for seasonal promotions and flash sales, which often feature high-value coupons for new customers. H2: What Are The Advantages Of Using The Temu Coupon $100 Off? Using the Temu coupon code 100 off comes with numerous advantages that enhance your shopping experience. Here are the key benefits of applying the Temu coupon code $100 off to your purchases: $100 discount on your first order, significantly reducing your initial spend $100 coupon bundle for multiple uses, allowing you to save across several purchases 70% discount on popular items, making premium products more accessible Extra 30% off for existing Temu customers, rewarding your loyalty Up to 90% off on selected items during special promotions Free gift for new users, adding extra value to your purchase Free delivery to 68 countries, saving you money on shipping costs Temu $100 Discount Code And Free Gift For New And Existing Customers The Temu $100 off coupon code offers multiple benefits for both new and existing customers. By using our $100 off Temu coupon code, you'll unlock a world of savings and extras that make your shopping experience even more rewarding. Here are the key benefits you can enjoy with our [[acq615756] or [acq615756]] coupon code: [[acq615756] or [acq615756]]: $100 discount for the first order [[acq615756] or [acq615756]]: Extra 30% off on any item [[acq615756] or [acq615756]]: Free gift for new Temu users [[acq615756] or [acq615756]]: Up to 70% discount on any item on the Temu app [[acq615756] or [acq615756]]: Free gift with free shipping in 68 countries including the USA and UK Pros And Cons Of Using The Temu Coupon Code $100 Off This Month Before you use the Temu coupon $100 off code, it's important to consider both the advantages and potential limitations. Here are the pros and cons of using the Temu 100 off coupon this month: Pros: Significant savings of $100 on your purchase Applicable to a wide range of products on Temu Can be combined with other ongoing promotions for maximum savings No minimum purchase requirement Valid for both new and existing customers Cons: May not be applicable to certain limited edition or already discounted items The coupon might have a usage limit per account Terms And Conditions Of Using The Temu Coupon $100 Off In 2024 When using the Temu coupon code $100 off free shipping offer, it's essential to be aware of the terms and conditions. Here are the key points to remember about our latest Temu coupon code $100 off: Our coupon code [[acq615756] or [acq615756]] has no expiration date, allowing you to use it at your convenience The code is valid for both new and existing users in 68 countries worldwide There are no minimum purchase requirements for using our Temu coupon code [[acq615756] or [acq615756]] The discount is applied to the total purchase amount before taxes and shipping The coupon cannot be combined with certain promotional items or flash sale products Temu reserves the right to modify or cancel the promotion at any time The coupon is for personal use only and cannot be transferred or sold Final Note: Use The Latest Temu Coupon Code $100 Off Don't miss out on the incredible savings offered by our Temu coupon code $100 off. This exclusive discount is your gateway to a world of affordable, high-quality products available on the Temu platform. Remember to apply the Temu coupon $100 off during checkout to maximise your savings. Happy shopping, and enjoy your Temu experience! FAQs Of Temu $100 Off Coupon Q: How often can I use the Temu $100 off coupon? Ans: The usage frequency of the Temu $100 off coupon may vary. Generally, it's designed for one-time use per account, especially for new customers. However, some promotions may allow multiple uses or offer a coupon bundle. Always check the specific terms of the coupon you're using. Q: Can I combine the $100 off coupon with other Temu promotions? Ans: In most cases, yes. The Temu $100 off coupon can often be combined with other ongoing promotions or discounts on the platform. However, some exclusions may apply, particularly for limited-time offers or already heavily discounted items. Always review the terms and conditions of each promotion. Q: Is there a minimum purchase amount required to use the $100 off coupon? Ans: Typically, there is no minimum purchase amount required to use the Temu $100 off coupon. However, to maximise your savings, it's best to use the coupon on orders exceeding $100. Always check the specific coupon terms as requirements may vary for different promotions. Q: How do I know if my Temu $100 off coupon has been applied successfully? Ans: After entering the coupon code at checkout, you should see an immediate reduction in your total order amount. The discount will be clearly displayed in your order summary. If you don't see the discount applied, try re-entering the code or contact Temu customer support for assistance. Q: What should I do if my Temu $100 off coupon isn't working? Ans: If your coupon isn't working, first ensure you've entered the code correctly. Check if the coupon has expired or if you've already used it. If issues persist, clear your browser cache or try using a different device. For further assistance, contact Temu's customer support team who can help resolve any coupon-related problems.
Last updated: 2024-10-26
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 climblinne on Calling OPC UA Methods from UaExpert
CODESYS Forge
talk
(Post)
Hello, I hope someone could help me. I installed the newest Codesys 3.5 SP 20 Patch 1. When loading the demo files from @i-campbell I can upgrade them to the latest version and everthing works on the OPC-UA client side as expected (object "a" is visible, I can use the "ExampleMethod"). Now I * remove the "Information Model", * delete the "OPC_UA_Symbols Objects", * Add "Information Model" again * add "TestRootObjectType" again and "Generate IEC declarations" * and search for mapped instances (to get instance "a" again) Very good still working as expected. Now I delete the OPC_UA_Symbols and add it again referring to the "objecttest" from 16.9.2020. Also I redo the steps from above. The result is now, that I can't see the "a" object in the "Root/Objects" folder. Why ist this and how can I make it running? I think, it could may be a different version of the UA configuration file. I tried to build my own model definition files and got the same problem (but I am really not an expert). When someone has a actual model, which is also running in the actual Codesys I would be very grateful. Or even better, how to make the correct model in e.g. UA Modeler SW (I followed the description https://documentation.unified-automation.com/uamodeler/1.6.0/html/howprojnet_sec.html).
Last updated: 2024-07-01
Post by dekelec on Codesys 2.3 & Peak PCAN
CODESYS Forge
talk
(Post)
I use Peak USB adapter daily to download from CoDeSys 2.3 and 3.5 to IFM, EPEC and other controllers. The process: - First you need to install the appropriate driver. Link: https://www.peak-system.com/Drivers.523.0.html?&L=1 - Restart the computer - Start the CoDeSys application - Change the name of the adapter in Communication parameters, as mentioned in previous comment. Write the name exactly as written "Peak_USB", as it could also be case sensitive (defines which .dll file to use). If this doesn't work I would contact the vendor of the controller to find out the procedure. In the attachment I've added a FAQ document from IFM regarding using PCAN USB. P.S. I've noticed in your picture of communication parameters a channel via TCP/IP is mentioned. In this case a USB to CAN connection is not being used. First you should change the channel/gateway to connect via CANbus or connect using an Ethernet cable.
Last updated: 2024-07-09
Post by faceplant on CmpDynamicText unresolved references
CODESYS Forge
talk
(Post)
Hello! I am new to codesys so I am sorry if this is not the right place to ask this question. I am using codesys V3.5 SP20 Patch 1 + (64-bit) and a Groov EPIC PLC (GRV-EPIC-PR2). I am trying to build and deploy my application to the PLC, but when I log in I get 6 errors (codesys_error.png). It seems that the errors have to do with the CmpDynamicText system library which I have as version 3.5.20.0. I have tried to add CmpDynamicText to the ComponentManager section in the PLC's CODESYSControl.cfg file as described in this forum post and still hit the same error. I noticed that the library is grayed out in the library manager, which I think might be the issue. However I don't remember if it was grayed out before I encountered this issue. Please let me know if I can provide anymore info. Thank you!!!
Last updated: 2024-07-19
Post by abauza on Image Pool using in other libraries
CODESYS Forge
talk
(Post)
Hi im Albert, im developing libraries for my PLCs and i have some issues on visualization part. First of all I have done a library that have a image pool with a list of 4 gifs "ImagePoolErrors" (i've tested in other projects and it works) but the problem comes when i create another library that in the visualization part contains images from my image pool library, when i simulate a program that includes a instance of my second library object the visualization images dont show, any of them, i've checked all the references and tried some options of the image properties but without any difference. Here is the screenshots of the first library (that contains Image Pool) and the second library (that includes images of the image pool first library) and the visualization simulation (with the missing image gif issue). Any idea of what i forgotten in the process? If you need any detail of the library or of the project or you need the library file, ask me, thank on advance
Last updated: 2024-08-19
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 dominggus on FileDialog - OnDialogClosed not called anymore
CODESYS Forge
talk
(Post)
Hi, since the latest update it seems the OnDialogClosed is not called anymore?? using CODESYS SP20 Patch 3 with CODESYS Visualization 4.6.0.0 I am using LoadWriteRecipe to load a recipe file from disk (with some custom dialog settings), and I need to run a function (Recipes_LoadFromRecipeData()) afterwards which I execute when OnDialogClosed is closed with OK button. See attached screenshot and code below: *** OnDialogClosed : Recipes_OnLoadFileDialogClosed(pClientData): *** // 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 Recipes_LoadFromRecipeData(); END_IF END_IF END_IF *** OnMouseClick: Execute ST-Code *** // override FileOpenSave Dialog settings // Visu_FbFileListProvider.Initialize(stDirectory, stFilter, stFileIn, stTitle, iRowCount, bBrowseDirectory, bTouch) VisuDialogs.g_FileListProvider.Initialize('./', '*.bunkerrecipe', '', 'Load recipe', 20, TRUE, FALSE); VisuDialogs.g_FileListProvider(); This used to work in CODESYS v3.5 SP20 Patch 1, but it seems it doesn't work anymore unfortunately? The OnDialogClosed just never seems to be called anymore....
Last updated: 2024-12-18
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.