i'm new to PLC programming and i have a problem with connection to the beckhoff device. I used a EL1008 device which has 8 Inputs. On the beckhoff website i found this table below. I'm confused when assigning variable to the inputs, which variable is mapped to %IX0.0 %IX0.1 %IX0.3
If you open up your hardware tree and click on your individual inputs, you can see which variable they are linked to, and if they are linked at all.
The most common way to map I/O is to declare globals variable like this:
// Inputs
myInput1 AT %I* : BOOL;
myInput2 AT %I* : BOOL;
// Outputs
myOutput1 AT %Q* : BOOL;
myOutput2 AT %Q* : BOOL;
You then find your physical I/O in the hardware tree, double click them and assign them to your variables.
%IX0.0, %IX0.1 and %IX0.3 are just the address in the register.
If you're using TwinCAT 3, usually these variables are declared in the Global Variable List. Alternatively, you can also use %I* to let the software automatically map the variable to the register address.
This, however, does not map your variable to the hardware (in your case, a Digital Input). To do that, you have to get to the I/O tree and assign the variables to each Digital Input channel.
Make sure to build your solution first, or else your variables won't be found.
Find your EL1008 device, open the tree and link the hardware to a variable.
The variable is now mapped to the device. Activate Configuration and restart TwinCAT in Run Mode.
To answer your question Terminal input 1 goes to %IX0.0., terminal input 2 goes to %IX0.1, etc.
Related
When we pin a MAP, we can able to share information from userspace to ebpf but it is system wide.
But if i want to share different value to different instance from tc ingress/egress (array map with size of 1)
Is there any way to pass argument ?
Map (unpinned unique per instance) - update from userspace
Any other way to communicate from userspace to kernel (while attaching or after)
Really appreciate your help.
Pinning a map doesn't make it system wide. Every map is always accessible system wide, pinning just adds a reference to the file system to make it easier to find and to make sure a map isn't removed even when not in use by any program.
Is there any way to pass argument ?
No, once a program is loaded, only the kernel can pass arguments(contexts) to a program, userspace can only use maps to communicate with eBPF programs.
Map (unpinned unique per instance) - update from userspace
Any userspace program with the right permissions can update any map as long as you can obtain a file descriptor to the map. Map FDs can be obtained:
By creating a new map
By opening a map pin
By using its unique ID (directly or by looping over all loaded maps)
By IPC from another process that already has the FD
Any other way to communicate from userspace to kernel (while attaching or after)
Maps are it. You can rewrite the program before loading it into the kernel by setting constants at specific locations, but not at attach time. One way which might be interesting is that on newer kernels, global data is supported. Which allow you to change the value of variables defined in the global scope from userspace. In this case the global data is packed in a array map with a single key/value.
I'm actually using the Ecostruxure skin on codesys, trying to attach the output of a Modicon encoder to determine the speed a motor should go.
However, I can't figure out how to grab the variable that would correspond to that data. Any help appreciated.
The screenshots below indicate where I'm stuck. I need to create a variable of type ENC_REF_M262 however double clicking on the device does not take me to a screen I can map it with like what I've seen on a number of other devices. Obviously something I'm missing. The linking between this physical device and actually getting data from it is the part I'm struggling with.
edit: The system seems to have now correctly accepted the settings when before the reference to the variable Incremental Encoder would not be found. Seems to take a while to catch up.
I was wondering,
Is there anyway to force writing on a 'Read-Only' Modbus Register?
Does defining a Register as a 'Read-Only' is secure enough or can be bypassed??
Thanks for the answers!
The correct way to define a "read-only" analog variable in Modbus is to map it as an input register. There is no function code defined in Modbus to write to an input register.
For historical reasons, several vendors maps all their variables as holding registers, which are theoretically read/write, i.e, there's a Write Multiple Registers function. Whenever they map a read only variable as a holding register, they must assert that the write functions fail. However, there's no standard exception code for this, as a holding register should be read/write. This is only one of Modbus' idiosyncrasies.
Getting back to your question, if you map your variable as an input register, you can be sure that the protocol will not allow a master to write to it. If, for interoperability issues you map it as a holding register, the protocol will allow the master to use a write funcion to change its value, and it is up to you to block in your device implementation.
I need to increment an integer value each time the PLC program is updated to track changes.
There are system events like online_change and before_download, but I have no idea how to implement their functions.
Also I need to save value between updates. I think the tracking variable should be created as RETAIN but not sure.
The variable declaration type should be VAR RETAIN PERSISTENT in your case. Variables declared under RETAIN only will lose their values (intentionally) with a program change.
I believe the builtin Codesys library SysLibProjectInfo.lib has what you are looking for with the function SysGetProjectID. If you store SysGetProjectID as a RETAIN PERSISTENT and then compare against it, you can track changes (or, this unique value may be exactly what you wanted in the first place, without manually creating an ID).
Note: Depending on how you declare your variables, changing the I/O configuration can have unexpected changes even on VAR RETAIN PERSISTENT variables (as all dynamically allocated addresses are shifted and may not point where they used to).
If I understand you you only want to know like what version is running on the PLC and you want to track changes that you make? You can do it two ways:
Since it's a constant each time you make a change external to the PLC you roll the rev of a variable that is declared like SoftwareVersion :WORD := 100; and keep it in a Revision global list that you can add your notes to and change the version before downloading to PLC.
You can also use the PLC summary area that has fields to enter the values and then you can read them through CoDeSys without software upload.
And of course the suggestion above can work.
I am controlling a pilot plant of boiler through Matlab using modbus RTU (serial communication).
I am running my control program (in editor) for 45 mins through a loop but I am facing two problems :
1] I can't change any variable value while running program which is deadly needed.
2] I am unable to see real time data in workspace while running script.
It updates all variables after finishing execution time. For my application I want data to appear for every iteration.
I couldn't solve them so I switched to simulink but that was even more frustrating.
In simulink I used user defined blocks (embedded Matlab function) to generate modbus address PDU which does not support to in-built matlab functions (like dec2hex).
Will please someone let me know in simulink, serial send/receive support which data format?(ASCII/HEX/DEC)
If you want to see the status of your system after each iteration this can be solved by putting a breakpoint there. If required you can even change the value of variables then.