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 tortilla on J1939 connection between two devices
CODESYS Forge
talk
(Post)
Hey, I'm pretty new to CoDeSys so I don't know a lot of things yet. I have to create a connection between two devices (CANbus - J1939 connection). The idea for now is to send a message from one to another (one operates on 3.5 SP11 the other one on 2.3) I watched a few videos, worked with the documentation and worked with chatGPT 4o and was able to build the attached file. This part is about the device on 3.5.11: I'm using the J1939LocalECUDiag, TransmitParameterGroup, TransmissionTrigger Function blocks to send the message but my TransmitPG.xBusy / .xDone never turns to True and therefore my message is not sent while TransmitPG.xExcecute is True. I added the two devices in the CANbus in the J1939Manager and addapted the options like I've seen in the documentation. Can anyone explain what's wrong with my code in this casse or give me advices how to properly create a connection between my two devices? Thanks in advance!
Last updated: 2024-05-23
Post by svenkaro on Codesyscontrol.service stoppt nach 30s
CODESYS Forge
talk
(Post)
Wie Du schon vermutet hast, es meint, die Hardware/Firmware sei nicht kompatibel ... ooops... this runtime was built for RASPBERRYPI. Hardware version or firmware version not supported! (-18, 0x00000BB8, 0xFFFFFFFB) Architecture: aarch64 Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 Vendor ID: ARM Model name: Cortex-A72 Model: 3 Thread(s) per core: 1 Core(s) per cluster: 4 Socket(s): - Cluster(s): 1 Stepping: r0p3 CPU(s) scaling MHz: 40% CPU max MHz: 1500.0000 CPU min MHz: 600.0000 BogoMIPS: 108.00 Flags: fp asimd evtstrm crc32 cpuid Caches (sum of all): L1d: 128 KiB (4 instances) L1i: 192 KiB (4 instances) L2: 1 MiB (1 instance) Vulnerabilities: Gather data sampling: Not affected Itlb multihit: Not affected L1tf: Not affected Mds: Not affected Meltdown: Not affected Mmio stale data: Not affected Retbleed: Not affected Spec rstack overflow: Not affected Spec store bypass: Vulnerable Spectre v1: Mitigation; __user pointer sanitization Spectre v2: Vulnerable Srbds: Not affected Tsx async abort: Not affected Allerdings habe ich schon reichlich Firmware versionen getestet.
Last updated: 2024-06-21
Post by aris on Modbus write via FB failure
CODESYS Forge
talk
(Post)
Hi all, I am using CoDeSys V3.5 and a soft controller Win V3x64. I am trying to read a modbus slave via Function Blocks and not via the channels of the hardware tree for the Slave. I created some requests of type ModbusRequest and I notice that I can read Input Registers and Coils but I can not write Holding Registers and Coils. I am using the library IoDrvModbusTCP 4.1.0.0. When i just use a single modbus request with FC06 (or FC16), there is no request sent to the slave and although the xExecute takes its true value from a pulse of 2 seconds duration, I take almost every 3 minutes an error "TCP_COMMUNICATION_ERROR - 16#A5 - TCP Port. error. Request was not sent". My code is ok because if i change the function code for reading registers, everything works fine. Did anyone have this issue in the past? Thank you in advance.
Last updated: 2025-11-06
Post by bertus on Can't get SMC_SmoothPath to work
CODESYS Forge
talk
(Post)
Hi Georg, thanks for your time. What is the value of D_ANGLE_TOL? It is set to 0.01. Do you need the assignment bAbort := NOT bDecoder? Does it help to leave it out? This seems to make no difference. Any errors (e.g. SMC_SmoothPath.Error/ErrorID) or PLC log messages? No errors or log messages. What if you comment out SMC_SmoothMerge and SMC_LimtiDynamics, is corner smoothing still not working? Indeed. Is bDecode written from a different task (e.g. visu)? Then I would recommend to assign to a local variable (bDecodeLocal := bDecode) and use that for all FBs. Otherwise, FBs might see different values of bDecode in a single cycle, which will cause problems. It is a local variable, written from a state machine inside this program. But there is new information: During some trial and error, I tried skipping "stage 2: merge short linear segments" (SMC_SmoothMerge). And suddenly it rounds the corners, see attached image. Looking a bit closer, I noticed that (with the original program) after a download (cold start?), it in fact did round the corners, but only once. Ever next cycle in which the NC program was executed, the corners where not rounded. Not sure if there is any relation, but SMC_SmoothMerge is also the only FB which has no bAbort input. Perhaps I need to reset it (or any buffers) by other means?
Last updated: 3 days ago
Post by mondinmr on COL.IMap2 and HashTableFactory cause frequent Access Violation
CODESYS Forge
talk
(Post)
Good morning, Iāve been using the Collection library for a long time, mostly with Stack, LinkedList, and List. From your examples I was able to manage the different factories, even for custom elements. Now I need a hashtable, but with this object Iām running into a lot of random access violations. If I append something inside FB_Init after constructing the hashtable, it crashes, even though the list was already created. If I only create the hashtable in FB_Init and append afterwards, it usually works. I donāt understand the meaning of the dispose call in this code: pSlave := ADR(slave); uSlave := TO_ULINT(pSlave); iKey := fKey.Create(uSlave); IF hash.CountKeys() = 0 THEN Service.logger.appendLog('Filling hashtable', 'HashManager', AdvLogType.AdvDebugMsg); ok := FALSE; ELSE eError := hash.ContainsKey(iKey, xResult => ok); END_IF IF NOT ok THEN pI := __NEW(UINT); iVal := fKey.Create(TO_ULINT(pI)); Service.logger.appendLog(CONCAT('New slave', TO_STRING(uSlave)), 'HashManager', AdvLogType.AdvDebugMsg); hash.AddKeyValuePair(iKey, iVal); appendNewSlave := pI; ELSE eError := hash.GetElementByKey(iKey, itfValue => iElem); xResult := __QUERYINTERFACE(iKey, itfIInstance); IF xResult THEN itfIInstance.Dispose(); END_IF IF eError <> COL.COLLECTION_ERROR.NO_ERROR THEN Service.logger.appendLog(CONCAT('ERROR ', TO_STRING(eError)), 'HashManager', AdvLogType.AdvCriticalMsg); appendNewSlave := nullptr; RETURN; END_IF __QUERYINTERFACE(iElem, iVal); {warning disable C0033} pI := TO___UXINT(iVal.UlintValue); {warning restore C0033} appendNewSlave := pI; END_IF Without the dispose call, every second cold reset crashes immediately when I try to access iVal, even if eError doesnāt report any error. With the dispose call, the cold reset issue disappears, but I get other problems: a) If I start the runtime using systemctl start codesyscontrol, it crashes at IF hash.CountKeys() = 0 THEN b) If I delete the files in PlcLogic and download again, it works and survives multiple cold resets. But as soon as I run systemctl restart codesyscontrol, everything gets corrupted again and it starts crashing at that point. FUNCTION_BLOCK SlaveMapCounter VAR hash : COL.IMap2; eError : COL.COLLECTION_ERROR; END_VAR In its FB_Init I create it: METHOD FB_Init: BOOL VAR_INPUT bInitRetains: BOOL; // TRUE: retain variables are initialized (reset warm / reset cold) bInCopyCode: BOOL; // TRUE: the instance will be copied to the copy code afterward (online change) END_VAR VAR hF : COL.HashTableFactory; END_VAR hash := hF.Create(256); In another FB I instantiate it statically: FUNCTION_BLOCK ABSTRACT AbstractServoEthercatController EXTENDS AbstractServoController VAR_STAT hashSlaves : SlaveMapCounter; END_VAR VAR field : REFERENCE TO ADVAbstractFieldUnitEthercatCia402; initCnt : REFERENCE TO UINT; END_VAR The append method is the one shown above, and I call it after the runtime has started. The accesses are performed by a single task, and in any case Iām working on an isolated single core. Iāve tried everything, moving the create, the instances, and all the rest several times, but nothing seems to work. Iād like to point out that these FBs are part of our own library, which is used in many applications.
Last updated: 2025-09-11
Post by manuknecht on Opening a Dialog on a specific Client from ST
CODESYS Forge
talk
(Post)
I managed to find a solution that seems to work reliably. As the VU.Globals.CurrentClient-filter accesses the CURRENTCLIENTID or at least a similar, internal variable it can only be used if called from a certain client (e.g. from a button in a visualization). My solution works by implementing a new client filter that compares the client ID of all clients to the ID of the last client that was used. The variable containing the data of the last client is defined as: G_LastClient : VU.IVisualizationClient; // Copy of last client that detected click This last client is then updated every time a button is pressed using the Execute ST-Code input configuration of the button: G_LastClient := VU.PublicVariables.Clients.Current; Next, I created a function block that implements the client filter interface as so: FUNCTION_BLOCK FB_LastClientFilter IMPLEMENTS VU.IVisualizationClientFilter VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR END_VAR Then i added a method to the FB called IsAccepted which is used to filter out the client. When creating the method, it should automatically be filled with the according variable declaration, as it is defined in the interface: (* For every client can be desided, if it is accepted. ``TRUE``: Client is accepted*) METHOD IsAccepted : BOOL VAR_INPUT (* The client, to check*) itfClient : VU.IVisualizationClient; END_VAR Now the client can be compared to the last used client as such: // check if clientID corresponds to clientID of last recorderd client IF itfCLient.ClientId = G_LastClient.ClientId THEN IsAccepted := TRUE; ELSE IsAccepted := FALSE; END_IF To make use of this custom client filter, initialize a variable with the client filter: LastClient : FB_LastClientFilter; // Client filter to find last used client Then use this client filter when opening or closing a dialog from ST: fbOpenMyDialog(itfClientFilter:=LastClient,xExecute:=TRUE,sDialogName:='VIS_MyDialog_DLG');
Last updated: 2023-09-27
Post by thommy54 on CODESYSControl_User cfg richtig konfigurieren
CODESYS Forge
talk
(Post)
Hallo, nach Erwerb eines neueren Raspberry pi 4 (V1.5) musste ich zwangsläufig von Codesys 3.5.16 hochwechseln - ich habe auf 3.5.20.1 geupdated. Da schlugen mir plötzlich ne Menge Einschränkungen entgegen, deren Behebung einige Zeit dauerte. Eine davon ist, das ein SysFile.SysFileOpen nicht mehr funktioniert. Ich habe das Problem mit Einträgen in der /etc/CODESYSControl.cfg behoben: [SysFile] FilePath.1=/etc/, 3S.dat IecFilePath.1=/proc/, cpuinfo IecFilePath.2=/proc/, iomem PlaceholderFilePath.1=/sys/devices/w1_bus_master1, $OneWire$ PlcLogicPrefix=1 ; ; ---------------------- ; selbst eingefügt PlaceholderFilePath.2=/home/root, $my_home_root$ PlaceholderFilePath.3=/etc/init.d, $my_conf$ PlaceholderFilePath.4=/var/lib/mpd, $my_music$ PlaceholderFilePath.5=/root/Rasp_SPS_Filesystem, $my_Rasp$ Ob die Einträge sich etwas überlappen, kann mir gern jemand sagen, das ist aber nicht das Problem. Ich habe bei den vielen Versuchen, das Teil zum Laufen zu bringen, bemerkt, daà die Einträge auch ganz schnell mal verschwinden. Das ist ja auch so beschrieben, wenn die nächste Version kommt, sind meine Einträge weg. Da ich ähnliche Probleme mit dem Funktionieren von "SysProcessExecuteCommand2()" hatte, die ich ebenfalls mit Einträgen in die /etc/CODESYSControl.cfg hätte beheben können, habe ich gelesen, das man "private" Einträge lieber in die Datei /etc/CODESYSControl_User.cfg machen soll. Gesagt getan und "SysProcessExecuteCommand2()" lief: [SysProcess] Command=AllowAll Command.0=shutdown Aber auch irgendwo stand, das so ein Beteichner wie [SysFile] oder [SysProcess] nur einmal in den beiden Files /etc/CODESYSControl.cfg oder(!) /etc/CODESYSControl_User.cfg vorkommen darf. Das ist nun die eigentliche Frage! Ist das so ? Bei [SysProcess] ist das kein Problem, das gibt es in /etc/CODESYSControl.cfg nicht. Aber bei [SysFile] sieht das anders aus. Da sind 5 Zeilen schon in /etc/CODESYSControl.cfg drin. Würde ich diese in die User-Datei rüberschieben, könnte beim nächsten Update was fehlen oder, oder... Lasse ich es so wie es ist, sind meine Einträge beim Update weg - das sollte ja verhindert werden. Kann da jemand genaue Auskunft geben ?? Vielen Dank Thomas
Last updated: 2024-06-28
Post by thommy54 on Raspi-Cam: CameraStream.project nicht zum Laufen zu bringen
CODESYS Forge
talk
(Post)
Hallo, Ich bringe das CameraStream.project nicht zum Laufen. Ich sehe die Ursache darin, das das Beispielprogramm sehr sparsam mit Programm-Kommentaren umgeht (von der Hilfe gar nicht zu reden). Ich habe beide Varianten bei der zu Ƥndernden Zielvariable getestet: //copy video.htm to the webserver; //the location of the webserver depends on the used Apache version as mentioned in online help hDirHtmlTest:=SysDirOpen( szDir:='/var/www', pDirInfo:= ADR(dirInfo), diMaxDirEntry:=iMaxDirEntry, szDirEntry:=szDirEntry, pResult:=ADR(iDirHtmlError)); IF (iDirHtmlError = 0) THEN SysDirClose(hDir:=hDirHtmlTest); SysFileCopy('/var/www/video.htm', '$$PlcLogic$$/Application/video.htm', ADR(dwCopySize)); ELSE .... als auch hDirHtmlTest:=SysDirOpen( szDir:='/var/www/html', pDirInfo:= ADR(dirInfo), diMaxDirEntry:=iMaxDirEntry, szDirEntry:=szDirEntry, pResult:=ADR(iDirHtmlError)); IF (iDirHtmlError = 0) THEN SysDirClose(hDir:=hDirHtmlTest); SysFileCopy('/var/www/html/video.htm', '$$PlcLogic$$/Application/video.htm', ADR(dwCopySize)); ELSE .... Die Url-Streams habe ich gelassen wie sie vorgegeben waren: urlStream := CONCAT('http://', CONCAT(sIPAddress, '/video.htm')); urlPicture := CONCAT('http://', CONCAT(sIPAddress, '/cam_pic.php')); In der Webvisu im Browser komme ich maximal dahin wie im Screeshot Video_Visu_1 zu sehen. Also scheint der Link zu video.htm zu klappen. Das der zu cam_pic.php nicht klappt, wundert mich nicht, denn es existiert nicht und wird auch nicht evtl. am rechten Ort angelegt. Ich bin mir vollkommen im Unklaren: muss da was auf dem Raspberry Pi im Hintergrund laufen , z.B. raspivid . Welcher Programmteil bedient die Cam ? Ich erkenne auch nicht, wo ein einzelnes picture entstehen soll. WƤre dankbar, wenn ich hier etwas Hilfe bekommen kƶnnte. Evtl. gibt es Probleme mit der von mir verwendeten Codesys-Version 3.5.20.1 ? Ich benutze einen Raspberry 4 Rev.1.2. GrüĆe Thomas
Last updated: 2024-07-04
Post by youness on No source code available (cip object)
CODESYS Forge
talk
(Post)
Hi yotaro, hope your problem was resolved. I had the same, but with an other library title. This exception is not detected during compilation, but rather at a given position in the program (when switching to a given visualization). Although the exception is generated at this point, it does not involve the visualization in question. This error is due to one of 3 reasons: 1) A division by zero somewhere: The program is able to detect divisions by zero at compile time. But in the case of a variable, which takes a valid value at init and changes to 0 at a later stage. 2) An invalid pointer: (either because it has a value of 0, or because it points outside the memory reserved for the program) is being dereferenced. Locate any pointers or interfaces you have in the code and check them - you should also be wary of mixing inline modifications and pointers. 3) Array overflow: Generally when a processing operation is executed outside the array's definition range. Example: a write loop with n iterations is executed on an array of dimmension n-1. On the other hand, the error message may not appear. In the latter case, the error may have fatal consequences, as the overflow has induced writing to potentially forbidden memory areas. This problem can be explained by the fact that it's not always the adjacent memory areas of PLC_PRG that are overwritten, but the memory areas that are randomly allocated to the array during compilation. In this case, however, there is no entry in the log, so you need to integrate the "Implicit Check function", which checks the line of code generating the error. To integrate this functions, click on Application --> POU for implicit controls Regards,
Last updated: 2024-07-16
Post by jeffg on ERROR: GetNetLinkSockAndInfoByMac(): could not open netlink socket: Too many open files
CODESYS Forge
talk
(Post)
I just installed codesys runtime on a raspberry pi Cortex-A72 (ARM v8) 64-bit SoC @ 1.5GHz (Compute Module 4) I am running on Codesys control for raspberry pi 64 SL ver 4.13.0 and I keep getting a crash after about five to ten minutes. This program was running fine on a 32bit system with runtime 4.8 previously but they upgraded the panel PC cause it got smashed. Looking at the logs I see this error "ERROR: GetNetLinkSockAndInfoByMac(): could not open netlink socket: Too many open files" at the time of crash. I do have a UDP socket open for a serial to ethernet adapter and im wondering if maybe its opening a bunch of sockets and while receiving messages, Im not sending anything to the device only receiving. Below is the code used for the UDP VAR // Scale Comm fbPeerServer : NBS.UDP_Peer; ipAddress : NBS.IPv4Address; fbReceive : NBS.UDP_Receive; xPeerActiv : BOOL := TRUE; abyReceive : ARRAY [0..255] OF BYTE; sLastValidReceive : STRING(255); udiIndex : UDINT; END_VAR IF xPeerActiv AND NOT fbPeerServer.xBusy THEN ipAddress.SetInitialValue(ipAddress := gvlSettings.sIPAddres); fbPeerServer(xEnable := TRUE, itfIPAddress := ipAddress, uiPort := gvlSettings.uiPort); END_IF fbPeerServer(); fbReceive(xEnable := fbPeerServer.xBusy, itfPeer := fbPeerServer, pData := ADR(abyReceive), udiSize := SIZEOF(abyReceive)); IF fbReceive.udiCount > 0 THEN IF fbReceive.udiCount < SIZEOF(sLastValidReceive) THEN SysMem.SysMemCpy(pDest := ADR(sLastValidReceive), pSrc := ADR(abyReceive), udiCount := fbReceive.udiCount); // Set End of String sLastValidReceive[fbReceive.udiCount] := 0; END_IF END_IF If anyone as seen this I could really use some help figuring it out. I included the Log report
Last updated: 2024-09-19
Post by yannickasselin on MQTT QoS 1 & 2
CODESYS Forge
talk
(Post)
Hello, I am using Codesys sp20p3 and IIoT library 1.11. I am trying to test QoS 1 & 2 and I have some issues. I am using mosquitto as the broker. I am also using some other MQTT clients like Node-Red and TwinCAT. They all work as expected for every QoS levels. I only have issues with Codesys MQTT client. In the Codesys client, if I subscribe to a topic as QoS 1 or 2, and a client publishes to this topic, I receive the message. But if I disconnect the Codesys client from the network and a client publishes to the subscribed topic, when I reconnect Codesys client to the network, I don't receive the messages as expected. Also there does not seem to be an auto-reconnect feature. So I have to manually set the mqttClient.xEnable bit to FALSE then back to TRUE in order to reconnect to the broker, then I also have to set the subscribe.xEnable to FALSE and back to TRUE in order to re-subscribe to the topic, but even then, I don't receive the messages that were published while I was disconnected. What am I doing wrong? I set the cleanSession bit to FALSE and I give my client a clientID. With the TwinCAT MQTT Client, I do the same thing and everything works as expected. It even auto-reconnects to the broker. I would expect Codesys MQTT Client to be as reliable as TwinCAT. Maybe I am doing something wrong? I also noticed that when trying to publish a QoS 1 or 2 message while disconnected from the broker, it does not work. In TwinCAT, I am still able to publish. The messages are stored in the client and published once reconnected to the broker. I would expect to be able to do the same thing in Codesys. Is this all possible? Am I doing something wrong? Thank you
Last updated: 2024-10-26
Post by kevintumibay on Struggling to connect to EK1100 to Raspberry Pi
CODESYS Forge
talk
(Post)
SUMMARIZED VERSION OF QUESTION: I'm trying to connect a Raspberry Pi running "Codesys Control for Raspberry Pi" to a Beckhoff EK1100, unfortunately, when I try to connect I get the following messages SEE FIRST PICTURE DETAILED VERSION OF QUESTION: Hi everyone, I'm a college student that is super interested in learning about PLCs. I wanted to dive into the subject and decided to follow this great Instructables article: https://www.instructables.com/Programming-Raspberry-Pi-With-CODESYS/ Thank you in advance for your help! My current setup is as follows: 1. I have Codesys Control for Raspberry Pi, version 4.14.0.0, (https://store.codesys.com/en/codesys-control-for-raspberry-pi-sl.html) installed on a Raspberry Pi 3B. 2. I am using my smartphone hotspot to create a network. 3. I have CODESYS 3.5 SP21 (64 bit) installed on my Windows 11 laptop. 4. Both the Raspberry Pi and my laptop are connected to the smartphone hotspot network (I am wirelessly connecting to the Raspberry Pi). Connecting to the Raspberry Pi from CODESYS on my laptop: 1. I launch Codesys Installer -> I install Codesys Control for Raspberry Pi (link to the software). 2. I launch Codesys 3.5 SP21 (64 bit) on my laptop. 3. I go to file --> new project --> standard project --> in the pop-up I select "Codesys Control for Raspberry Pi" and "Structured Text" 4. I click on tools -> Deploy Control SL (on older versions of Codesys you would click on "update Raspberry Pi", I got that information from this video: link) 5. Inside Deploy Control SL --> I go to the "communication" menu and I input the IP address of my Pi, the password, and click on connect. 6. Inside Deploy Control SL --> I go to the "deployment" menu and I install Codesys Control for Raspberry Pi SL and Codesys Edge Gateway for Linux 7. Now I double click on "device" in the left hand tree and put in the IP address of my Raspberry Pi and click on connect --> success! I am able to connect! SEE SECOND PICTURE Powering the EK1100 and connecting it to the Raspberry Pi: 1. I am supplying the EK1100 with 24 V across the + and - pins. 2. I have jumper wires going from the + pin to the 24V pin and from the - pin to the 0V pin. SEE THIRD PICTURE 4. I am pretty confident that the EK1100 is receiving power because the "LED Us 24 V" and "LED Up 24 V" are lighting up. 5. I then run an ethernet cable from the EK1100 to the Raspberry Pi port (the Raspberry Pi is connected to my laptop wirelessly over WiFi). I think this connection should also be good since the LINK/ACT LED lights up. Trying to connect to the EK1100: 1. Back in Codesys I right-click on "Device" in the left tree and then in the pop up I click on "add device". 2. I then click on EtherCAT Master. 3. Next in a terminal window I SSH into the raspberry Pi and run the "ifconfig" command. 4. From there I get the MAC address for eth0 --> in my case: b8:27:eb:29:a9:25 5. Then, back in Codesys I double click on "EtherCAT Master" in the left hand tree. I then paste the MAC address into the "Source Address (MAC)" field. 6. I go to the Beckhoff official website and download the XML files for EtherCAT: https://www.beckhoff.com/en-en/products/i-o/ethercat-terminals/ek1xxx-bk1xx0-ethercat-coupler/ek1100.html? 7. I unzip those files in my computer into some folder that I can remember. 8. Back in Codesys I click on "Tools" --> "Device Repository" --> "Install" --> and then on the "Beckhoff EK11xx.XML" file. 9. In theory the necessary XML file is now installed. 10. THIS IS WHERE I RUN INTO THE PROBLEM: I then click on login --> I right click on EtherCAT_Master and then scan for devices --> and nothing. 11. It just doesn't detect it. On top of this whenever I login I get those orange triangles on the left on my tree. When I check the Log I get the messages at the very first screenshot of this post. SEE FOURTH PICTURE Solutions that I have tried to resolve this problem: 1. I thought it was maybe the .XML file so I installed all the .XML files from the EtherCAT folder that I downloaded. That didn't fix it. 2. I went on the Wayback Machine and got the .XML files from 2018 as I thought maybe an older version would work. This file of EtherCAT folders had a .XML file named "Beckhoff EKxxxx.XML" I thought this would work because that's the name of the file the guy in the Instructables used (https://www.instructables.com/Programming-Raspberry-Pi-With-CODESYS/). That didn't do anything. 3. I ran the PLC on my computer instead of the Raspberry Pi and tried to connect to the EK1100, in case the issue was with the Raspberry Pi, but I still ran into the same error from the picture above: "Attention! The device was not found in the repository. Vendorcode: 0x0. Productcode: 0x0. Revision: 0x0". SEE FIFTH PICTURE 4. I reinstalled Codesys, I was originally on version 3.5 SP20 when I did this, I upgraded to 3.5 SP21 with no success. 5. I then thought the solution might be to first add the EK1100 hardware before connecting so I did the following: 6. Right click on "EtherCAT Master" on the left hand tree --> then click on "add device" --> then I added the "EK1100 EtherCAT Coupler (2A E-Bus)" MY THEORY OF WHAT IS CAUSING THE PROBLEM: I asked ChatGPT for help and it said that it might have something to do with the revision number. On the physical EK1100 it says "Rev. Nr.: 0018". I believe that this means that I need to a revision 0018 XML file but if you look in Codesys it says the version is 16 (picture above). This is confusing because I got my .XML file from the official Codesys website so it should be the most up to date version possible. I searched and I searched and I couldn't find a version 18 .XML file, I don't even now if this exists. Any help you can provide is greatly appreciated, I don't know what to do anymore and I really really want to get this working. Thank you!
Last updated: 2025-03-30
Post by edson-bueno on SysProcess Execute Command unable to run commands with special characters
CODESYS Forge
talk
(Post)
Hi, I found the same issue, and I fixed with this steps: 1st go to codesys .cfg file. sudo nano CODESYSControl.cfg Then insert this: [SysProcess] BasePriority=Realtime Command=AllowAll Now we need to grant codesys root rights on Linux. Step 1: Create or edit the systemd override configuration: sudo systemctl edit codesyscontrol In the editor that opens, insert: [Service] User=root Save and exit: Press Ctrl+O to save Press Ctrl+X to exit Step 2: Reload systemd and reboot To apply the override: sudo systemctl daemon-reexec sudo systemctl daemon-reload sudo reboot Step 3: Confirm CODESYS is running as root After reboot, open the terminal and run: ps aux | grep codesyscontrol You should see something like: root 1234 ... /opt/codesys/bin/codesyscontrol.bin ... If instead it shows admin or another user, the override was not applied correctly. Step 4: (Optional) Confirm from within CODESYS In your CODESYS project, insert this test code to run the Linux command whoami: Make sure the lib SysProcessImplementation, SysTypes, and CmpErrors is on the project. VAR sCommand : STRING := '/usr/bin/whoami'; sOutput : STRING(255); refCommand : REFERENCE TO STRING; refOutput : REFERENCE TO STRING; resultCmd : UDINT; END_VAR refCommand REF= sCommand; refOutput REF= sOutput; SysProcessExecuteCommand2( pszCommand := refCommand, pszStdOut := refOutput, udiStdOutLen := SIZEOF(sOutput), pResult := ADR(resultCmd) ); Notes & Warnings This method gives full system access to the CODESYS runtime ā do not expose this system to the public network without protection. Do not use sudo in commands inside CODESYS when the runtime is already running as root. @tomas111, in case you want to read the temperatur, use this command: sCommand:STRING:='/usr/bin/vcgencmd measure_temp';
Last updated: 2025-05-20
Post by jeindhoven on Deploying to raspberry pi 5 hangs
CODESYS Forge
talk
(Post)
Hi CoDeSys support forum, hope that this is the correct place to ask this. Might be double as i am new to Codesys and dont know all terminology. I am trying to test Codesys with a virtual plc on a raspberry pi 5. Already figured that i need Tools -> Deploy Control SL, enter Communication parameters. Codesys says "Connected". Then tab "Deployment", there i select "CODESYS Control for Raspberri Pi SL" and "4.16.0.0 (all)". Click "Install" and the gui turns grey and unresponsive. The titlebar says "Untitled1.project - CODESYS (Not Responding)" as well. Restarting Codesys and checking shows no package was installed. How to deploy the runtime? Thank you in advance for your time. Edit: After some patience, an error showed up: "Error when sending ssh heartbeat: Session operation has timed out" "Error installing codesyscontrol" Any pointers to what remote command might have failed, or log of some sort, would be welcome. Software versions: Codesys version 3.5.21.10 Raspberry pi 5 (deployment machine): $ uname -a Linux raspberrypi 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 11 (bullseye) Release: 11 Codename: bullseye $ apt list --installed | grep openssh-server openssh-server/oldstable,now 1:8.4p1-5+deb11u3 arm64 Development machine: $ uname -a Linux 2B 6.1.0-35-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.137-1 (2025-05-07) x86_64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 12 (bookworm) Release: 12 Codename: bookworm VirtualBox Version 7.0.26 r168464 (Qt5.15.8) Virtual OS: Windows 10 Pro 64-bit (10.0, Build 19045) .NET version 4.0.30319.42000
Last updated: 2025-06-22
Post by jeindhoven on Deploying to raspberry pi 5 hangs
CODESYS Forge
talk
(Post)
Yep sure, though now that i think of it, its a pi 4. My bad. The whole ordeal was necessary to use the VGA666 adapter. That needs the old graphical system and GPIO directly on the CPU. Edit: Putty on the virtual development machine connects fine. But i did change the login/pw. The account is still a sudo'er so that should be all right. Edit2: Sorry i get a "Comment rate limit exceeded" from the forum. Then i'll add it as edit here. So i have tried the stock raspberry pi image on a different pi5 (truly 5 this time). Packages updated. Standard password. Same symptoms, no runtime deployed and long hang time. Versions of this pi: pi@raspberrypi:~ $ uname -a Linux raspberrypi 6.12.25+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.12.25-1+rpt1 (2025-04-30) aarch64 GNU/Linux pi@raspberrypi:~ $ lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 12 (bookworm) Release: 12 Codename: bookworm pi@raspberrypi:~ $ apt list --installed | grep openssh-server openssh-server/stable,now 1:9.2p1-2+deb12u6 arm64 [installed,automatic] Attached is the Device information and error text that Codesys comes up with. Edit 3 (Comment rate limit, otherwise it would be a new post) Now i have tried booting an older native Windows 10 machine (no virtualization), and it just works as expected. I have now a raspberry pi 4 and raspberry pi 5 with version 4.16.0.0 of the control application. Windows 10 native: build 19045 (same as virtualised Win 10), same .NET version, same CODESYS version. It seems that running CODESYS virtualized somehow messes with the deployment?
Last updated: 2025-06-23
Post by westcountryewe on ac_persistence not working when creating a Boot Application but works with a Direct Download to the PLC
CODESYS Forge
talk
(Post)
I am using V3.5 SP18 Patch 5. I have noticed that when I Create a Boot Application from CODESYS, and upload this to my PLC via a USB stick the AC_Persistence does not work and none of my values that are in my PersistenceChannel are retained. However, if I connect direct to my PLC and I perform a direct download of my CODESYS program, my values that are in my PersistenceChannel are retained and work as they should. This makes me wonder if there are files that are missing when a Boot Application is created. I have tried taking a backup of my configuration files after performing a direct download, which gives me the plclog.zip folder, and appears to have the ac_persistence folder present within the file structure, however when I replace the plclogic.zip with the same folder that was created when I created a Boot Application, it still does not work but I wonder whether this is because the ac_persistence folder isn't stored in the correct location for reading. The .app and .crc files are embedded within the plclogic.zip folder, which obviously when uploading need to be standalone files in the root directory of the USB, so the intention there is clearly to extract the .app and .crc files and put them into the correct location within the USB. I wonder if it could be the same for the ac_persistence folder? I have tried moving it to different locations but none have worked. Has anybody else discovered a fix for this? I know the short-term solution is to do a direct download to the PLC but there are some logistical reasons why this isn't neccesarily the best solution for us.
Last updated: 2024-02-27
Post by testlogic on Sending Sequential Modbus TCP Packets
CODESYS Forge
talk
(Post)
I have a Modbus TCP slave device where I need to do sequential writes to the same register. The register I'm writing to is kind of like a command line, each packet is a command word encoded in Hexadecimal. I am having difficulty implementing this system in CoDeSys 3.5 SP19. I feel like the structure of the program should be something along the lines of (Pseudocode): ModbusTCPSend(Command Register, Command1) ModbusTCPSend(Command Register, Command2) ModbusTCPSend(Command Register, Command3) I have tried to implement this with a rising edge trigger wMot1OPCode := 16#E1; //Stop Motor & Kill Program xMot1SendOP := TRUE; //Send OP on rising edge xMot1SendOP := FALSE; //Reset wMot1OPCode := 16#9E; //Disable Motor xMot1SendOP :=TRUE; //Send OP on rising edge xMot1SendOP := FALSE; //Reset Where "wMot1OPCode" is the IO map for writing to the command register, and "xMot1SendOP" is the rising edge trigger for that modbus channel. However, this doesn't work. The device never responds to the modbus commands. It seems like the trigger variable is switched too quickly for modbus to send the packet. I know the modbus register is working, because I can set the channel to cyclic and the device will respond. However, I can't use this reliably because I need each command to be sent once, in order. Cyclic keeps re-sending the commands and seems like it could miss a command as well if one was sent in-between cycle time. I have also trying using the Application trigger as described by https://faq.codesys.com/pages/viewpage.action?pageId=24510480, but this is also not working for me. See attached picture for my FBD code. This seems like a simple function, I can't tell what I'm doing wrong here. Thanks for the help.
Last updated: 2024-03-06
Post by thysonfury on OPTO22 Groov Epic PR2 Modbus Comms Dropping out every 2 hours and 4 Mins
CODESYS Forge
talk
(Post)
Hi after some assistance with an error on a Groov PR2 PLC. We have a few different communications set up as shown below: One Modbus TCP Slave Connection - ( Sending / Receiving Data from a PC ) Two Modbus TCP Master Connection - ( Reading Data from a UPS Panel and Reading Data Gas Chromatograph) One Modbus RTU Slave Connection 485 - (Reading Data from a fire and gas panel) One Modbus RTU Master Connection 485 - (Sending Data to a Telemetry Unit) All Licenses have been installed as per OPTO22 suggestions of the order below: Modbus TCP Master Modbus TCP Slave Modbus RTU Master Modbus RTU Slave When I check on License manager the RTU Master license seems to disappear on installing the RTU. (What ever reason Iāve been told this is ānormalā). If I use Device License Read It will successfully read all the licenses correctly. Now the issue is every 2 hours and between 4. For what ever reason the communications seems to end and lock up for about 20 seconds. During this time even if I was logged into the PLC it would kick me off and Iād have to re type the password to enter. Most of the devices can handle this however the RTU flags up a communications failure at the SCADA and is raising alarms every 2 hours and 4 mins. Weāve had multiple people go through the code to check for anything obvious. Does anyone have any ideas?
Last updated: 2024-04-15
Post by thysonfury on OPTO22 Groov Epic PR2 Modbus Comms Dropping out every 2 hours and 4 Mins
CODESYS Forge
talk
(Post)
Hi after some assistance with an error on a Groov PR2 PLC. We have a few different communications set up as shown below: One Modbus TCP Slave Connection - ( Sending / Receiving Data from a PC ) Two Modbus TCP Master Connection - ( Reading Data from a UPS Panel and Reading Data Gas Chromatograph) One Modbus RTU Slave Connection 485 - (Reading Data from a fire and gas panel) One Modbus RTU Master Connection 485 - (Sending Data to a Telemetry Unit) All Licenses have been installed as per OPTO22 suggestions of the order below: Modbus TCP Master Modbus TCP Slave Modbus RTU Master Modbus RTU Slave When I check on License manager the RTU Master license seems to disappear on installing the RTU. (What ever reason Iāve been told this is ānormalā). If I use Device License Read It will successfully read all the licenses correctly. Now the issue is every 2 hours and between 4. For what ever reason the communications seems to end and lock up for about 20 seconds. During this time even if I was logged into the PLC it would kick me off and Iād have to re type the password to enter. Most of the devices can handle this however the RTU flags up a communications failure at the SCADA and is raising alarms every 2 hours and 4 mins. Weāve had multiple people go through the code to check for anything obvious. Does anyone have any ideas?
Last updated: 2024-04-15
Post by thysonfury on OPTO22 Groov Epic PR2 Modbus Comms Dropping out every 2 hours and 4 Mins
CODESYS Forge
talk
(Post)
Hi after some assistance with an error on a Groov PR2 PLC. We have a few different communications set up as shown below: One Modbus TCP Slave Connection - ( Sending / Receiving Data from a PC ) Two Modbus TCP Master Connection - ( Reading Data from a UPS Panel and Reading Data Gas Chromatograph) One Modbus RTU Slave Connection 485 - (Reading Data from a fire and gas panel) One Modbus RTU Master Connection 485 - (Sending Data to a Telemetry Unit) All Licenses have been installed as per OPTO22 suggestions of the order below: Modbus TCP Master Modbus TCP Slave Modbus RTU Master Modbus RTU Slave When I check on License manager the RTU Master license seems to disappear on installing the RTU. (What ever reason Iāve been told this is ānormalā). If I use Device License Read It will successfully read all the licenses correctly. Now the issue is every 2 hours and between 4. For what ever reason the communications seems to end and lock up for about 20 seconds. During this time even if I was logged into the PLC it would kick me off and Iād have to re type the password to enter. Most of the devices can handle this however the RTU flags up a communications failure at the SCADA and is raising alarms every 2 hours and 4 mins. Weāve had multiple people go through the code to check for anything obvious. Does anyone have any ideas?
Last updated: 2024-04-15
Post by manuknecht on Maximum dynamic limits of MC_MoveLinearAbsolute and MC_MoveLinearRelative
CODESYS Forge
talk
(Post)
Hello all I use an axis group with two linear axes in a kinematic system. Using MC_MoveLinearAbsolute and MC_MoveLinearRelative, I am trying to realise dynamic movements (set velocity: 1 m/s, set acceleration: 30 m/s^2) with the highest possible jerk, as I want to compare this with a movement with a trapezoidal velocity profile. However, my measurements show that the axes accelerate with a maximum jerk of approx. 800 m/s^3, even if the value in the function block was set to 10,000 m/s^3. I have already increased the dynamic limits of the two axes accordingly (Velocity: 5000 u/s, Acc-/Deceleration: 250'000 u/s^2, Jerk: 100'000'000 u/s^3, where 1 u = 1 mm), but this had no effect. I have checked the input parameters of the function blocks and the VelFactor, AccFactor and JerkFactor factors are all set to the maximum (value 1). Reducing the cycle time has resulted in a higher jerk, but as we are already working with a cycle time of 1 ms, there is nothing more that can be done here. The axes themselves are still a long way from drawing the maximum current, which is why I assume that this should not be a problem either. Are there other factors or parameters that influence the dynamic limits and therefore allow faster movements? The PLC I am using is a Raspberry Pi 4 and Codesys V3.5 SP20 with all libraries up to date. Thanks in advance Manuel
Last updated: 2024-05-08
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 paulg on RasPi CAA Serial example - unexpected behavior during debug
CODESYS Forge
talk
(Post)
I've trimmed down the CAA Serial Codesys example to only listen on one port but, when stepping through the Case structure in debug mode, it jumps out of the structure during a specific point in every scan (I'll point it out below after describing the setup and listing the code). I'm using a Pi 4 Model B, and I have an Arduino Nano Every plugged in via USB which is streaming the following serial message at 1 Hz: Time since opening connection: 1 s Time since opening connection: 2 s ...and so on. The Pi shows the Nano at /dev/ttyACM0 so I edited CODESYSControl_User.cfg to read: Linux.Devicefile=/dev/ttyACM The code in my PLC_PRG is (ignore some of the comments, I hadn't deleted them out from the original example): PROGRAM PLC_PRG VAR xStartTest : BOOL:= TRUE; iState : INT; xTestDone : BOOL;(* True, when the test was done succesfully *) (* Settings to communicate with the COM Port *) aCom1Params : ARRAY [1..7] OF COM.PARAMETER; como1 : COM.Open; comc1 : COM.Close; comw1 : COM.Write; comr1 : COM.Read; //sWrite : STRING := 'Test String!'; sRead : STRING(25); szRead : CAA.SIZE; xCom1OpenError : BOOL; xCom1CloseError : BOOL; xCom1WriteError : BOOL; xCom1ReadError : BOOL; END_VAR //This example shows the communication of two COM Ports with each other. //The first one writes a string of characters, which is read by the second one. //After successful execution, the two COM Ports are closed and the test is done. IF xStartTest THEN CASE iState OF 0: //The parameters are set for the COM Port aCom1Params[1].udiParameterId := COM.CAA_Parameter_Constants.udiPort; aCom1Params[1].udiValue := 1; // the correct Port should be adapted aCom1Params[2].udiParameterId := COM.CAA_Parameter_Constants.udiBaudrate; aCom1Params[2].udiValue := 115200; aCom1Params[3].udiParameterId := COM.CAA_Parameter_Constants.udiParity; aCom1Params[3].udiValue := INT_TO_UDINT(COM.PARITY.NONE); aCom1Params[4].udiParameterId := COM.CAA_Parameter_Constants.udiStopBits; aCom1Params[4].udiValue := INT_TO_UDINT(COM.STOPBIT.ONESTOPBIT); aCom1Params[5].udiParameterId := COM.CAA_Parameter_Constants.udiTimeout; aCom1Params[5].udiValue := 0; aCom1Params[6].udiParameterId := COM.CAA_Parameter_Constants.udiByteSize; aCom1Params[6].udiValue := 8; aCom1Params[7].udiParameterId := COM.CAA_Parameter_Constants.udiBinary; aCom1Params[7].udiValue := 0; //The first Port is opened with the given parameters como1(xExecute := TRUE, usiListLength:=SIZEOF(aCom1Params)/SIZEOF(COM.PARAMETER),pParameterList:= ADR(aCom1Params)); IF como1.xError THEN xCom1OpenError := TRUE; iState := 1000; END_IF //After a successful opening, the next state is reached IF como1.xDone THEN iState := 15; END_IF 15: // the reading process is started comr1(xExecute := TRUE,hCom:= como1.hCom, pBuffer:= ADR(sRead), szBuffer:= SIZEOF(sRead)); IF comr1.xError THEN xCom1ReadError := TRUE; END_IF //After completion the size of the written bytes are saved IF comr1.xDone OR comr1.xError THEN szRead := comr1.szSize; iState := 20; END_IF 20: // If everything was successful the ports are closed and the handles are released comc1(xExecute := TRUE,hCom:= como1.hCom); IF comc1.xError THEN xCom1CloseError := TRUE; END_IF IF comc1.xDone OR comc1.xError THEN iState := 25; END_IF 25: // The first port is closed and the used handle released xTestDone := TRUE; xStartTest := FALSE; iState := 0; como1(xExecute := FALSE); comw1(xExecute := FALSE); comc1(xExecute := FALSE); ELSE iState := 0; END_CASE END_IF I realize as I write this that the .udiPort should be 0 and not 1, but that shouldn't be causing the issue I'm seeing. I'm forcing xStartTest:=TRUE every scan so that I can step into each line and observe what's happening. What I see is that the port parameters are set and the port is opened with no errors, but the code jumps out of the case structure to the last line every time it reaches (and I step into) the iState:=15 line (at the end of the iState:=0 block). So every scan cycle it goes through the block for iState=0 and jumps out at the same spot. I'm a little new to PLC programming so I may be misunderstanding the flow, but shouldn't this case structure keep moving down in the same scan? If it only handles one case per scan, why doesn't the value of iState persist? Thanks! Update: I restarted the Codesys control today and I was then able to see an error for como1.eError of "WRONG_PARAMETER". I tried doing some digging and another post made me think I should add another line to CODESYSControl_User.cfg, so I now have: [SysCom] Linux.Devicefile=/dev/ttyACM portnum := COM.SysCom.SYS_COMPORT1 So now when I set .udiPort to 1, I get "NO_ERROR" but I also don't read anything from the port (i.e. szRead = 0 always). If I try setting the port to 0 (which I'm confused about, because I added a COMPORT1 line but the device shows on the Pi as ACM0), I get the "WRONG_PARAMETER" error again. Is there an easier way to troubleshoot the Pi and view what ports the Codesys runtime is actually able to see while the Pi is running?
Last updated: 2024-06-06
Post by dwpessoa on CNC Jumps G20 - SMC_NCInterpreter and long time to process
CODESYS Forge
talk
(Post)
I am studying and developing a Softmotion+CNC system for a machine that executes multiple pieces. The G code program is written by the machine operator and each cycle execute 1 piece. The programs are large, exceeding 1000 lines and using up to 8 axes (X, Y, Z, A, B, C, P and Q). The machine needs to run cyclically, executing N pieces (selected by the Operator)... so I tested it using Looping and counters (G36 G37 and G20) and it worked, but it takes a long time to process, and the more pieces I need, the longer the processing time and this is totally impracticable. I found this solution which was very good, and for a few cycles it works well, but for 99999 pieces of a program with 1000 lines, it doesn't work very well... Another solution I tested is to maintain the interpolator with an automatic restart, that is, I load the program without looping (without G20) and give it another start as soon as it finishes. This partially resolved it, but there is still a delay in processing SMC_NCInterpreter in each restart :(. Another solution I thought of is to manually create the SMC_GEOINFO structure and then reuse it, avoinding the Interpreter, but reading the documentation and checking the structure filled by standard blocks, I noticed that there doesn't seem to be a "JUMP" function in the structure! In other words, the SMC_NCInterpreter actually keeps copying and copying the program section for each jump (G20)... If I repeat a 10-line program 1000 times, I will have a structure with more than 10000 lines... possibly this is the cause of take so long to process. Has anyone ever had a problem like this? I believe the same thing happens with typical applications with manipulator robots using Codesys in continuous cycles, and I would like to know if there is any solution, or even if I am misinterpreting the G20 question in SMC_GEOINFO. Thanks!
Last updated: 2023-09-20
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.