Search talk: Visu FB

 
<< < 1 .. 25 26 27 (Page 27 of 27)

Post by herbasso88 on WebVisu flickering CODESYS Forge talk (Post)
Good morning, I'm new on Codesys Forge, so I'm not sure if this is the right place to talk about my problem. When I open my WebVisu pages with Microsoft Edge, or Chrome, the background and also some rectangles blinking without reason!!! The application is developed with Codesys 3.5.17.10 and run on Codesys HMI, same version (3.5.17.10). After several experiments I discover that the problem happens when I made dynamic the "End of area" property of a meter object, but I can't understand why this blinking problem happens. Also, the problem is only at the WebVisu page, the "normal" VISU pages (the ones opened when Codesys HMI start) work always perfectly. Another strange thing is that the problem happens only if on the same page, where there is the meter object, there is also a trend object!?!? Codesys HMI is running on a Virtual Machine (VMware Workstation 15 player, v.15.5.6) running Windows 10 Pro N 64-bit. The blinking problem happen also if I convert the project to Codesys 3.5.20.0. This version of Codesys and Codesys HMI are installed on a Virtual Machine running Windows Server 2019 Standard 64-bit. In attachment the archive of my project. The attached project has only one page, if "Enable Counter" is not pressed the "End of area" variable of the meter is not updated in the software, and everything work well, normal VISU and WebVisu; if "Enable Counter" is pressed, the "End of area" variable of the meter is updated in the software, and the WebVisu page start blinking. I tried also to enable the "Support client animations and overlay..." property at VisualizationManager, this seems stop the blinking problem, but that property also destroy my WebPage, moving almost all the graphical object, that also seem not working anymore. I really need help to understand what I'm doing wrong, I have to develop a bigger project and I have to understand if trend objects and animated meters cannot stay in the same page. In the final project the WebVisu will be very important because the customer will use this way to access the application to monitor the process. Regards
Last updated: 2024-05-06

Post by axilleas on SMC_Interpolator + SMC_controAxislbyPos CODESYS Forge talk (Post)
dear all I am working on a very generic gantry system (virtual drives + win v3 control) reading gcode from external file. In order to stop the interpolator function from running when gaps are detected, SMC_controlAxisByPos FB has the bStopIpo output which according to the manual is connected to the Interpolator's bEmergencyStop. Lets assume that the axis are parked in position X1000 Y1000 and the initial G code movement is G00 X500 Y500. The normal behavior is to travel from the actual x1000 y1000 to G00 X500 Y500. The SMC_Interpolator always gets the X0 Y0 as the initial position, meaning that the bStopIpo is active until the axis are in X0 Y0 and the release the interpolator to set the new positions to X500 Y500. Is there a suggested method to solve this behavior? bonus question: I get a lot of bStopIpo during standard interpolation movements (not gaps). While working with virtual axis this is not a problem but when real axis are installed this will be an issue. What exactly triggers the bStopIpo output? Slow axis accelerations compare to Gcode defaults? Kind Regards
Last updated: 2024-02-05

Post by alexgooi on Modbus writing on value change CODESYS Forge talk (Post)
Hi Duvan, You could make this in 1 single object (FB), Indeed don't use a function for this beacuse you need some memory to keep the old value. For i := 0 TO 200 BY 1 DO //Check if the value has been changed IF Old_Value[i] <> Value[i] THEN //Set the trigger to TRUE Trigger[i] := TRUE; Old_Value[i] := Value[i]; END_IF END_FOR If you define the Value array as an In_Out and the Trigger as an In_Out you arn't claiming any aditional memory to your system. You ofcourse then need to add some code arround it that does something with the trigger and writes it back to FALSE again. If you want more flexability you also could use pointers instead of using the IN_OUT FOR i := 0 TO 200 BY 1 DO address := address_Input + i * SIZEOF(*Put type here); IF Address^ <> Old_Value[i] THEN Trigger[i] := TRUE; Old_Value[i] := Address^; END_IF END_FOR
Last updated: 2024-04-02

Post by mxj262 on FB having single input but initialized with Array CODESYS Forge talk (Post)
I am adding elements of an ARRAY using pointer to access each element inside a FOR loop and the FOR loop does not stop! What is the right way to use pointers in such case?? I have another loop that is not using pointer and it stops but the loop using pointer keep on adding. METHOD FB_Init: BOOL VAR_INPUT bInitRetains: BOOL; // TRUE: the 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_IN_OUT // basically REFERENCE TO window_buffer: ARRAY [*] OF INT; // array of any size END_VAR THIS^.windowPtr := ADR(window_buffer[0]); THIS^.windowSize := UPPER_BOUND(window_buffer, 1) - LOWER_BOUND(window_buffer, 1) + 1; FUNCTION_BLOCK FB500 VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR windowPtr: POINTER TO INT; windowSize: DINT; currentIndex: UINT; element1:INT; element2:INT; i:INT; j:INT; sum:DINT:=0; END_VAR element1:=windowPtr[0]; // read the first element of the Array dynamic memorry element2:=windowPtr[1]; FOR i:=0 TO (TO_INT(windowSize-1)) BY 1 DO // this loop does not stop Sum:=sum + windowPtr[i]; END_FOR FOR j:=0 TO 5 BY 1 DO // this loop stops j:=j+1; END_FOR https://ibb.co/k3DhkZT
Last updated: 2024-05-06

Post by paro on Modbus Client Request Not Processed CODESYS Forge talk (Post)
Hi, Problem in your code is that you are not calling the ClientFb cyclic. Please look at the Example from CODESYS: https://forge.codesys.com/prj/codesys-example/modbus/home/Home/ Your code works if the client fb is called cyclic! IF NOT initDone THEN initDone := TRUE; // configure clientTcp clientTcp(aIPaddr:=Ethernet.IPAddress, uiPort:=502); // configure clientSerial clientSerial(iPort:=SysCom.SYS_COMPORT2, dwBaudRate:=SysCom.SYS_BR_115200, byDataBits:=8, eParity:=SysCom.SYS_EVENPARITY, eStopBits:=SysCom.SYS_ONESTOPBIT, eRtuAscii:=ModbusFB.RtuAscii.RTU); // configure clientRequestReadCoils_1 clientRequestReadCoils_1(rClient:=clientTcp, uiUnitId:=42, udiTimeout:=TO_UDINT(T#10MS)); // configure clientRequestWriteSingleRegister clientRequestWriteSingleRegister(rClient:=clientTcp, uiUnitId:=43, udiTimeout:=TO_UDINT(T#10MS)); // configure clientRequestReadCoils_2 clientRequestReadCoils_2(rClient:=clientTcp, uiUnitId:=44, udiTimeout:=TO_UDINT(T#10MS)); // configure clientRequestReadInputRegisters clientRequestReadInputRegisters(rClient:=clientTcp, uiUnitId:=44, udiTimeout:=TO_UDINT(T#10MS)); END_IF // call the client FB's clientTcp(); clientSerial(); // call client request FB's clientRequestReadCoils_1(rClient:=clientTcp, xExecute:=TRUE, uiStartItem:=2, uiQuantity:=3, pData:=ADR(aDataCoils_1[0])); // for more details see Example_TCP, especially ClientRequest control (xExecute, xDone, xError). IF clientRequestReadCoils_1.xDone THEN // get data from aDataCoils_1 ... END_IF clientRequestWriteSingleRegister(rClient:=clientTcp, xExecute:=TRUE, uiItem:=3, uiValue:=123); clientRequestReadCoils_2(rClient:=clientTcp, xExecute:=TRUE, uiStartItem:=2, uiQuantity:=3, pData:=ADR(aDataCoils_2[0])); clientRequestReadInputRegisters(rClient:=clientTcp, xExecute:=TRUE, uiStartItem:=16, uiQuantity:=3, pData:=ADR(aDataInputRegisters[0]));
Last updated: 2024-05-29

Post by timvh on How to implement an interface (IElement)? CODESYS Forge talk (Post)
See: https://forge.codesys.com/prj/codesys-example/element-collect/home/Home/ This contains an application "OnlineChangeSafeLinkedListExample". What you should do is create a new interface which has your "Priority" property. Then your FB should extend the base element function block and implement your own interface: E.g. FUNCTION_BLOCK MyElement EXTENDS COL.LinkedListElementBase IMPLEMENTS I_MyInterface Then the __QUERYINTERFACE does the magic to check if your "element" also implements your interface. Something like this: // Compares this element with itfElement. // Returns 0 if the elements are equal, < 0 if the element is less than itfElement, // > 0 if the element is greater than itfElement. // This method will be called from sorted collections (e.g. |COL.SortedList|) to sort the elements. // IMPORTANT: The underlying value to be compared with MUST NOT be changed during the lifecycle of the object. METHOD ElementCompareTo : INT VAR_INPUT (* The element to compare*) itfElement : COL.IElement; END_VAR VAR itfIntElement : I_MyInterface; xResult : BOOL; END_VAR // We use integer iInt1 for sorting. xResult := __QUERYINTERFACE(itfElement, itfIntElement); IF xResult THEN IF iInt1 < itfIntElement.Priority THEN ElementCompareTo := -1; ELSIF iInt1 > itfIntElement.Priority THEN ElementCompareTo := 1; ELSE ElementCompareTo := 0; END_IF ELSE ElementCompareTo := -1; END_IF
Last updated: 2024-07-22

Post by mecmag on gear over gear (2 masters,1 slave) - how to do it? CODESYS Forge talk (Post)
Hello, i need to create an application that uses 2 masters, with 2 different ratios, and it outputs in one single slave. I explain better: Imagine axis A, B and C. -Axis A is the slave. -Axis B is master of A, with a specific ratio. -Axis C is master of A, with a specific ratio. the result motion from B and C should be executed by A, proportionally in position and ratios from B and C. With standard softmotion libraries (MC_...) it is not possible (i couldn't) because it is allowed only one master with its ratio. I have made a similiar application in past, using MoveOverGear in order to synch gears before engage. Instead this time, i need to do a gear over gear application, using 2 different masters. The position have to be the sum of both masters (considering their ratios). Any clue about how to do it? Or were to find some FB that can do it?
Last updated: 2024-08-16

Post by dominggus on when going online, stuck on "Syncing file "visuelemsdatetime.tl_datetime.txt" CODESYS Forge talk (Post)
Hi, We are currently using a Raspberry Pi 4 CM4 module in a EdgeBox RPI 200 - Industrial Edge Controller running the latest CODESYS Runtime Package 4.11.0.0. On the PC (actually an Intel Macbook Pro running Windows 10 in Parallels) we run CODESYS V3.5.19.50. Yesterday end of day when I was about to logoff and head home, I wanted to send the latest build to the Raspberry I clicked the Login button to compile a new version and then sync the application and all the files, it get's stuck on the last file to sync (see attached screenshot). This takes eternally, although sometimes, when I use my SFTP client (Cyberduck) and go into the raspberry and refresh the directory /var/opt/codesys/PlcLogic/visu/, or when I open the actual file visuelemsdatetime.tl_datetime.txt, it gets un-stuck (forcing a refresh, which might fix the syncing issue) and CODESYS continues and I can click the Start button to start the application. But this SFTP force refresh trick does not always help either... What could be the issue here? network connectivity? Can someone please help me out?
Last updated: 2024-03-02

Post by rmaas on Fieldbus has lost synchronicity CODESYS Forge talk (Post)
Hi, On a gantry system with 2 axis i am getting the following error: SMC_DI_FIELDBUS_LOST_SYNCRONICITY This happens random, sometimes it happens every 5 minutes and sometimes no error for 2 hours... The Setup: - Using codesys 3.5 SP20 with all latest libs... - Kontron AL Pi-Tron CM4 with Preempt realtime patch (Raspberry Pi 4) - Codesys runtime 4.11.0.0 (single core) - CODESYS Control for Raspberry Pi SL licensed - Softmotion + CNC + Robotics licensed - 2x Leadshine EL8-EC400 servo drives - Axis group for a 2-axis T-Gantry Ethercat network wiring: Ethercat master softmotion -> Beckhoff EK1100 -> Servo drive #1 -> Servo drive #2 Ethercat Cycle time = 4ms Max Jitter = 140~150 What i have tried so far: - changed the sync offset from 20% to 30% - changed ethercat task priority from 1 to 0 Running tasks: - Ethercat tast: Prio = 0, Interval = 4ms - Main task: Prio = 1, Interval = 8ms - Visu task: Prio = 31, Interval = 100ms - Softmotion planning task: Prio = 15, Freewheeling - 3 other default tasks that were created by AC_Persist Motion fb's are called in the ethercat task... Does anyone have an idea how to fix this? Any help is greatly appreciated!
Last updated: 2024-04-11

Post by kblundy on Change the Opening Position of the Dialog using VU.FbOpenDialog CODESYS Forge talk (Post)
I hope the community can help me with this. I need to use the Visu Utils FbOpenDialog to control the opening and closing of a dialog. I have the Opening and Closing working, but I can’t get the dialogue's position to be controlled. The code looks like this: PROGRAM OPEN_DIALOG VAR xOpenLatchSettingDialog : BOOL; TopLeftDialog : VisuStructPoint ; fbOpenLatchSettingsDialog : VU.FbOpenDialog ; END_VAR IF xOpenLatchSettingDialog THEN xOpenLatchSettingDialog:= FALSE ; TopLeftDialog.iX := 100; TopLeftDialog.iY := 23; fbOpenLatchSettingsDialog(sDialogName := 'visu_AlarmLatchSettings', xExecute := xOpenLatchSettingDialog , xModal := TRUE, itfClientFilter := VU.Globals.OnlyTargetVisu, pTopLeftPosition := ADR(TopLeftDialog)); CloseVisuDialog(sDialogName:= 'visu_AlarmLatchSettings'); ELSE xOpenLatchSettingDialog:= TRUE ; IF fbOpenLatchSettingsDialog.xError THEN xOpenLatchSettingDialog := FALSE; END_IF END_IF I can't seem to work out a way to make the values in TopLeftDialog.iX and TopleftDialog.iY be passed correctly in the call and for it to change the position of the dialogue box. The code is compiled, but the position has not been changed. Any guidance or suggestions for revising this code would be incredibly valuable. Your insights could be the key to solving this issue.
Last updated: 2024-05-05

Post by biiebs on Aufbau von Ablaufsteuerungen ermitteln CODESYS Forge talk (Post)
Hallo Zusammen, gibt es in CODESYS bei Ablaufsteuerungen weitere Möglichkeiten außer den AS-Einstellungen z.B. die Aufbaustruktur der Ablaufsteuerung herauszufinden? Gesamtanzahl der verwendeten Aktionen / Schritte - Im besten Fall auch die einzelnen Verzweigungen? Ich würde den gesamten Aufbau der Schrittkette gerne als "View" in einer übergeordneten Software abbilden lassen, da sich die Ablaufsteuerungen, je nach Projekt im Aufbau unterscheiden bräuchte ich die Kenntniss über den Aufbau dieser Schrittketten. Oder müsste ich mir hier einen "Workaround" programmieren, der z.B. bei Init erstmal den Aufbau der Ablaufsteuerung durchläuft und mir die nötigen Informationen liefert? Natürlich wäre auch ein Weg den Aufbau des AS-Bausteins über die PLCopen XML zu exportieren, jedoch müsste dies bei Änderungen jeweils nachgezogen werden - was etwas unschön wäre, falls dies vergessen würde. Mittlerweile habe ich auch das Tool "SFC Visu Generator" gefunden, dessen Funktion im Prinzip genau das darstellt, was ich benötige - jedoch leider nur als CODESYS interne Visualisierung. Ich würde den Export des Bausteins gerne in meine übergeordnete Software implementieren. Gibt es hier die Möglichkeit das Vorgehen zu Erfahren oder den vom Baustein generierten Export bei mir zu implementieren? Hat hier jemand sowas ähnliches schonmal gelöst? Vielen Dank im Voraus Mit freundlichen Grüßen Biiebs
Last updated: 2024-07-25

Post by etienneneu on Trend x-axis description incorrect display CODESYS Forge talk (Post)
Hello everyone, maybe someone can help me with the following problem. I wanted to insert a trend element in my visualization. The problem is that I have set fixed fonts with a scaling of 1.5 for the individual languages via the visualization manager. This setting means that I have this scaling in every element, which has been quite comfortable so far because I didn't have to set the individual properties in the text fields. But in the trend element, even if I select other font sizes or fonts in the element itself, this font is also overwritten and I get a label on the x-axis that is no longer displayed correctly. Is there a way to prevent the overwriting of the font properties in this element or similar behavior? I mean, I could change the font size of each element manually, but the Visu app is a bit larger and it would be easier to have another option. Best regards Etienne
Last updated: 2024-11-28

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 mubeta on Some 'pathetic' errors in SoftMotion program CODESYS Forge talk (Post)
Thank you for your interest. Your answers are in line with what I knew, so at least it comforts me that I did not misinterpret the situation. However, I don't have an exact match as, for this project over the past few days I have: 1) I have gone back to leaving the various FBs of the motion always called, all of them, and in the state machine I use a boolean to activate the various useful Execute. (But in the future I want to go back and try the programming technique with which I wanted to develop this project); 2) For the occasional error: SMC_FB_WASNT_CALLED_DURING_MOTION perhaps it was due to the fact that I had set the Ethercat bus synchronism only at the CAN master level, but not at the level of individual drives. I have now also activated it for the individual drives and it does indeed seem to have been resolved, but having also adopted the programming technique mentioned in point 1), I cannot say whether this was the solution to the problem, or instead the previous point. Is there an error ‘regulator or start not set’ in the device log before the error ‘motion generating FB wasn't called for at least one cycle’? I can't answer that right now. By now the machine is running and I am no longer there, at this one. Also, I seem to remember that the 'fbeFBerror' drive structure (5-element array), does not cycle, BUT ONCE THE 5 EVENTS AFTER SWITCHING ON, IT DOES NOT UPDATE ANYMORE (but that's another issue), so diagnostics were not easy.
Last updated: 2024-07-24

Post by bbm1995 on Camera RTSP Feed CODESYS Forge talk (Post)
Hi dgrard, I had the same issue for a long time, but on a WAGO webvisu. Now I'm glad that I can share my solution. I don't know if you are trying to use the webvisu or the target visu, but this works on webvisu: Get "go2rtc" and set it up according to the documentation. I'm running the Windows binary. Here's my example of the go2rtc.yaml config file (contains working example streams): api: listen: ":1984" # default ":1984", HTTP API port ("" - disabled) origin: "*" # default "", allow CORS requests (only * supported) static_dir: "www" # default "", folder for static files (custom web interface) tls_listen: ":443" # default "", enable HTTPS server tls_cert: "./SSL/fullchain.pem" tls_key: "./SSL/privatekey.pem" streams: # Streams with multiple links will fall back on the next link. ABUS TVIP48511: - rtsp://<username>:<password>@<hostname>:<port>/ch1/main - rtsp://<username>:<password>@<hostname>:<port>/ch1/sub # Diagnostic connections Kirchhoff Institute for Physics - Germany: http://pendelcam.kip.uni-heidelberg.de/mjpg/video.mjpg Blanton Bottling, Kentucky - USA: http://camera.buffalotrace.com/mjpg/video.mjpg Tokyo - Japan: http://61.211.241.239/nphMotionJpeg?Resolution=320x240&Quality=Standard Tampere Hacklab - Finland: http://tamperehacklab.tunk.org:38001/nphMotionJpeg?Resolution=640x480&Quality=Clarity Soltorget Pajala - Sweden: http://195.196.36.242/mjpg/video.mjpg Kaiskuru Skistadion - Norway: http://77.222.181.11:8080/mjpg/video.mjpg webrtc: listen: ":8555" #ice_servers: # - urls: [ "stun:localhost:3478" ] # username: "" # credential: "" Access the webinterface of go2rtc and get the link of your stream. Use the link as for your browser frame in the visualization. Depending on your device, you need to be able to access the file /etc/lighttpd/lighttpd.conf or /etc/lighttpd/webvisu.conf and change the contents similar to this one, otherwise you'll get CORS and CSP errors in the browser and you won't be able to view the stream on the webvisu: # Webvisu specific settings $SERVER["socket"] =~ port_webvisu_used_any { url.redirect += ( "^/webvisu/?$" => "/webvisu/webvisu.htm" ) $HTTP["url"] =~ "^/webvisu/?" { var.response_header_policy_webvisu = ( # CSP for WebVisu, allowing inline sources. "Content-Security-Policy" => "default-src 'self' 'unsafe-inline'; media-src *; frame-src *", # CORS for WebVisu, allowing any origin to access. "Access-Control-Allow-Origin" => "*", # Tell older browsers that this page can only be displayed if all ancestor # frames are same origin to the page itself. "X-Frame-Options" => "SAMEORIGIN" ) # Response header policy for WebVisu setenv.set-response-header = var.response_header_policy_webvisu setenv.set-response-header += var.response_header_policy_common }
Last updated: 2023-11-14

Post by scoob on ModbusFB - Slow Response Time CODESYS Forge talk (Post)
Hello, I have been trying to use the ModbusFB functions so I can put some code into libraries, but it seems to be very slow for me. I have a Modbus device with 100ms registers. I previously setup 10 channels in the 'traditional' Modbus Slave with channels and mappings - and set a cyclic trigger at 100ms - this worked fine. I then tried the ModbusFB example, and setup reading the same 10 blocks of modbus addresses, copying the example and putting all of the requests into an array and triggering the requests sequentially. I timed how long the requests are taking to get round to each one, and it is around 1s 450ms. How do I speed this up to match the cyclic time? IF NOT(init) THEN init := TRUE; // Set the required IP address: ipAddress[0] := 192; ipAddress[1] := 168; ipAddress[2] := 1; ipAddress[3] := 10; // Pass the required IP address to the clinet FB: client_NetworkSwitch.aIPaddr := ipAddress; client_NetworkSwitch.udiLogOptions := (ModbusFB.LoggingOptions.ClientConnectDisconnect OR ModbusFB.LoggingOptions.ClientReceivedValidReplies); // Try to connect the client client_NetworkSwitch(xConnect:=TRUE); // Configure all the channels to read connecting them to the client: portStatus_Request(rClient := client_NetworkSwitch, uiStartItem := 4096, uiQuantity := 32, pData := ADR(portStatus), udiReplyTimeout := udiReplyTimeout); portSpeed_Request(rClient := client_NetworkSwitch, uiStartItem := 4352, uiQuantity := 32, pData := ADR(portSpeed)); flowControl_Request(rClient := client_NetworkSwitch, uiStartItem := 4608, uiQuantity := 32, pData := ADR(flowControl)); linkUpCounter_Request(rClient := client_NetworkSwitch, uiStartItem := 5888, uiQuantity := 32, pData := ADR(linkUpCounter)); txPacketCounter1_Request(rClient := client_NetworkSwitch, uiStartItem := 8192, uiQuantity := 100, pData := ADR(txPacketCounter1)); txPacketCounter2_Request(rClient := client_NetworkSwitch, uiStartItem := 8292, uiQuantity := 28, pData := ADR(txPacketCounter2)); rxPacketCounter1_Request(rClient := client_NetworkSwitch, uiStartItem := 8448, uiQuantity := 100, pData := ADR(rxPacketCounter1)); rxPacketCounter2_Request(rClient := client_NetworkSwitch, uiStartItem := 8548, uiQuantity := 28, pData := ADR(rxPacketCounter2)); txErrors_Request(rClient := client_NetworkSwitch, uiStartItem := 8704, uiQuantity := 64, pData := ADR(txErrors)); rxErrors_Request(rClient := client_NetworkSwitch, uiStartItem := 8960, uiQuantity := 64, pData := ADR(rxErrors)); // Trigger all client requests initially FOR clientRequestsCnt := 0 TO (SIZEOF(clientRequests)/SIZEOF(clientRequests[0]))-1 DO pClientRequest := clientRequests[clientRequestsCnt]; pClientRequest^.xExecute := TRUE; END_FOR // Prepare sequential trigger / control of client requests. clientRequestsCnt := 0; pClientRequest := clientRequests[clientRequestsCnt]; END_IF // Call the client to do request processing: client_NetworkSwitch(); // Now we trigger client request sequentially ... IF NOT pClientRequest^.xExecute AND NOT pClientRequest^.xDone AND run AND client_NetworkSwitch.xConnected THEN pClientRequest^.xExecute := TRUE; END_IF // .. and check result/error IF pClientRequest^.xExecute AND run AND client_NetworkSwitch.xConnected THEN IF pClientRequest^.xDone THEN // Prepare next trigger of client request (a rising edge of xExecute) pClientRequest^.xExecute := FALSE; IF clientRequestsCnt < SIZEOF(clientRequests)/SIZEOF(clientRequests[0])-1 THEN // next client request clientRequestsCnt := clientRequestsCnt + 1; ELSE clientRequestsIterationCounter := clientRequestsIterationCounter + 1; clientRequestsCnt := 0; END_IF pClientRequest := clientRequests[clientRequestsCnt]; END_IF END_IF I did try a semi-coded way using the IoDrvModbusTCP library, and setting the slave com settings, then 10 commands and 10 requests, then using a TP on xDone as a pause, before triggering another request - this is time the delay is around 120ms - so the device is fine with the speed, just something I am doing wrong in the ModbusFB method I am sure.
Last updated: 2024-04-26

Post by mubeta on Some 'pathetic' errors in SoftMotion program CODESYS Forge talk (Post)
Hello everyone, I have a very simple program for the process, but it's driving me crazy and I can't see the problems I'm left with: Short topological description: Dual Core Berghof controller with softmotion runtime version 3.5.19.30; Two axes with servodrive on canopen bus, clocked distributed from master; Ethercat I/O node; 2 ms ethercat task, 2 ms canopen bus cycle time; I/O objects of the canopen master and canopen drives connected to the ethercat task cycle; Problem 1: Two separate programs each manage their own axis and drive, with separate state machines. A first axis moves primarily in velocity, except having to position itself absolutely at a predetermined point at the end of the job; the second axis, on the other hand, is a paper unwinder that changes, for each job cycle, from actions in absolute, relative, and cam displacement with the master axis. Well, the state machine of both axes was written in such a way as to call running the useful FB and change it on state change in this way: CASE i_stateMachine OF 0: o_Power(Enable := TRUE, bRegulatorOn := FALSE, bDriveStart := FALSE, Axis := o_PaperUnwinderAxis); o_MoveAbs(Execute := FALSE, Axis := o_PaperUnwinderAxis); o_MoveRel(Execute := FALSE, Axis := o_PaperUnwinderAxis); o_CamSelect(Execute := FALSE, Master := o_MachineAxis, Slave := o_PaperUnwinderAxis, CamTable := cam_PaperUnwinder); o_CamIn(Execute := FALSE, Master := MachineEncoder, Slave := o_PaperUnwinderAxis); o_CamOut(Execute := FALSE, Slave := o_PaperUnwinderAxis); o_SetPosition(Execute := FALSE, Axis := o_PaperUnwinderAxis); IF ... THEN i_StateMachine := 10; END_IF; 10: o_Power( Enable := TRUE, bRegulatorOn := TRUE, bDriveStart := TRUE, Axis := o_PaperUnwinderAxis ); IF o_Power.Status THEN i_StateMachine := 20; END_IF; 20: (* Avanzamento carta *) o_MoveAbs( Execute := TRUE, Position := o_Somewhere, Velocity := 25.0, Acceleration := 3666.7, Deceleration := 3666.7, Jerk := 48000.0, Direction := MC_DIRECTION.positive, Axis := o_PaperUnwinderAxis ); IF o_MoveAbs.Done THEN o_MoveAbs(Execute := FALSE, Axis := o_PaperUnwinderAxis); i_StateMachine := 30; END_IF 30: d_HomingPosition := ...; o_SetPosition( Execute := TRUE, Position := d_HomingPosition, Mode := FALSE, Axis := o_PaperUnwinderAxis ); (* ... *) IF o_SetPosition.Done = TRUE THEN o_SetPosition(Execute := FALSE, Axis := o_PaperUnwinderAxis ); o_LogServer.Append(sMessage := '...', lscClass := LOGSERVER_CLASS.ALWAYS, sdt := o_CommonsMgrData.systime.sdtLocal); i_StateMachine := 40; END_IF; 50: ... The code above is a sketchy example of what I wanted to write. But it gives me a spot problem: in some, the state change results in a drive error, which is unrecoverable except with a reinitialization via SM3_ReinitDrive(). Things are improved a little if in the program I always run the call of all softmotion blocks in this way: o_Power(Axis := o_PaperUnwinderAxis); o_Jog(Axis := o_PaperUnwinderAxis); o_Halt(Axis := o_PaperUnwinderAxis); o_MoveAbs(Axis := o_PaperUnwinderAxis); o_MoveRel(Axis := o_PaperUnwinderAxis); o_CamIn(Master := MachineEncoder, Slave := o_PaperUnwinderAxis); o_CamOut(Slave := o_PaperUnwinderAxis); If I don't execute all the calls of all the motion FBs used, when exchanging machine state often (but not always), the axis goes into error with event id THE_FB_WASNT_CALL... Done a little diagnostics it seems that the FBs return the bDone, before they are completely terminated. I tried doing the machine state exchange not with the bDone bit of the FBs, but with the 'standstill' state of the axis. It didn't seem to change anything. Problem 2: During the use SM3_ReinitDrive() I get the erro in the log: "NetID 0: SDO read error for object 16#607C..." Assuming that the device involved it's one of the two servodrive, (no others device are present in the network), I don't found any object 0x607C in the 'possible object list in/out' of the two drive, and I don't understand where this object can be listed. So any ideas and suggestions regarding these two issues will be very, very welcome. If you need the source project, I am willing to send it.
Last updated: 2024-07-17

Post by kevinrn on CODESYS Development System V3 installation auf unter Parallells Windows 11auf MAC PRO M1 ARM Prozessor CODESYS Forge talk (Post)
Hallo, das Thema ist ja etwas offtopic. Aber ich kann gerne mal von meiner Erfahrung berichten: Nachdem ich von 2020 bis 2023 immer einen MacBook Pro mit Intel CPU hatte (i9/32GB) und nun seit Januar 2024 mit dem M3 Max unterwegs bin kann ich Nachfolgendes berichten. Infos zu den Aufgaben, die ich damit erledige: Die Runtime nutze ich nicht auf dem Mac (Wenn ich von Mac rede, dann meine ich damit die Win11 ARM64 Parallels Umgebung) Ich nutze die IDE für Library development und für automatisierungs Tests von CI/CD jobs. Weiterhin öffne ich oft große Projektarchive mit teilweise 160 MB. Erfahrungen zur Installation von CODESYS Versionen: Ich habe einige Versionen installiert, unter anderem, 3.5.14.4, 3.5.17.2, 3.5.16.3, 3.5.18.4 und 3.5.19.6. Ich hatte mit keiner einizgen Installation ein Problem. Die Installation lief immer ohne Probleme durch. Runtimes (Control Win) installiere ich nicht. Ich nutze linux basierte Zielsysteme und bei bedarf eine Windows VM auf einen entfernen Host mit X64. Lokales Gateway läuft ebenso Sonstige Erfahrungen: Ich nutze viele Komponenten Querbeet: Alarming, AC Persistence, Symbol Konfiguration, CFC und ST Editor, externes Packages wie STWeep, Git für Library Entwicklung, Visu, etc. Mit keiner dieser "Komponenten" hatte ich schwierigkeiten oder einen Unterschied zu x64 systemen festgestellt. Man muss aber auch sagen, dass das alles nur ein kleiner Bruchteil ist, was die CODESYS Welt beinhaltet, deshalb sind diese Aussagen auch nur subjektiv aus meinem Erfahrungsbereich. Für das Entwickeln von Libraries sehe ich keine Performance Einschränkungen. Ganz im Gegenteil, für das, dass hier eine emulation stattfindet, ist es erstaunlich schnell. Meiner Meinung nach sind sogar einfache und kleine Projekte schneller als beim Intel Mac. Die Akku Leistung mit dem Mac und Parallels ist fantastisch. Lüfter hört man nicht mal bei der Nutzung von CODESYS. Beim Intel konnte ich sonst ein Spiegelei auf der Abdeckung zubereiten... Was evtl. etwas langsamer ist bzw. mir manchmal so vor kommt ist, der CFC Editor im Online Mode. Aber hierzu fehlt mir ein richtiger Vergleich. Fazit: Ich bin selbst erstaunt wie gut die CODESYS IDE auf einem ARM64 emuliert wird. Ich muss aber auch sagen, dass ich jederzeit eine x64 Workspace zur Verfügung habe, falls was nicht funktionieren sollte. Das habe ich mir extra zum Umstieg zu gelegt. Bisher habe ich es jedoch noch nie benötigt, da meine Anforderungen alle erfüllt werden. Es sollte einem aber bewusst sein, dass dies keine supportete Umgebung ist und man auch bei spezifischen Problemen keinen Support erwarten sollte. Ich nutze CODESYS ca. 4-12 Stunden die Woche und ich warte immer noch auf etwas, um meine X64 Cloud Workspace mal zu verwenden... Vielleicht hilft dir dies ja etwas bei der Entscheidung.
Last updated: 2024-03-21

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

<< < 1 .. 25 26 27 (Page 27 of 27)

Showing results of 669

Sort by relevance or date