Post by ahuckphin on Issues with Modbus Slave with Raspberry Pi
CODESYS Forge
talk
(Post)
I have a DFRobot RS485 temperature & humidity sensor (SEN0438) connected to my Raspberry Pi via a USB to RS485 adapter. I am able to connect and read the sensor data when running a python code locally. However in Codesys, I encounter this error "A bus error has occurred." and "There was no response in time". Could this be because of Modbus Server Channel and Modbus Server Init configuration on my part? Admittedly I am new to Codesys. To get to this stage, I: 1. added some lines to CODESYSControl_User.cfg 2. added "Modbus_COM" in Codesys and set "Serial Port Configuration" under "General" 3. added "Modbus_Master_COM_Port" in Codesys and checked transmission mode is set to "RTU" 4. added "Modbus_Slave_COM_Port" in Codesys and checked server address is set to 1 (also set 1 in my sensor) 5. added 1 channel and 1 init for "Modbus_Slave_COM_Port" under "Modbus Server Channel" and "Modbus Server Init"
Last updated: 2024-07-10
Post by andrax on Bosch BME 280 bzw 688 Sensor per I2C Bus steuern und Daten in Codesys verarbeiten
CODESYS Forge
talk
(Post)
Die GerƤte Bibliothek von Stefan Dreyer ist dafür gedacht, um Treiber für deine Sensoren zu erstellen, damit sie an einem MUX-Board betrieben werden kƶnnen. Auch ist ein Betrieb ohne MUX-Board mƶglich. Der Aufbau ist relativ einfach und besteht aus folgenden Komponenten: -Initialize (hier wird die .devdesc.xml eingelesen) -BeforeWriteOutputs (ruft initDevice auf und ist für ausgehende Signale gedacht) -initDevice (initialisiert den Sensor) -AfterReadInputs (SelbsterklƤrend, Werte einlesen und Signalkonversation) Bei meinen Sensoren habe ich es immer so gemacht. Zuerst habe ich mit die .devdesc.xml gebaut bzw. eine Vorlage umgeschrieben, wobei Parameter 1-10 für ein Mux-Board reserviert sind. In der .devdesc.xml definierst du alle wichtigen Parameter für den Sensor. Danach schreibst du die Initialize und liest die Werte ein. InitDevice ist FleiĆarbeit. Für die meisten Sensoren liegt immer ein Pythonscript oder was in C bei. Du gehst die Scripte durch und baust es in Codesys nach. Im letzten Schritt baust du die AfterReadInputs. Signale einlesen und Conversation. Du solltest dir auch ein I2C-Logic Analyzer zulegen. Da Teil ist sehr hilfreich um die I2C Kommunikation mitzulesen. Wenn es irgendwo klemmt, siehst du sofort an welcher Stelle du suchen musst. Ich hab hier den AZ-Delivery Logic Analyzer! GrüĆe Andre
Last updated: 2025-01-11
Post by ph0010421 on How to create a stopwatch?
CODESYS Forge
talk
(Post)
Do you need an 'hours-run' counter? And 1 second resolution is ok? I think you're over-thinking it. (The task time needs to be < 1second) Have a look at the LAD... Then, the time in seconds can be made into hh:mm:ss with this FUNction Declarations: FUNCTION funSecondsToStringTime: string VAR_INPUT InSeconds: UDINT; END_VAR VAR AsString: STRING; Minutes: UDINT; Hours: UDINT; Seconds: UDINT; MinutesAsString: STRING(2); HoursAsString: STRING(2); SecondsAsString: STRING(2); END_VAR and the code: Hours := InSeconds / 60 / 60; //Derive hours Minutes := (InSeconds - (Hours * 60 * 60)) / 60; //Derive minutes Seconds := InSeconds - ((Hours * 60 * 60) + (Minutes * 60));//Derive seconds HoursAsString := UDINT_TO_STRING(Hours); MinutesAsString := UDINT_TO_STRING(Minutes); SecondsAsString := UDINT_TO_STRING(Seconds); IF LEN(HoursAsString) = 1 THEN HoursAsString := CONCAT('0',HoursAsString); END_IF; IF LEN(MinutesAsString) = 1 THEN MinutesAsString := CONCAT('0',MinutesAsString); END_IF; IF LEN(SecondsAsString) = 1 THEN SecondsAsString := CONCAT('0',SecondsAsString); END_IF; AsString := CONCAT(HoursAsString, ':'); //assemble string AsString := CONCAT(AsString,MinutesAsString); AsString := CONCAT(AsString,':'); AsString := CONCAT(AsString, SecondsAsString); funSecondsToStringTime := AsString;
Last updated: 2023-12-08
Post by chalk on No source code available
CODESYS Forge
talk
(Post)
Hello, This is my first time using Codesys, I am trying to add EtherNetIP communication to a Raspberry PI. Iāve added the EtherNetIP Adapter configured the network setting and added some modules to the pi but when I download the project it generates the following error: āThere is no source code available for the object because it is in the compiled library ācip object, 4.5.1.0 (3s ā smart software solution gmbh)ā. Do you want to browse for the original library in order to display the source code? There are 2 errors in the log which are: SOURCEPOSITION App=[Application] area=3, offset=332760 EXCEPTION [Application] occurred: App=[Application], Task=[ENIPAdapterServiceTask] I canāt for the life of me work out how to get around this. I canāt find the source code anywhere or any information regarding this error. Iām using Codesys V3.5 SP19 Patch 3, the version of the Ethernet adapter is 4.5.1.0 and the version of the modules is 4.1.0.0. Any help on this will be greatly appreciated. Thanks
Last updated: 2024-02-02
Post by wbj0t on What the right way to update TCP/COM slave device holding registers
CODESYS Forge
talk
(Post)
Hi all :) I have an plc. This plc has option to be as slave device. There are TCP -> Serial Slave Device and COM -> Serial Slave Device. There are 4096 ModBus holding registers with mark "internal modify" for the both devices above. So, COM Slave has 4096 registers and TCP Slave has 4096 registers. And, finally, I have an ARRAY[0..4095] OF WORD. This array glued with COM Slave and TCP slave. Yes, I need plc's opportunity to be communication both TCP and COM ways for the same registers. For example, the next task structure: * TASK_0: 1. pou_READ_Registers 2. pou_0 3. pou_1 4. ... 5. pou_N 6. pou_WRITE_Registers At the first pou I read registers for the other pous, after job we have sort of state of the plc. At the last pou (6) we write modified registers. It is a good scenario: some one wrote registers for the job, after job we save these (modified) registers. But, what if registers wrote between 1 and 6 pou by operator, for example, at the 3 pou -> the last pou 'pou_WRITE' will rewrite this request from operator. What the right way to work with this logic? Thanks you.
Last updated: 2024-07-01
Post by xgongx on What is the insights of IoDrvEtherCAT.DCInSyncWindow?
CODESYS Forge
talk
(Post)
It is well known that you need to increase the value of IoDrvEtherCAT.DCInSyncWindow to solve the "Fieldbus lost synchronicity" issue. In the official document, IoDrvEtherCAT.DCInSyncWindow is explained as the toleration of a certain jitter. But the official document doesn't explain what kind of the jitter is. Is it the jitter of DC sync deviation, master timer or something else? It is very important to know the insights of IoDrvEtherCAT.DCInSyncWindow. For example, if it is the toleration of DC sync deviation, and the official recommending value is 200us for CODESYS SoftMotion. It means maximum of DC sync deviation is 200us. It is unacceptable for some high precision motion control tasks, for example high speed gear task, etc. Increasing the value of IoDrvEtherCAT.DCInSyncWindow will increase the deviation of motor rotation sync if it is the toleration of DC sync deviation. So, would anyone tell me what the insights of IoDrvEtherCAT.DCInSyncWindow is? Thanks.
Last updated: 2024-07-09
Post by trusty-squire on CNC - How to manipulate SMC_GeoInfo objects
CODESYS Forge
talk
(Post)
I have an application using CNC GCode interpolation, but I need to modify the GCode provided to the PLC based on certain parameters. I am currently attempting to modify the SMC_GeoInfo objects in the SMC_OutQueue using the code below. Note that all the other code is pretty standard and works fine, but when I add the below it errors. PROGRAM TEST VAR fbReadCncFile : SMC_ReadNCFile2; fbCncInterpreter : SMC_NCInterpreter; arrCncInterpreter : ARRAY[1..99] OF SMC_GeoInfo; pGeoInfo: POINTER TO SMC_GeoInfo; giGeoInfo: SMC_GeoInfo; // ... END_VAR // ... Some code here in order to read CNC file using SMC_ReadNCFile2 and provide to SMC_NCInterpreter pGeoInfo := SMC_GetObj(poq:=ADR(fbCncInterpreter.poqDataOut), n:=1); IF pGeoInfo <> 0 THEN giGeoInfo := pGeoInfo^; // Do some manipulation here, then update the queue at the same position MC_SetObj(poq:=ADR(fbCncInterpreter.poqDataOut) , n:=0 , pgi:=ADR(giGeoInfo) ); END_IF It throws an error when I get to the line giGeoInfo := pGeoInfo^; Error: EXCEPTION [AccessViolation] occured: App=[Sim.Device.Application], Task=[PathTask] How do I use SMC_GetObj and access the data? It creates a pointer with the value as shown in the photo, but all the dereferenced values say dereference of invalid pointer.
Last updated: 2024-07-26
Post by egau on Hard shutdown: no code on device after power on
CODESYS Forge
talk
(Post)
This explanation aligns with the issues weāre experiencing with our machines. The scenario I described is happening with one of them (letās call it Machine A). This machine is identical to another one (Machine B), except for some custom code that facilitates communication with an external Beckhoff PLC for MES integration in the production line. Machine B has been powered on and off daily for at least three months and has never had this problem. Given that, I highly doubt the MES custom code is the cause of the code corruption. This being said, your explanation does seem plausible. However, if faulty EtherCAT cables were the issue, why wouldn't the error occur during normal operation? Why would bad cables only cause problems during a hard shutdown? One last question: When you encountered this behavior, did you see a similar error in your logs? i.e, an "AccessViolation" exception in the EtherCAT Task?
Last updated: 2024-10-03
Post by breiter on Frustration-Fueled Feedback on Project File Management and Git Integration
CODESYS Forge
talk
(Post)
Hi, supporting a text based storage format is on our roadmap, see https://www.codesys.com/the-system/releases-updates-lifecycle/release-plan-roadmap.html It will be an Add-On feature called "File Based Storage" for the professional developer edition. Structured text POUs will be stored as plain text. Other graphical languages will remain in an xml format. You will be able to switch the storage type for projects. Certain workflows will become easier this way. Nevertheless restrictions will remain because of CODESYS specific storage logic (for example how methods below function blocks are stored as file). So merging using our Git Integration Add-On remains the recommended workflow. A workflow involving Visual Studio Code as the main IDE is not supported. Simply because many topics like library management, task configuration or fieldbus configurators are not available for VS Code. A PLC project is a lot more than just some ST POUs. Best Regards
Last updated: 2024-10-16
Post by ellocco on XOR with four Inputs with OR-, NON- and AND-Operators
CODESYS Forge
talk
(Post)
My topic is more of academic nature, I would like to implement an XOR-operation with four inputs on my own (without the predefined XOR-operator) in a function block diagram (FBD). I have two proposals. One works fine and the other one is just an idea, but I do not know, if it is possible to code it in CODESYS V3.5 SP18 in form of a FBD. Here the one that works: And here an idea, which I have not managed to code it as an FBD: Any ideas? Is the 2nd diagram a correct interpretation of the coding task? And is there a way to implement it in form of an FBD in CODESYS V3.5 SP18? Followup (08-Nov-2024): Also in the current version of CODESYS (V3.5SP20Patch3) I have not managed to connect the existing blocks. In the alternative SPS-IDE PLCnext Engineer it is possible.
Last updated: 2024-11-08
Post by dogulas on OPC UA C# client connecting to OPC UA CODESYS server
CODESYS Forge
talk
(Post)
Ok, I have a simple test environment. From C#, using OPC UA, I can read DINTs, write DINTs, read Structs, but when I try to write a struct I get BadNotWritable. I am using Communication Manager, OPC UA Server, and IEC Symbol Publishing. I have a struct defined with one single DINT in it. The instance of the struct is in GVL. The struct is marked read/write in IEC Symbol Publishing. Any ideas? Pointers are welcome. public static async Task WriteStructA(byte[] structAData) { if (_session == null) throw new Exception("session is null"); // create a RequestHeader RequestHeader requestHeader = new RequestHeader { Timestamp = DateTime.UtcNow, TimeoutHint = 30000 // timeout in milliseconds }; // create an ExtensionObject to wrap the value to be written ExtensionObject extensionObject = new ExtensionObject( new ExpandedNodeId("GVL_StructA", 5), structAData ); // create a WriteValue object to hold the value to be written WriteValue writeValue = new WriteValue { NodeId = _structANodeId, AttributeId = Attributes.Value, Value = new DataValue(extensionObject) }; // put the WriteValue object into a WriteValueCollection object WriteValueCollection writeValueCollection = new WriteValueCollection() { writeValue }; // perform the write operation asynchronously WriteResponse writeResponse = await _session.WriteAsync( requestHeader, writeValueCollection, CancellationToken.None ); // check the result of the write operation if (writeResponse.Results[0] != StatusCodes.Good) throw new Exception("Write failed: " + writeResponse.Results[0]); }
Last updated: 2024-12-17
Post by struccc on The future and proper use of CAA.BOLT, CAA.SEMA,..
CODESYS Forge
talk
(Post)
Dear All, Dear CODESYS, I'm curiously following CODESYS transitioning away from the CAA libraries, and I'm mostly in favor of these major changes. Naturally, I'd like to align my current (not end-user) developments accordingly. I'm tracking , reading release notes, ... And want to figure out the future :) Is it possible to hear / read more about the reasons, objectives and scope of these changes? One important element is CAA Types - CAA Types Extern. What is the plan with that? What's the future of CAA.SEMA, CAA.BOLT ? I have never used them (always relied on SysLib*), but they are tempting... Would be useful to have a platform independent "Macro" for this functionality... Is there something in existing or planned ? Are they suitable to be used in low level libraries... For Example IO-Drivers, Components, "to-become system libraries"? CAA.TaskLock, CAA.TaskUnlock ? Well, they don't claim platform independency, so I can't rely on those.... Any up-to-date advise, standard, pattern to follow in new libraries for task and resource locking? Practical set of conditional defines to be used? If this information is not publicly available, can you please send a private message about the proper way to achieve this? I have support agreement, just couldn't get trough with these questions... P.
Last updated: 2025-03-14
Post by jschu on Dynamical scaling of bar graph without the bar itself
CODESYS Forge
talk
(Post)
Hi there, Task: dynamical changing the scaling of an bar graph, linear scaling whitout showing the bar only the scaling values and Lines for Main and partial steps. Define 4 Limits for Hi and LO Values with different colors Option 1 : use the bar graph whitout showing the actual bar whitout showing the bar, only the scaling values and lines for main and partial steps. Then what to do with the 4 Limits ? I could use 4 moveable Rectangles with the start and end value fo the areas but then the whoel bargraph must be transparent. Best way would be if only the scale ist possible to show as it is possible for the Meter 180° but this option does not exist for the bargraph. Option 2 : user defined HMTL5 Widgets wich may be some allreay has created or where is a dome for using this kind of html5 widget. The expanse for use html is in my eyes to big and gives more option for errors. Have some one experience in this topic or a hint how to do it the easiest way? Thanks for your help.
Last updated: 2025-05-15
Post by jy77812 on MC_MoveCircularAbsolute Using Help
CODESYS Forge
talk
(Post)
Dear People Iām trying to draw a circle using MC_MoveCircularAbsolute, but I keep encountering an error. The error message is SMC_CP_CIRCLE_CENTER_NOT_ON_BISECTOR. What Iām trying to do is simply draw a circle with a diameter of 20, starting from the point X=0, Y=0. Iāve set CircMode to center. It seems like a simple task, but the error keeps occurring, and itās giving me a headache. Iād appreciate your help. Iāve also attached the program, so please provide any advice you can. I want to use the mode as the center. I've tried changing multiple coordinates and it won't run. Please help. sample stCirculAuxPoint.c.X := 20; stCirculAuxPoint.c.Y := 10; stCirculEndPoint.c.X := 20; stCirculEndPoint.c.Y := 30; fbMoveCircularAbsolute( AxisGroup := AxisGroup, Execute := xGroupCirculEx, CircMode := SMC_CIRC_MODE.CENTER, AuxPoint := stCirculAuxPoint, EndPoint := stCirculEndPoint, PathChoice := 0, Velocity := 50, Acceleration := 50, Deceleration := 50, Jerk := 50, CoordSystem := SMC_COORD_SYSTEM.MCS, BufferMode := 0, TransitionMode := 0, TransitionParameter := , OrientationMode := , VelFactor := , AccFactor := , JerkFactor := , TorqueFactor := , Name := , Done => , Busy => , Active => , CommandAborted => , CommandAccepted => , Error => , ErrorID => , MovementId => );
Last updated: 2025-06-04
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 mubeta on Some 'pathetic' errors in SoftMotion program
CODESYS Forge
talk
(Post)
Yes, this is the error the sometimes show up. What make me crazy is the fact that it happens randomly and not each times. I know very well where the problem is, in wich one program row it's located. For each actions of the state machine I have all events recorded with log on text file. it is not problematic for me to find the application point of the fault, but I need to understand why occasionally and for no apparent reason, switching the state machine and thus changing the motion FB, sends the axis into failure (but only occasionally). For example, one case that is often problematic is the execution of the Axis Halt instruction. When, after a MoveAbosulte instruction this returns the event as 'done' and indeed the axis is in standstill, the state machine first sets the move instruction to FALSE, and the next cycle sets the Halt request to TRUE. Some of the time everything works out fine. Occasionally, however, in this exchange, the axis goes into fault, also losing the OPERATIONAL state. Meanwhile, I would like to understand why the motion FB instances must still be called even after the Execute is set to FALSE, especially in view of the fact that the next instruction is programmed to abort the previous one, with BufferMode set to 'Aborting'. All these unnecessary FB calls are an unnecessary overhead on the CPU anyway. Is there any precise rule about when to cease calling the various instances? (It should precisely be the 'done' status that says this one has finished its work).
Last updated: 2024-07-18
Post by maldus512 on How to adapt Codesys Control SL to custom board
CODESYS Forge
talk
(Post)
Hello everyone, I have been given the task to develop I/O drivers for a custom made, Linux based board to allow for Codesys applications to run and control the hardware. I have successfully installed Codesys Control SL for ARM/Linux and tested it with a simple demo application. Now I should start interfacing the runtime to the actual hardware; I should be able to interact with 2 RS485 serial ports, a few GPIOs and an I2C port, all of which already have the corresponding /dev/ interface in the Linux system. I am having trouble understanding how it should be approached. I have found sporadic references that fail to lead to a really comprehensive documentation. For example: The store page (https://store.codesys.com/en/codesys-control-for-linux-arm-sl-1.html#options) mentions a "runtime package" that should allow "Integration of existing C code" and "Usage of local I/Os", which seems exactly what I need to interact with custom peripherals. I have found no further reference to Codesys-C interpop. The Codesys Help page for the runtime package has a page on the "Development of Drivers" (https://content.helpme-codesys.com/en/CODESYS%20Control/rtsllinuxrbpdriverdevelopment.html) that suggests to either "Implement a function block" or "Implement I/O drivers". Those in turn lead to this page (https://forge.codesys.com/drv/io-drivers/doc/Generic/) which describes briefly an XML schema to describe new devices; unfortunately, it doesn't mention what to do with such a description (i.e. how does the runtime know about it) or how it is in any way connected to the actual hardware. Could anyone give me some pointers? I should also mention I have no prior experience with Codesys, so maybe I'm missing an obvious answer.
Last updated: 2024-08-09
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
Post by mgabryel on Problems with CAN 2.0 comunication on Wago PLC (Codesys 3.5)
CODESYS Forge
talk
(Post)
Hello, I am trying to program CAN Bus comunication on WAGO PLC (more precisely on WAGO Touch Monitor model TP600). I am using for this purpose library "WagoAppCanLayer2" from Wago company. My IDE for programming this device is CODESYS V3.5 SP19 Patch 2 + (64-bit). My program is written in Structured text using function blocks from previously mentioned library. Here is code of this program: 1) Variables declarations: PROGRAM PLC_PRG VAR oOpenInterface : WagoAppCanLayer2.FbCanL2Open :=( udiBaudrate := 125000 ); xInterfaceIsOpen : BOOL; sInterfaceInfo : STRING; oReceive : WagoAppCanLayer2.FbCanRx29BitFrame :=( xBufferMode := FALSE, wCanId := 16#181 ); xRecv : BOOL; sReceiveInfo : STRING; oSend : WagoAppCanLayer2.FbCanTx29BitFrame :=( dwCanId := 16#100, //was 16#201 xRtrFrame := FALSE ); xSend : BOOL; sSendInfo : STRING; oCanDiag : WagoAppCanLayer2.FbCanErrorInfo; xRst : BOOL; aSendData : ARRAY [1..8] OF BYTE; bSendLen : BYTE; TON_0 : TON; TON_1 : TON; END_VAR 2) Program body: oOpenInterface( xEnable := NOT xInterfaceIsOpen, I_Port := IoConfig_Globals.WAGO_CAN_LAYER2_DEVICE ); sInterfaceInfo := oOpenInterface.oStatus.GetDescription(); xInterfaceIsOpen S= oOpenInterface.xValid AND NOT oOpenInterface.xError; oReceive( xEnable := xInterfaceIsOpen, I_Port := IoConfig_Globals.WAGO_CAN_LAYER2_DEVICE, xRxTrigger := xRecv ); sReceiveInfo := oReceive.oStatus.GetDescription(); IF NOT xRecv THEN IF oReceive.bRxNBytes > 0 THEN oReceive.aRxBuffer[1]; oReceive.aRxBuffer[2]; oReceive.aRxBuffer[3]; oReceive.aRxBuffer[4]; oReceive.aRxBuffer[5]; oReceive.aRxBuffer[6]; oReceive.aRxBuffer[7]; oReceive.aRxBuffer[8]; END_IF xRecv := TRUE; END_IF aSendData[1] := 224; aSendData[2] := 13; aSendData[3] := 14; aSendData[4] := 15; aSendData[5] := 222; aSendData[6] := 13; aSendData[7] := 14; aSendData[8] := 15; bSendLen := 8; TON_0(IN:= NOT TON_1.Q, PT:= T#2S , Q=>xSend, ET=> ); TON_1(IN:= TON_0.Q, PT:= T#2S , Q=>, ET=> ); oSend( xEnable := xInterfaceIsOpen, I_Port := IoConfig_Globals.WAGO_CAN_LAYER2_DEVICE, aTxBuffer := aSendData, bTxNBytes := bSendLen, xTxTrigger := xSend ); sSendInfo := oSend.oStatus.GetDescription(); oCanDiag( xEnable := TRUE, I_Port := IoConfig_Globals.WAGO_CAN_LAYER2_DEVICE, xTriggerResetCounter := xRst, xValid=> , xError=> , oStatus=> , wBusState=> , wBusDiag=> , uiRxOverflowsL2=> , uiTxOverflowsL2=> , uiRxOverflows=> , uiMsgTimeouts=> , uiBusOffs=> , uiBusWarnings=> ); Program first opens comunication on CAN 2 device and then periodically try send one CAN data frame. After starting program CAN 2 interface is properly open. The xSend variable is toggling with period 2s. When program sends data an "Tx overflow" error appears. When I am watching CAN_H line on DSub 9 socket i am not able to see proper CAN frames - see screenshot attached to this message. Could somebody help me determine what is wrong with this program. Best regards
Last updated: 2024-08-02
Post by mondinmr on Frustration-Fueled Feedback on Project File Management and Git Integration
CODESYS Forge
talk
(Post)
In reality, other vendors are already moving towards integration with VS Code. B&R, for example, is likely the only one that could truly challenge Codesys in the market: theyāve overhauled their once-archaic environment (previously lacking ST OOP) and are now catching up significantly with Automation Studio Code, offering modern programming capabilities and native support for tools like Git and GitHub Copilot. The other big names in the market, frankly, are still light years behind. For smaller projects, typically handled by āwire strippersā (with all due respect!), a classic environment might be just fine. But once youāre dealing with thousands or even millions of lines of codeāpossibly organized in an OOP paradigm, spanning large teams, integrating third-party libraries, requiring version control, and performing comprehensive testsāa lightweight, responsive editor supercharged with AI-based features becomes essential. The real strength of something like VS Code lies in its vast ecosystem of extensions and integrations: from advanced Git support to automated build/test pipelines, and even AI-assisted autocompletion that already makes software development much more agile and productive. I understand that a PLC project involves more than just ST code (task setup, fieldbus configuration, libraries, etc.). However, thereās no technical reason not to at least provide ST files in a pure text format, making version control and collaboration far easier. B&R has clearly adopted this approach; I hope Codesys will accelerate its own efforts to offer a native, text-based integration and modern development tooling. Once you go beyond a certain level of complexityādozens of configurations, OOP hierarchies, and distributed teamsāyou really do need āengineer-levelā software tools, not just solutions targeting āwire strippers.ā For large-scale automation projects, a more open and flexible approach is the only way to avoid chronic frustration. Let me emphasize that I truly love Codesys and consider the work done so far to be brilliantāIād be sorry to see it overshadowed by others moving faster in this direction.
Last updated: 2025-02-18
Post by mondinmr on Direct Pointers in IOMapping for EtherCAT with IoDrvEthercatLib.ETCSlave_Dia
CODESYS Forge
talk
(Post)
I have found a very interesting solution using: IoConfigTaskMap IoConfigConnectorMap IoConfigChannelMap The first is the list of IO tasks. The second is the connector for each IO module in the IOMap. The third is the individual input or output on the IOMap. One of the properties of the connector is another pointer to a connector, which corresponds with the connector of the EtherCAT slave. Through this information, it is possible to understand to which EtherCAT slave an IO connectormap corresponds. I am attaching an FB that allows for the construction of an IO map and finding the pointer to the actual IOs in the IOMap based on the bitoffset. FUNCTION_BLOCK IOExplorer VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR inputChannels: COL.LinkedList; outputChannels: COL.LinkedList; ulintFactory: COL.UlintElementFactory; END_VAR METHOD inputAtBitOffsetOfConnector : POINTER TO BYTE VAR_INPUT conn: POINTER TO IoConfigConnectorMap; bitOffset: UDINT; END_VAR VAR it: COL.LinkedListIterator; itf: COL.IElement; elem: COL.iUlintElement; channelInfo: POINTER TO ADVChannelInfo; bitOffsetR: UDINT; END_VAR inputChannels.ElementIterator(it); WHILE it.HasNext() DO it.Next(itfElement => itf); __QUERYINTERFACE(itf, elem); {warning disable C0033} channelInfo := TO___UXINT(elem.UlintValue); {warning restire C0033} IF channelInfo^.connectorField = conn THEN IF bitOffsetR = bitOffset THEN inputAtBitOffsetOfConnector := channelInfo^.addr; RETURN; END_IF bitOffsetR := bitOffsetR + channelInfo^.size; ELSE bitOffsetR := 0; END_IF END_WHILE inputAtBitOffsetOfConnector := 0; END_METHOD METHOD outputAtBitOffsetOfConnector : POINTER TO BYTE VAR_INPUT conn: POINTER TO IoConfigConnectorMap; bitOffset: UDINT; END_VAR VAR it: COL.LinkedListIterator; itf: COL.IElement; elem: COL.iUlintElement; channelInfo: POINTER TO ADVChannelInfo; bitOffsetR: UDINT; END_VAR outputChannels.ElementIterator(it); WHILE it.HasNext() DO it.Next(itfElement => itf); __QUERYINTERFACE(itf, elem); {warning disable C0033} channelInfo := TO___UXINT(elem.UlintValue); {warning restire C0033} IF channelInfo^.connectorField = conn THEN IF bitOffsetR = bitOffset THEN outputAtBitOffsetOfConnector := channelInfo^.addr; RETURN; END_IF bitOffsetR := bitOffsetR + channelInfo^.size; ELSE bitOffsetR := 0; END_IF END_WHILE outputAtBitOffsetOfConnector := 0; END_METHOD METHOD scanIO VAR_INPUT END_VAR VAR numTasks: DINT := IoConfig_Globals.nIoConfigTaskMapCount; tType: WORD; ioTask: POINTER TO IoConfigTaskMap; numCon: WORD; connector: POINTER TO IoConfigConnectorMap; numCh: DWORD; channelInfo: POINTER TO ADVChannelInfo; iTsk: DINT; iCon: WORD; iCh: DWORD; i: DINT; _tmpConnList: COL.IList; elem: COL.IUlintElement; itf: COL.IElement; tmpCh: POINTER TO ADVChannelInfo; lastE: DINT; e: COL.COLLECTION_ERROR; e1: Error; END_VAR VAR_INST lF: COL.ListFactory; END_VAR IF outputChannels.CountElements() > 0 OR inputChannels.CountElements() > 0 THEN RETURN; END_IF _tmpConnList := lF.CreateDynamicList(16, 16); //Iterate through all IO tasks FOR iTsk := 0 TO numTasks - 1 DO ioTask := ADR(IoConfig_Globals.pIoConfigTaskMap[iTsk]); //Store the type of the task (Input or Output) tType := ioTask^.wType; numCon := ioTask^.wNumOfConnectorMap; //Iterate through all connectors of the task FOR iCon := 0 TO numCon - 1 DO connector := ADR(ioTask^.pConnectorMapList[iCon]); numCh := connector^.dwNumOfChannels; //Iterate through all channels of the connector FOR iCh := 0 TO numCh - 1 DO //Create a new channel info object and fill it with the address, connector and size of the channel //Connectors is address of field connector in this case like EtherCAT slave //Address is the address of the IOMap //Size is the size of channel data in bits in IOMap channelInfo := __NEW(ADVChannelInfo); channelInfo^.addr := connector^.pChannelMapList[iCh].pbyIecAddress; channelInfo^.connectorField := connector^.pConnector; channelInfo^.size := connector^.pChannelMapList[iCh].wSize; //We put the channel info a temporary ordered list //Order is based on the address of IOMap lastE := TO_DINT(_tmpConnList.CountElements()) - 1; FOR i := 0 TO lastE DO _tmpConnList.GetElementAt(udiPosition := TO_UDINT(i), itfElement => itf); __QUERYINTERFACE(itf, elem); {warning disable C0033} tmpCh := TO___UXINT(elem.UlintValue); {warning restire C0033} //If the address of the channel is smaller than the address of the channel in the list IF tmpCh^.addr > channelInfo^.addr THEN //Insert the channel in the list at the current position _tmpConnList.InsertElementAt(TO_UDINT(i), ulintFactory.Create(TO_ULINT(channelInfo))); //Clear the channel info pointer channelInfo := 0; //Exit the loop i := lastE + 1; END_IF END_FOR //If the channel info is not 0, it means that the channel was not inserted in the list IF channelInfo <> 0 THEN //Add the channel to the end of the list elem := ulintFactory.Create(TO_ULINT(channelInfo)); _tmpConnList.AddElement(elem); END_IF END_FOR //Iterate temporary list and add the channels to the input or output list lastE := TO_DINT(_tmpConnList.CountElements()) - 1; FOR i := 0 TO lastE DO _tmpConnList.GetElementAt(udiPosition := TO_UDINT(i), itfElement => itf); __QUERYINTERFACE(itf, elem); {warning disable C0033} tmpCh := TO___UXINT(elem.UlintValue); {warning restire C0033} //If type is input, add the channel to the input list IF tType = TaskMapTypes.TMT_INPUTS THEN e := inputChannels.AddElement(ulintFactory.Create(TO_ULINT(tmpCh))); //If type is output, add the channel to the output list ELSIF tType = TaskMapTypes.TMT_OUTPUTS THEN e := outputChannels.AddElement(ulintFactory.Create(TO_ULINT(tmpCh))); ELSE __DELETE(tmpCh); END_IF END_FOR //Clear the temporary list _tmpConnList.RemoveAllElements(); END_FOR END_FOR END_METHOD
Last updated: 2024-02-13
Post by smeitink on Timeout Error in Modbus Communication with WAGO PFC200 and iEM2050 Meter using 750-652 Module
CODESYS Forge
talk
(Post)
Hi all, I'm looking for help with an issue I've come across while trying to facilitate Modbus communication between a WAGO PFC200 PLC using a 750-652 communication module and an iEM2050 Series Single Phase Energy Meter. I believe to have everything wired and setup correcty, but I keep running into a "Error time out" message, and by now I don't really know what else to try. My setup is as follows: A PFC200 Wago PLC, which has 2 750-652 Serial Interfaces extension modules connected to its field bus. I'm using one of these to talk to a Schneider iEM2050 - kWh-meter over modbus. I have connected terminal 23 (A) of the iEM2050 to connector 6 (A) on the 750-652. I have connected terminal 24 (B) of the iEM2050 to connector 2 (B) of the 750-652. I'm using 200mm of twisted together wires to connected them both, and I have placed a 120 ohm resistor between A and B at both ends. I've attached relevant pinout images to this post. I then wrote a simple program that configures the Mobus port, as per the datasheet of the iEM2050. You can find an image of the relavent page attached to this post too. This is my program: PROGRAM PLC_PRG VAR Master: FbMbMasterSerial; xIsConnected: BOOL; xError: BOOL; iIndex: INT := 1; xTrigger: BOOL; utQuery : typMbQuery := ( bUnitId := 1, // The Modbus unit or slave address bFunctionCode := 4, // Function code for reading input registers uiReadAddress := 1829, // adress for the Power on off counter uiReadQuantity := 1 // Quantity of registers to read ); iStep: INT; oStatusModbus: WagoSysErrorBase.FbResult; utResponseModbus: typMbResponse; xConnect: BOOL := FALSE; delayTimer: TON; END_VAR Master( xConnect:= xConnect, I_Port:= _750_652_24_1, udiBaudrate:= 9600, usiDataBits:= 8, eParity:= WagoTypesCom.eTTYParity.Even, eStopBits:= WagoTypesCom.eTTYStopBits.One, eHandshake:= WagoTypesCom.eTTYHandshake.None, ePhysical:= WagoTypesCom.eTTYPhysicalLayer.RS485_HalfDuplex, xIsConnected=> xIsConnected, xError=> xError, oStatus=> oStatusModbus, eFrameType:= WagoAppPlcModbus.eMbFrameType.RTU, tTimeOut:= T#5S, utQuery:= utQuery, xTrigger:= xTrigger, utResponse:= utResponseModbus); delayTimer(IN := TRUE, PT := T#3S); // Use the Q output of the timer to set xConnect after the delay IF delayTimer.Q THEN xConnect := TRUE; END_IF CASE iStep OF 0: //Wacht totdat de master de poort geopend heeft IF xIsConnected THEN iStep := 1; END_IF 1: //Stuur request naar de slave xTrigger := TRUE; iStep := 2; 2: //Wacht totdat de master klaar is met het afhandelen van de request IF NOT xTrigger THEN iStep := 3; END_IF END_CASE The TON delay before opening the port is due to a an error I encountered when opening it straight away. This seems to be a bug, as described here. However, the TON solved that particular issue. I tried reading multiple registers, but like I said, I still always end up with the "Error time out". What else can I test or try at this point?
Last updated: 2024-02-24
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 drbuzz on Communication Error (#0) for IFM controller
CODESYS Forge
talk
(Post)
Hi Folks, Every time I use an IFM controller I always seem to run into a problem connecting to it. I get the Communications Error (#0). So I thought I would share some tips and tricks. Once the CANfox Cable (EC2112) cable driver is installed, you can use the yellow app in the sys tray to blink the lights on the cable. Confirm the cable works in the IFM maintenance software by connecting to the controller and reading the information on it. Make sure to download an OS into the controller (the light will go from a fast blink to solid green). In Codesys V2.3, the communication settings for the CR0401 is 250kBaud by default and Node ID 127. What got me, was I needed to reboot the computer after the cable driver install. Also if your application has canbus settings in it which are changed from default, after the controller is power cycled, the new Node ID and Baud will be in effect. I made a handy guide because too much time has been wasted on this. Programming IFM CR0401 Serial/Can Programming Cable ⢠Connect IFM EC2112 CanFox programming cable with connector adapter. ⢠Make sure cable is linked to VM (if using VM). ⢠Install drivers for cable if not installed. o Download from IFM EC2112 site. https://www.ifm.com/ca/en/product/EC2112 ⢠Once Installed, reboot computer. ⢠In system tray, there should be a yellow icon that you can open and check on programming cable. Select the cable in the list and flash the lights to confirm it is working. Maintenance Software ⢠Install IFM Maintenance Tool Software. o Download from IFM Site. https://www.ifm.com/ca/en/download/eco100_MaintenanceTool ⢠Open IFM Maintenance software ⢠Select Basic System ⢠Select CAN cable ⢠It will tell you if you donāt have a cable connected. ⢠Use Wizard if needed. ⢠Read Channel Parameter on the Settings page, or get Identity in the System Information > Identity. ⢠Default Node is 127 on a new unit. Baud is 250kBaud (bits/sec) ⢠Controller information should populate. ⢠Controller green light should be blinking at 5hz (meaning OK but no OS, just bootloader). ⢠Click Software > Load. ⢠Open the OS file. Should match Codesys version selection (for CR0401 this is version 3). o Download OS file from IFM Website. https://www.ifm.com/ca/en/product/CR0401 o It is located at the top of the download under āsoftware for CR0401ā. o Select the file and load it⦠this will take a minute. ⢠Once completed the unit should now have a solid green light o Solid green means the controller has an OS but no application is running. Codesys V2.3 Application ⢠Codesys needs to be downloaded and installed from the IFM website as it has the IFM libraries and license to use the software. o Download from the IFM CR0401 page. o https://www.ifm.com/ca/en/product/CR0401 ⢠Create new application with the correct IFM controller or Open Codesys application. ⢠Keep in mind that the PLC Configuration on the Resources tab can be changed for the CAN communication interface⦠so changes to node and baud will take effect after the first download and reboot of the controller. ⢠Go to āOnlineā in the top menu and change āCommunication Parametersā o The Local dropdown shows the last configuration used. All other interfaces will show below it and need to be updated when changed or used. o Confirm Node ID is 127 for the first download. ļ§ The NodeID will change to whatever the program has after (in my case 125). ļ§ Node Send Offset should be default at 1536 ļ§ Node Recv Offset should be default at 1408 ļ§ Can bus Baudrate should be 250 kbaud. ļ§ Yes to Motorola Byte Order ļ§ Block Transfer should be false and note used (60 is default setting). ļ§ Can Card Driver should match the systray item which is Sie_USB. ⢠If the system populated the other one, just update and relay the communication parameters. The software will usually bring up the available cable and driver. ⢠Go to āOnlineā and Login to download. o Press Yes to Download Application. I hope this helps!
Last updated: 2025-03-21
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
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
.