Post by r-c-r on SM3RaspiStepper 0.0.0.6 issue
CODESYS Forge
talk
(Post)
Ok, so i made some tests in the meantime and i have some conclusions. It apears that the enable bit is activated only when a motion function is executed. I implemented a very simple program with MC_Power and MC_Jog. If i enable everything on MC_Power, the enable GPIO pin stays off. However, as soon as the MC_Jog function is used the enable GPIO pin turns ON and remains ON. In version 0.0.0.4 this is not happening. The GPIO enable pin turns on or off when the MC_Power is enabled or disabled. From this behaviour i understand that in version 0.0.0.6 the GPIO enable bit is activated together with pulse and dir pins when motion starts. When motion stops, enable bit remains with the last state (on in this case) and you cannot turn it off for example. For me this bit is useful because i can turn on and off the stepper drive with MC_Power function. Now i can turn it on, but never off.
Last updated: 2025-04-04
Post by pernockham on Engineering IDE from linux?
CODESYS Forge
talk
(Post)
I have done the switch (linux mint, virtual windows through QEMU/KVM) now and is generally pleased. Have had problems in two areas initially. To bridge IP to the Virtual unit (solved), I overthought things initially. Solution. Configure manually a bridge in the mint-"network connections". Use that bridge in the Qemu settings as "Bridge device", "Device name": "name of the configured bridge" Figure out where to store the projects. I started out have the data in linux world (sort of) and linking it the windows with "virtio-fs". That had some serious impact though on git-handling. It seems that virtio-fs interpreted any file-path as lowercase only even if there were uppercase, resulting in git not able to sync files between its repository and the source code (it created a new file-path for me with only lowercase). Then I switch to samba-share instead and this works much better, though (git-actions) is a part that still has low performance with lots of waiting for file-actions. What should be the best way of handling the source/git? Edit to answer myself: Save the project "locally" in windows, then a lot of slow performance is avoided. Then a git-remote sync for backup.
Last updated: 2025-05-08
Post by mondinmr on Unexpected behavior in cyclic encoder read method during INT overflow (wrap-around)
CODESYS Forge
talk
(Post)
Hi everyone, Iâm investigating a potential issue with a cyclic method we use for reading incremental encoders in our libraries. Iâve come across two implementations that, at first glance, appear to perform the same operation: motionUnit.vlPositionActualValue is UINT due strange encoder type. Version A METHOD PROTECTED cyclicReadField VAR_INST actPosFieldOld: INT; rI: INT; delta: INT; END_VAR rI := TO_INT(motionUnit.vlPositionActualValue); delta := rI - actPosFieldOld; m_actPosRaw := m_actPosRaw + TO_LREAL(delta); actPosFieldOld := rI; IF settings.velocityFeebackMapped THEN m_actVelRaw := TO_LREAL(motionUnit.velocityActualValue); END_IF Version B METHOD PROTECTED cyclicReadField VAR_INST actPosFieldOld: INT; END_VAR m_actPosRaw := m_actPosRaw + TO_LREAL(TO_INT(motionUnit.vlPositionActualValue) - actPosFieldOld); actPosFieldOld := TO_INT(motionUnit.vlPositionActualValue); IF settings.velocityFeebackMapped THEN m_actVelRaw := TO_LREAL(motionUnit.velocityActualValue); END_IF Both use INT and the same delta logic, so they seem equivalent. However, when an overflow (wrap-around) occurs, version A continues correctly as expected, while version B unexpectedly resets to -32768 without a clear reason. Has anyone experienced similar behavior or can shed light on what might be happening here? It almost seems as if the cast to LREAL is being applied before the calculation â but that would be illogical and potentially very dangerous in many situations! Thanks!
Last updated: 2025-05-13
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 shaunvdm on Canbus Slave SDO Read from Object
CODESYS Forge
talk
(Post)
Busy testing a solution to use Canbus Slave to replace a physical device and convert to Ethercat device but keep the Canbus Master in place. Master needs to Read SDO object 5FA2. In the Master PLC if i send the SDO with 8 bytes in message IE: 60B 40 A2 5F 00 00 00 00 00 i get my expected 58B 43 A2 5F 00 00 68 36 02 containing data back. Problem is if we issue a 4 byte command can send 60B 40 A2 5F. Surely the canbus slave should respond with a 58B 43 A2 5F 00 00 68 36 02 but it comes back as 80 A2 5F 00 00 00 00 08 - meaning this OBJECT does not exist. Is there a setting in the canbus slave driver for Canbus to allow the 4 byte command to read the SDO OBJECTS ?
Last updated: 2025-05-27
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 hwillems on Ranges, Lambdas, on Fixed arrays of structs
CODESYS Forge
talk
(Post)
I do datastructures and algorithms in Codesys. For example a Struct of Person with thing's like IdNumber, Name, Age etc. as example. Now i do all kind of calculations, filters. So i have this pretty big Fixed Array with Structs. On this struct i want to do simple stuff you can do easily in C++/Python/Rust etc. For example i want to do this: AvererageAge := Average(Peoples.Age); Then it will return the average of all members ages. Or Sort struct on age etc. Or sort on alphabetical Name. Or use Lambda functions to filter/mutate out things like, filter out everybody above 18 years old. Or remove people who it's name start with "A". Currently i have to write my own custom function for example sorting on Age. And make a super specific function based on that particulare datastructure. Here an Example: (*Before calling this FIlter method, set the mNodeFilterSwitch to the desired filter.*) CASE mNodeFilterSelect OF (********************************[ Status Filters ]***********************************) NodeID: FOR x := ACS_OUT_BEGIN TO ACS_OUT_END BY 1 DO FOR y := ACS_IN_BEGIN TO ACS_IN_END BY 1 DO IF marrNode[y].Status.oiNodeID > marrNode[y + 1].Status.oiNodeID THEN mNodeTemp := marrNode[y + 1]; marrNode[y + 1] := marrNode[y]; marrNode[y] := mNodeTemp; END_IF; END_FOR; END_FOR; Started: FOR x := DES_OUT_BEGIN TO DES_OUT_END BY -1 DO FOR y := DES_IN_BEGIN TO DES_IN_END BY -1 DO IF marrNode[y].Status.oxStarted > marrNode[y - 1].Status.oxStarted THEN mNodeTemp := marrNode[y - 1]; marrNode[y - 1] := marrNode[y]; marrNode[y] := mNodeTemp; END_IF; END_FOR; END_FOR; Starting: FOR x := DES_OUT_BEGIN TO DES_OUT_END BY -1 DO FOR y := DES_IN_BEGIN TO DES_IN_END BY -1 DO IF marrNode[y].Status.oxStarting > marrNode[y - 1].Status.oxStarting THEN mNodeTemp := marrNode[y - 1]; marrNode[y - 1] := marrNode[y]; marrNode[y] := mNodeTemp; END_IF; END_FOR; END_FOR; END_CASE; I have like 30+ of these in the enum. Not really DRY code right? These are custom made bubble sort filters in a function. You pass in the Datastructure, and say what function you want. (This is an enum collection of sorting functions) And then the Array with Nodes of Structs gets ordered. Why can't we have Iterators and Lambda's and build in standard functions like regular languages? Also i use bubble sort because it's the easiest to implement because i can't get this to code DRY. Problem with ST (Even the new one with classes) that it's very limited for programming datastructures and algorithms. Yes you still not want dynamic memory and you need to choose the correct algorithm so you know the most extreme edge cases regarding the time it takes to execute the algorithms.(Real-time execution) How are other people dealing with this? Here for example saw some software using an adjusted ST language and having FOR EACH possibility: https://www.fernhillsoftware.com/help/iec-61131/structured-text/st-for-each.html You can then build your own custom Iterator functions. I wish the IEC 61131-3 standard would be more expressive and having more standard modern features, but still keep close to the fact of no dynamics memory and real-time systems.
Last updated: 2023-08-31
Post by francesco86 on Script python for write in a file Project information
CODESYS Forge
talk
(Post)
Dear all, My python script can read a Codesys project and save in file the different POU, but the problem is that I don't able to read the project info from the obj list. Following of this message there is my python script. Can you help my? Best regards Francesco # encoding:utf-8 # We enable the new python 3 print syntax from __future__ import print_function import os import shutil import time import sys from datetime import datetime print("--- Saving files in the project: ---") print("sys.argv: ", len(sys.argv), " elements:") for arg in sys.argv: print(" - ", arg) if (len(sys.argv)>1): folderExportName = sys.argv[1] print(" folderExportName: ", folderExportName) exportPath = sys.argv[2]+ sys.argv[3]+ "\\"+ sys.argv[1] print(" File path: ", exportPath) # git has_repo=False #save_folder=r'E:\Tmp\ControlPlugins\ControlPlugins\Export' save_folder = exportPath if not os.path.exists(save_folder): os.makedirs(save_folder) else: a=os.listdir(save_folder) for f in a: if not f.startswith("."): sub_path= os.path.join(save_folder,f) if os.path.isdir(sub_path): shutil.rmtree(sub_path) else: os.remove(sub_path) elif f==".git": has_repo=True info={} type_dist={ '792f2eb6-721e-4e64-ba20-bc98351056db':'pm', #property method '2db5746d-d284-4425-9f7f-2663a34b0ebc':'dut', #dut 'adb5cb65-8e1d-4a00-b70a-375ea27582f3':'lib', #lib manager 'f89f7675-27f1-46b3-8abb-b7da8e774ffd':'m', #method no ret '8ac092e5-3128-4e26-9e7e-11016c6684f2':'act', #action '6f9dac99-8de1-4efc-8465-68ac443b7d08':'pou', #pou '6654496c-404d-479a-aad2-8551054e5f1e':'itf', #interface '738bea1e-99bb-4f04-90bb-a7a567e74e3a':'', #folder 'ffbfa93a-b94d-45fc-a329-229860183b1d':'gvl', #global var '5a3b8626-d3e9-4f37-98b5-66420063d91e':'prop', #property '2bef0454-1bd3-412a-ac2c-af0f31dbc40f':'tl', #textlist '63784cbb-9ba0-45e6-9d69-babf3f040511':'gtl', #global textlist '225bfe47-7336-4dbc-9419-4105a7c831fa':'dev', #device 'ae1de277-a207-4a28-9efb-456c06bd52f3':'tc', #task configuration 'f8a58466-d7f6-439f-bbb8-d4600e41d099':'m', #method with ret '261bd6e6-249c-4232-bb6f-84c2fbeef430':'gvl', #gvl_Persistent '98a2708a-9b18-4f31-82ed-a1465b24fa2d':'task', #task '085afe48-c5d8-4ea5-ab0d-b35701fa6009':'progInfo'#project information }; def save(text,path,name,tp): if not tp: tp='' else: tp='.'+tp+'.txt' with open(os.path.join(path,name+tp),'w') as f: f.write(text.encode('utf-8')) def print_tree(treeobj, depth, path): global info #record current Path curpath=path isfolder=False t='' #text tp='' #type # get object name name = treeobj.get_name(False) id = treeobj.type.ToString() if id in type_dist: tp = type_dist[treeobj.type.ToString()] #Print all type of objects #print("--Name: ", tp) else: info[id]=name if treeobj.is_device: deviceid = treeobj.get_device_identification() t = 'type='+str(deviceid.type) +'\nid=' +str(deviceid.id) + '\nver='+ str(deviceid.version) if tp == "progInfo": print("-- There is prog info, ", tp) print("-- It has textual declaration: , ", treeobj.has_textual_declaration) print("-- It has textual implementation: , ", treeobj.has_textual_implementation) print("-- It is folder: , ", treeobj.is_folder) print("-- It is children: , ", treeobj.get_children(False)) print("-- It is children len: , ", len(treeobj.get_children(False))) print("-- It is progInfo type: , ", type(treeobj.ScriptProject)) #for child in treeobj.get_children(False): # print_tree(child, depth+1,curpath) try: if treeobj.is_folder : #system.ui.prompt('folder:'+u, PromptChoice.YesNo, PromptResult.Yes) isfolder=true pass except: pass if treeobj.has_textual_declaration : t=t+'(*#-#-#-#-#-#-#-#-#-#---Declaration---#-#-#-#-#-#-#-#-#-#-#-#-#*)\r\n' a=treeobj.textual_declaration t=t+a.text if treeobj.has_textual_implementation: t=t+'(*#-#-#-#-#-#-#-#-#-#---Implementation---#-#-#-#-#-#-#-#-#-#-#-#-#*)\r\n' a=treeobj.textual_implementation t=t+a.text if treeobj.has_textual_declaration and not treeobj.has_textual_implementation: t=t+'(*#-#-#-#-#-#-#-#-#-#---NOT Implementation visible---#-#-#-#-#-#-#-#-#-#-#-#-#*)\r\n' if treeobj.is_task : exports=[treeobj] projects.primary.export_native(exports,os.path.join(curpath,name+'.task')) if treeobj.is_libman: exports=[treeobj] projects.primary.export_native(exports,os.path.join(curpath,name+'.lib')) if treeobj.is_textlist: treeobj.export(os.path.join(curpath,name+'.tl')) children = treeobj.get_children(False) if children or isfolder: if tp: curpath=os.path.join(curpath,name+'.'+tp) else: curpath=os.path.join(curpath,name) if not os.path.exists(curpath): os.makedirs(curpath) if t: save(t,curpath,name,tp) for child in treeobj.get_children(False): print_tree(child, depth+1,curpath) for obj in projects.primary.get_children(): print_tree(obj,0,save_folder) with open(os.path.join(save_folder,'ExportInfo.txt'),'w') as f: now = datetime.now() infTimeExecution = now.strftime("%Y-%m-%d %H:%M:%S") f.write("Export date and time: "+infTimeExecution + "\r\n" + str(info)) print("--- Script finished. ---") #system.ui.info('save ok') projects.primary.close()
Last updated: 2024-04-30
Post by francesco86 on Script python for write in a file Project information
CODESYS Forge
talk
(Post)
Dear all, My python script can read a Codesys project and save in file the different POU, but the problem is that I don't able to read the project info from the obj list. Following of this message there is my python script. Can you help my? Best regards Francesco # encoding:utf-8 # We enable the new python 3 print syntax from __future__ import print_function import os import shutil import time import sys from datetime import datetime print("--- Saving files in the project: ---") print("sys.argv: ", len(sys.argv), " elements:") for arg in sys.argv: print(" - ", arg) if (len(sys.argv)>1): folderExportName = sys.argv[1] print(" folderExportName: ", folderExportName) exportPath = sys.argv[2]+ sys.argv[3]+ "\\"+ sys.argv[1] print(" File path: ", exportPath) # git has_repo=False #save_folder=r'E:\Tmp\ControlPlugins\ControlPlugins\Export' save_folder = exportPath if not os.path.exists(save_folder): os.makedirs(save_folder) else: a=os.listdir(save_folder) for f in a: if not f.startswith("."): sub_path= os.path.join(save_folder,f) if os.path.isdir(sub_path): shutil.rmtree(sub_path) else: os.remove(sub_path) elif f==".git": has_repo=True info={} type_dist={ '792f2eb6-721e-4e64-ba20-bc98351056db':'pm', #property method '2db5746d-d284-4425-9f7f-2663a34b0ebc':'dut', #dut 'adb5cb65-8e1d-4a00-b70a-375ea27582f3':'lib', #lib manager 'f89f7675-27f1-46b3-8abb-b7da8e774ffd':'m', #method no ret '8ac092e5-3128-4e26-9e7e-11016c6684f2':'act', #action '6f9dac99-8de1-4efc-8465-68ac443b7d08':'pou', #pou '6654496c-404d-479a-aad2-8551054e5f1e':'itf', #interface '738bea1e-99bb-4f04-90bb-a7a567e74e3a':'', #folder 'ffbfa93a-b94d-45fc-a329-229860183b1d':'gvl', #global var '5a3b8626-d3e9-4f37-98b5-66420063d91e':'prop', #property '2bef0454-1bd3-412a-ac2c-af0f31dbc40f':'tl', #textlist '63784cbb-9ba0-45e6-9d69-babf3f040511':'gtl', #global textlist '225bfe47-7336-4dbc-9419-4105a7c831fa':'dev', #device 'ae1de277-a207-4a28-9efb-456c06bd52f3':'tc', #task configuration 'f8a58466-d7f6-439f-bbb8-d4600e41d099':'m', #method with ret '261bd6e6-249c-4232-bb6f-84c2fbeef430':'gvl', #gvl_Persistent '98a2708a-9b18-4f31-82ed-a1465b24fa2d':'task', #task '085afe48-c5d8-4ea5-ab0d-b35701fa6009':'progInfo'#project information }; def save(text,path,name,tp): if not tp: tp='' else: tp='.'+tp+'.txt' with open(os.path.join(path,name+tp),'w') as f: f.write(text.encode('utf-8')) def print_tree(treeobj, depth, path): global info #record current Path curpath=path isfolder=False t='' #text tp='' #type # get object name name = treeobj.get_name(False) id = treeobj.type.ToString() if id in type_dist: tp = type_dist[treeobj.type.ToString()] #Print all type of objects #print("--Name: ", tp) else: info[id]=name if treeobj.is_device: deviceid = treeobj.get_device_identification() t = 'type='+str(deviceid.type) +'\nid=' +str(deviceid.id) + '\nver='+ str(deviceid.version) if tp == "progInfo": print("-- There is prog info, ", tp) print("-- It has textual declaration: , ", treeobj.has_textual_declaration) print("-- It has textual implementation: , ", treeobj.has_textual_implementation) print("-- It is folder: , ", treeobj.is_folder) print("-- It is children: , ", treeobj.get_children(False)) print("-- It is children len: , ", len(treeobj.get_children(False))) print("-- It is progInfo type: , ", type(treeobj.ScriptProject)) #for child in treeobj.get_children(False): # print_tree(child, depth+1,curpath) try: if treeobj.is_folder : #system.ui.prompt('folder:'+u, PromptChoice.YesNo, PromptResult.Yes) isfolder=true pass except: pass if treeobj.has_textual_declaration : t=t+'(*#-#-#-#-#-#-#-#-#-#---Declaration---#-#-#-#-#-#-#-#-#-#-#-#-#*)\r\n' a=treeobj.textual_declaration t=t+a.text if treeobj.has_textual_implementation: t=t+'(*#-#-#-#-#-#-#-#-#-#---Implementation---#-#-#-#-#-#-#-#-#-#-#-#-#*)\r\n' a=treeobj.textual_implementation t=t+a.text if treeobj.has_textual_declaration and not treeobj.has_textual_implementation: t=t+'(*#-#-#-#-#-#-#-#-#-#---NOT Implementation visible---#-#-#-#-#-#-#-#-#-#-#-#-#*)\r\n' if treeobj.is_task : exports=[treeobj] projects.primary.export_native(exports,os.path.join(curpath,name+'.task')) if treeobj.is_libman: exports=[treeobj] projects.primary.export_native(exports,os.path.join(curpath,name+'.lib')) if treeobj.is_textlist: treeobj.export(os.path.join(curpath,name+'.tl')) children = treeobj.get_children(False) if children or isfolder: if tp: curpath=os.path.join(curpath,name+'.'+tp) else: curpath=os.path.join(curpath,name) if not os.path.exists(curpath): os.makedirs(curpath) if t: save(t,curpath,name,tp) for child in treeobj.get_children(False): print_tree(child, depth+1,curpath) for obj in projects.primary.get_children(): print_tree(obj,0,save_folder) with open(os.path.join(save_folder,'ExportInfo.txt'),'w') as f: now = datetime.now() infTimeExecution = now.strftime("%Y-%m-%d %H:%M:%S") f.write("Export date and time: "+infTimeExecution + "\r\n" + str(info)) print("--- Script finished. ---") #system.ui.info('save ok') projects.primary.close()
Last updated: 2024-04-30
Post by mubeta on Strange problem with the âMC_SetPositionâ function
CODESYS Forge
talk
(Post)
How are the servo drives controlled? EtherCAT, step/dir pulses, other? CANOpen, 1 Mb/s, bus load 35%, cycle time 2ms. Another thought is that - if it's step/dir pulse based control - the pulses from the PLC to the drive are getting missed/lost at high frequencies? If that's the case then there would be multiple troubleshooting steps/corrections that could be investigated. Here, it seems to me that we are getting completely off track with the observed problem. You could try to create a simplified program I had already written this elsewhere. The program before being brought into machines was exhaustively tested in SW emulation and the problem did not occur. However, in emulation I was interested in checking other aspects of the process, not this specific one which is for real a correction made necessary after the fact. The part of the program that does this correction with the function mentioned in the topic, came up from its origins, but I didn't know or didn't think it was really useful. A scruple that later turned out to be necessary. However, for now I do not think I will spend any more time on this verification, already lacking any to do my normal. I remain amazed, however, that a function intended to correct the axis position with the motor in motion and that it should not interfere with this, in fact instead changes behavior as the motor speed changes. Mah! When you manually control the motor directly from the servo drive software at the speeds you are calling for, does it move precisely to the target position? The drive and motor have been working fine for about 10 years. In replacing the machine control system, I opted for CoDeSys where before there was something else. But this is not the subject of the problem. What I need to resolve is the fact that a clutch specially placed at a certain point can slip and, therefore, I have the undeniable need to phase the 'prime mover' to the mechanical position of the machine, detected by a cam for each turn, in order to properly stop at its optimum point. Which for now I have ruled out doing. In fact, if I really have to say, since we have now gone brutally OT, I originally thought that this clutch should only come into action in cases of extreme necessity, as happens in most trials. But this one, the way it is made, slips more easily than I could estimate and the servo-controlled 'prime mover,' and the machine, get out of phase, maybe by a little, but frequently, and when the machine work at it's high speed, (in fact all of the time), I can't adjust properly the 'prime mover' position at fly.
Last updated: 2025-01-18
Post by ryandmg on Web Client (HMI) Disconnects from Webvisu (Weidmuller u-OS)
CODESYS Forge
talk
(Post)
Hey Everyone, I'm having a bit of a struggle finding settings that will reliably maintain a connection between the webvisu and a touchscreen client. Every so often the HMI disconnects and will perpetually display the red spinning arrow with the "Error Happened, Will resume automatically" text. Power cycling the HMI to force a reconnect will re-establish comms. It seems to happen during periods of inactivity if that's a clue. From what I've gathered so far this seems to have something to do with the webvisu update rate, buffer size as well as the visu task scan rate. We first tried the default settings as follows: Webvisu Update Rate: 200 ms Webvisu Buffer Size: 50,000 Visu Task Scan Rate: 100 ms Priority 31 Other Tasks for Reference: Main Task Scan Rate: 100 ms Priority 1 Alarm Manager Scan Rate: 50 ms Priority 31 Ethercat Task: 4 ms Priority 1 This would disconnect some what regularly. We then made the following changes to try and stabilize: Webvisu Update Rate: 150 ms Webvisu Buffer Size: 75,000 Visu Task Scan Rate: 75 ms Kept other tasks the same. This seems to disconnect even more frequently. Also for reference the network is very small and only consists of the PLC, a small switch and the HMI. We're also not controlling frames from outside the visu program itself. The frame changes are all done natively. Any suggestions to get this to stop disconnecting? Oh and whatever the issue is the log does not record it. Figured I would ask here before opening a ticket. Thanks in advance for your help!
Last updated: 2023-09-06
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 mondinmr on Why SysPipeWindows is not implemented in RTE?
CODESYS Forge
talk
(Post)
This library would be very useful for IPC communications. Using a UDP socket on localhost is unpredictable, as with slightly loaded machines it does not even guarantee packet delivery locally. Using TCP creates a lot of overhead. Message named pipes would be an excellent solution for Windows RTE. On Linux, since the release of the extension package, there is no issue, as it is sufficient to develop a component. However, although now 90% of our clients understand that Linux runtimes are better in every way compared to Windows RTE, especially from the security aspect (Not in kernel space) and the issues with Windows updates, 10% stubbornly insist (sometimes for trivial commercial reasons) on using Windows. Managing IPC with circular buffers in shared memory is quite ugly, or rather really ugly and unaesthetic. In the manuals, I saw the SysPipeWindows libraries, so I decided to test them, but unfortunately, I noticed that they are not implemented for RTE devices. Technically, I could try to open them as regular files, but SysFileOpen returns 16#27 or 16#39 depending on how I set the name (direction of the slashes). Here is the code to create shared memory and named pipes. Shared memory work great, named pipes no! #ifdef Q_OS_WIN32 SECURITY_ATTRIBUTES sa; SECURITY_DESCRIPTOR sd; InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = &sd; sa.bInheritHandle = FALSE; const wchar_t* name = L"Global\\ShmTest"; HANDLE hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(SharedData), name); if (hMapFile == NULL) { qCritical("Error creating shared memory"); return 1; } data = static_cast<SharedData*>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(SharedData))); if (data == NULL) { qCritical("Error mapping shared memory"); return 1; } HANDLE hPipe = CreateNamedPipe( TEXT("\\\\.\\pipe\\MyPipe"), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 1024 * 1024, 1024 * 1024, NMPWAIT_USE_DEFAULT_WAIT, &sa); if (hPipe == INVALID_HANDLE_VALUE) { qCritical("Error creating named pipe"); return -1; } if (!ConnectNamedPipe(hPipe, NULL)) { qCritical("Error connecting to named pipe"); return -1; } checkPipe(hPipe); #endif
Last updated: 2024-02-02
Post by thysonfury on OPTO22 Groov Epic PR2 Modbus Comms Dropping out every 2 hours and 4 Mins
CODESYS Forge
talk
(Post)
Hi after some assistance with an error on a Groov PR2 PLC. We have a few different communications set up as shown below: One Modbus TCP Slave Connection - ( Sending / Receiving Data from a PC ) Two Modbus TCP Master Connection - ( Reading Data from a UPS Panel and Reading Data Gas Chromatograph) One Modbus RTU Slave Connection 485 - (Reading Data from a fire and gas panel) One Modbus RTU Master Connection 485 - (Sending Data to a Telemetry Unit) All Licenses have been installed as per OPTO22 suggestions of the order below: Modbus TCP Master Modbus TCP Slave Modbus RTU Master Modbus RTU Slave When I check on License manager the RTU Master license seems to disappear on installing the RTU. (What ever reason Iâve been told this is ânormalâ). If I use Device License Read It will successfully read all the licenses correctly. Now the issue is every 2 hours and between 4. For what ever reason the communications seems to end and lock up for about 20 seconds. During this time even if I was logged into the PLC it would kick me off and Iâd have to re type the password to enter. Most of the devices can handle this however the RTU flags up a communications failure at the SCADA and is raising alarms every 2 hours and 4 mins. Weâve had multiple people go through the code to check for anything obvious. Does anyone have any ideas?
Last updated: 2024-04-15
Post by thysonfury on OPTO22 Groov Epic PR2 Modbus Comms Dropping out every 2 hours and 4 Mins
CODESYS Forge
talk
(Post)
Hi after some assistance with an error on a Groov PR2 PLC. We have a few different communications set up as shown below: One Modbus TCP Slave Connection - ( Sending / Receiving Data from a PC ) Two Modbus TCP Master Connection - ( Reading Data from a UPS Panel and Reading Data Gas Chromatograph) One Modbus RTU Slave Connection 485 - (Reading Data from a fire and gas panel) One Modbus RTU Master Connection 485 - (Sending Data to a Telemetry Unit) All Licenses have been installed as per OPTO22 suggestions of the order below: Modbus TCP Master Modbus TCP Slave Modbus RTU Master Modbus RTU Slave When I check on License manager the RTU Master license seems to disappear on installing the RTU. (What ever reason Iâve been told this is ânormalâ). If I use Device License Read It will successfully read all the licenses correctly. Now the issue is every 2 hours and between 4. For what ever reason the communications seems to end and lock up for about 20 seconds. During this time even if I was logged into the PLC it would kick me off and Iâd have to re type the password to enter. Most of the devices can handle this however the RTU flags up a communications failure at the SCADA and is raising alarms every 2 hours and 4 mins. Weâve had multiple people go through the code to check for anything obvious. Does anyone have any ideas?
Last updated: 2024-04-15
Post by thysonfury on OPTO22 Groov Epic PR2 Modbus Comms Dropping out every 2 hours and 4 Mins
CODESYS Forge
talk
(Post)
Hi after some assistance with an error on a Groov PR2 PLC. We have a few different communications set up as shown below: One Modbus TCP Slave Connection - ( Sending / Receiving Data from a PC ) Two Modbus TCP Master Connection - ( Reading Data from a UPS Panel and Reading Data Gas Chromatograph) One Modbus RTU Slave Connection 485 - (Reading Data from a fire and gas panel) One Modbus RTU Master Connection 485 - (Sending Data to a Telemetry Unit) All Licenses have been installed as per OPTO22 suggestions of the order below: Modbus TCP Master Modbus TCP Slave Modbus RTU Master Modbus RTU Slave When I check on License manager the RTU Master license seems to disappear on installing the RTU. (What ever reason Iâve been told this is ânormalâ). If I use Device License Read It will successfully read all the licenses correctly. Now the issue is every 2 hours and between 4. For what ever reason the communications seems to end and lock up for about 20 seconds. During this time even if I was logged into the PLC it would kick me off and Iâd have to re type the password to enter. Most of the devices can handle this however the RTU flags up a communications failure at the SCADA and is raising alarms every 2 hours and 4 mins. Weâve had multiple people go through the code to check for anything obvious. Does anyone have any ideas?
Last updated: 2024-04-15
Post by wildcard on Modbus Client Request Not Processed
CODESYS Forge
talk
(Post)
Hi, does anyone has a solution for this issue. I've the same problem. I've implemented a very simple client based on the Modbus Examples and connected the soft PLC to a Modbus Simulator. PROGRAM ModbusClient VAR initDone : BOOL := FALSE; errorID : ModbusFB.Error; client : ModbusFB.ClientTCP; timeout : UDINT := 500000; replyTimeout : UDINT := 200000; aUINT : ARRAY [0..8] OF UINT; clientRequestReadHoldingRegisters : ModbusFB.ClientRequestReadHoldingRegisters; clientRequestsCnt : UINT := 0; clientRequestsProcessCnt : UINT := 0; ipAddress : ARRAY[0..3] OF BYTE := [10,54,0,72]; END_VAR IF NOT initDone THEN initDone := TRUE; client(aIPaddr:=ipAddress, udiLogOptions:=ModbusFB.LoggingOptions.All); client(xConnect:=TRUE, ); clientRequestReadHoldingRegisters(rClient:=client, udiTimeOut:=timeout, uiUnitId:=1, uiStartItem:=0, uiQuantity:=4, pData:=ADR(aUINT[0]), udiReplyTimeout:=replyTimeout); clientRequestReadHoldingRegisters.xExecute := TRUE; clientRequestsCnt := 0; END_IF clientRequestReadHoldingRegisters(rClient:=client, udiTimeOut:=timeout, uiUnitId:=1, uiStartItem:=0, uiQuantity:=4, pData:=ADR(aUINT[0]), udiReplyTimeout:=replyTimeout, xExecute := TRUE); IF clientRequestReadHoldingRegisters.xError THEN clientRequestsCnt := clientRequestsCnt +1 ; errorID := clientRequestReadHoldingRegisters.eErrorID; END_IF clientRequestReadHoldingRegisters(rClient:=client, udiTimeOut:=timeout, uiUnitId:=1, uiStartItem:=0, uiQuantity:=4, pData:=ADR(aUINT[0]), udiReplyTimeout:=replyTimeout, xExecute := NOT clientRequestReadHoldingRegisters.xExecute); When the system is running I do get the following on the logs: 2024-05-13T10:18:07.443Z: Cmp=MODBUS lib, Class=1, Error=0, Info=0, pszInfo= Client.RequestProcessed ClientRequest,16#0164ADC561A0 unitId=1 fc=ReadHoldingRegisters id=2070 state=Error 2024-05-13T10:18:07.443Z: Cmp=MODBUS lib, Class=1, Error=0, Info=0, pszInfo= ClientRequest,16#0164ADC561A0 unitId=1 fc=ReadHoldingRegisters id=2070 change state Error -> None timestamp=63843421226 2024-05-13T10:18:08.444Z: Cmp=MODBUS lib, Class=1, Error=0, Info=0, pszInfo= ClientRequest,16#0164ADC561A0 unitId=1 fc=ReadHoldingRegisters id=2071 change state None -> Init timestamp=63844421420 2024-05-13T10:18:09.444Z: Cmp=MODBUS lib, Class=1, Error=0, Info=0, pszInfo= ClientRequest,16#0164ADC561A0 unitId=1 fc=ReadHoldingRegisters id=2071 change state Init -> Error timestamp=63845421675 But the errorID is jumping between OK and RequestNotProcessed. Any help is very appreciated which gives me a hint what I'm doing wrong. Thanks
Last updated: 2024-05-13
Post by youness on No source code available (cip object)
CODESYS Forge
talk
(Post)
Hi yotaro, hope your problem was resolved. I had the same, but with an other library title. This exception is not detected during compilation, but rather at a given position in the program (when switching to a given visualization). Although the exception is generated at this point, it does not involve the visualization in question. This error is due to one of 3 reasons: 1) A division by zero somewhere: The program is able to detect divisions by zero at compile time. But in the case of a variable, which takes a valid value at init and changes to 0 at a later stage. 2) An invalid pointer: (either because it has a value of 0, or because it points outside the memory reserved for the program) is being dereferenced. Locate any pointers or interfaces you have in the code and check them - you should also be wary of mixing inline modifications and pointers. 3) Array overflow: Generally when a processing operation is executed outside the array's definition range. Example: a write loop with n iterations is executed on an array of dimmension n-1. On the other hand, the error message may not appear. In the latter case, the error may have fatal consequences, as the overflow has induced writing to potentially forbidden memory areas. This problem can be explained by the fact that it's not always the adjacent memory areas of PLC_PRG that are overwritten, but the memory areas that are randomly allocated to the array during compilation. In this case, however, there is no entry in the log, so you need to integrate the "Implicit Check function", which checks the line of code generating the error. To integrate this functions, click on Application --> POU for implicit controls Regards,
Last updated: 2024-07-16
Post by 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 tk096 on Some 'pathetic' errors in SoftMotion program
CODESYS Forge
talk
(Post)
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). In general: - Motion function blocks have to be called until they report 'Done', 'Error', 'CommandAborted' or a subsequent motion FB with BufferMode=Aborting is started in the current cycle. - Setting the Execute input to FALSE will not abort any ongoing motion of the motion function block. 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. I think the error SMC_FB_WASNT_CALLED_DURING_MOTION is only a follow-up (and misleading) error that results from the axis not being in operational state anymore (bus problems). 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'? Which error does the respective function block (Halt.ErrorId) report?
Last updated: 2024-07-22
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 gorditron on I2C Communication with
CODESYS Forge
talk
(Post)
Hello, I have problems with the I2C communication to an ADS7828 AD converter. I don't get any value back from the chip. I use a Kontron chip (ARM 32SC) with Linux as the operating system. I also use the CmpCharDevice library. ADS7828 parameters Address: A1 = 0 / A0 = 0 = SD = 1 = Single End C2 = 0 / C1= 0 / C0= 0 / Channel 0 PD1 = Internal Reference and PD0 = AD Converter ON Here is my code: VAR b_i2cAdr : BYTE := 16#48; (* Standard I2C-Adresse des ADS7828 *) x_Init: BOOL;(* Flag fĂŒr die Initialisierung *) b_config_byte: BYTE;(* Konfigurationsbyte fĂŒr den ADS7828 *) ab_cmd_buffer : ARRAY [0..0] OF BYTE; (* Buffer fĂŒr den Befehl *) ab_data_buffer : ARRAY [0..1] OF BYTE; (* Buffer fĂŒr die empfangenen Daten *) ui_adc_value_1 : UINT; (* Ausgelesener ADC-Wert *) I2C_Handle: RTS_IEC_HANDLE; (* Handle fĂŒr das I2C-Device *) di_result_open: DINT;(* Ergebnis der Funktionsaufrufe *) di_result_adr: DINT;(* Ergebnis der Funktionsaufrufe *) di_result_wr_cmd: DINT;(* Ergebnis der Funktionsaufrufe *) di_result_rd_cmd: DINT;(* Ergebnis der Funktionsaufrufe *) di_result_close: DINT;(* Ergebnis der Funktionsaufrufe *) END_VAR //*** Init from the I2C communication port *** IF NOT x_Init THEN I2C_Handle := CDOpen(szFile:= '/dev/i2c-0', dFlags:= O_RDWR, pResult:= ADR(di_result_open)); //* I2C opening * //*** set of the I2C address *** CDIoctl(hFile:=I2C_Handle , dRequest:=1795 , dParameter:=b_i2cAdr , pResult:=ADR(di_result_adr) ); x_Init := TRUE; END_IF (* Hauptlogik *) IF I2C_Handle <> 0 THEN (* Konfigurationsbyte setzen: Single-Ended Kanal 0, interne Referenz *) b_config_byte := 16#8C; (* 10001100b: AIN0, interne Referenz, Single-Ended *) ab_cmd_buffer[0] := b_config_byte; (* Schreiboperation zum Konfigurieren des Chips *) CDWrite(hFile:= I2C_Handle, pbyBuffer:= ADR(ab_cmd_buffer), udCount:= SIZEOF(ab_cmd_buffer), pResult:= ADR(di_result_wr_cmd)); IF di_result_wr_cmd = 0 THEN (* Leseoperation, um den ADC-Wert zu erhalten *) CDRead(hFile:= I2C_Handle, pbyBuffer:= ADR(ab_data_buffer), udCount:= SIZEOF(ab_data_buffer), pResult:= ADR(di_result_rd_cmd)); IF di_result_rd_cmd = 0 THEN (* ADC-Wert aus den Daten extrahieren *) ui_adc_value_1 := SHL(TO_UINT(ab_data_buffer[0]), 8) OR TO_UINT(ab_data_buffer[1]); ELSE (* Fehler beim Lesen der Daten *) ui_adc_value_1 := 0; (* ADC-Wert auf 0 setzen *) END_IF ELSE (* Fehler beim Schreiben der Konfiguration *) ui_adc_value_1 := 0; END_IF END_IF
Last updated: 2024-12-13
Post by timo on String nach erlaubten/unerlaubten Zeichen durchsuchen
CODESYS Forge
talk
(Post)
Hallo, Ich bastele gerade an einer möglichst einfachen Möglichkeit mit der ich prĂŒfen kann ob ein String Sonderzeichen enthĂ€lt. Mein Ansatz ist ein ST FB mit einer Case Schrittkette. Ich vergleiche jedes Zeichen des Strings mit allen Zeichen eines vorher definierten Strings erlaubter Zeichen, der A-Z, a-z und 0-9 enthĂ€lt und ggf angepasst werden kann, wenn ich weitere Zeichen erlaube. Leider wird meine j ZĂ€hlervariable nicht richtig ausgefĂŒhrt. Hat da jemand eine Idee? Oder gibt es eine einfachere Lösung/einen fertigen FB den ich mir anschauen kann? FUNCTION_BLOCK Sonderzeichen_Check VAR_INPUT inputString : STRING; // Zu prĂŒfender String startCheck : BOOL; // Startsignal END_VAR VAR_OUTPUT ok : BOOL; // TRUE, wenn keine ungĂŒltigen Zeichen END_VAR VAR i : INT := 1; // Input-String ZĂ€hler j : INT := 1; // erlaubte Zeichen ZĂ€hler allowedChars: STRING := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; // Erlaubte Zeichen currentChar : STRING[1]; // Aktuelles Zeichen step : INT := 0; // Schritt END_VAR CASE step OF 0: // Warten auf Start IF startCheck THEN step := 10; END_IF 10: // Initialisierungen i := 1; j := 1; ok := TRUE; // Standard: ok step := 20; 20: // Durchgehen des Eingangs-Strings IF i <= LEN(inputString) THEN currentChar := MID(inputString, i, 1); // Aktuelles Zeichen step := 30; ELSE step := 70; // Alle Zeichen ok END_IF 30: // Durchgehen der erlaubten Zeichen IF j <= LEN(allowedChars) THEN step := 40; // Zu Schritt 40 ELSE step := 60; // UngĂŒltiges Zeichen END_IF 40: // Vergleich IF currentChar = MID(allowedChars, j, 1) THEN i := i + 1; // NĂ€chstes Zeichen im Input step := 20; ELSE j := j + 1; // NĂ€chstes erlaubtes Zeichen step := 30; END_IF 60: // UngĂŒltiges Zeichen ok := FALSE; // Setze auf FALSE step := 0; 70: // Alle Zeichen ok step := 0; END_CASE
Last updated: 2025-01-20
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 gilbert-mh on CAA net base TCP client cause PLC to crash - Kernel message : N0HZ_local_softirq_pending 80
CODESYS Forge
talk
(Post)
Hello all, I have been trying to implement a TCP client on a Festo PLC (CPX-E-CEC-M1) and it looks like it works well except that after some time (greatly varies between a few hours to more than 100h) my PLC crash. When I look into the log file the only thing I see is that before the crash happens a few kernel warnings : N0HZ_local_softirq_pending 80 and then the crash. I've looked into this warning and from what I could find on the net it seems that this is warning is triggered when the ethernet link is down. I've tried to correct this bug for quite some time and what I know is that : - The crash is caused by my TCP client, when I remove it from my code I see no crash - The crash happens more quickly the more the TCP client is used. - The time before the crash is not directly proportional to the number of communications or their size. But it looks like it is just more likely to happen if the client connect to the server at a higher frequency. - The precedent observation makes it seem unlikely that the crash is caused by some memory overflow because then the crash speed would be more proportional to the amount of data exchanged. SO from these observations, I believe that the crash could be caused by the PLC trying to connect to a server while there is some kind of issue with the ethernet link resulting in the PLC getting stuck in some indefinite state and making it crash. This still seems a bit unlikely to me because if the ethernet is down it simply shouldn't be able to contact the server and the communication would just fail which doesn't cause my PLC to crash. Has anyone encountered the same kind of problem (with the same kernel message) ? I am pretty sure the warning is not the direct cause of the crash but just an indicator that something is wrong with my PLC. Thanks in advance
Last updated: 2024-01-12
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
.