
HerculesRockefeller (Customer) asked a question.
This being the first time I've used this controller, I'm trying to figure out how to map variables to Modbus addresses so I can access them on my CM5 HMI. As stated in the title, I'm using ModbusTCP instead of ModbusRTU.
A basic overview of how address mapping works would be helpful. Here are a few questions I've already run into:
- How are double-word variable types like DINT mapped to Modbus addresses?
- Are the bit/byte addresses listed on the I/O mapping page listed in order of Modbus address?
- When a variable tag is assigned, the default address is struck through which to me implies that it is being overridden to map to the tag. Is this accurate?
- Is assigning variable tags in the I/O mapping page the correct approach, or should I be listing register addresses in my variable declarations?
- Can a single variable tag be mapped both to an I/O address and to a Modbus address to reduce redundancy?
In addition, I'm curious if my current approach of using the PLC as the ModbusTCP server and the HMI as the client is advisable. I'm planning to store all of my state information in the PLC, and simply display status & prompt the PLC to change the value of variables from the HMI.
I'm coming from a troubleshooting & service background, so apologies for my limited/lacking knowledge of basic protocol setup.
I haven't used Cmore much lately, if they don't have a symbolic driver for Codesys I'd re-evaluate why you want to use a Cmore as you'll be creating a lot of extra work vs simply using the built in Codesys visu and a web client or an HMI with full symbolic support for Codesys.
Regarding your questions though. Nothing is pre-configured for Modbus so you'll be on your own to define things as needed. HMI as master and PLC as slave is correct.
Development in Codesys can be incredibly fast and efficient but it does take a different way of thinking vs "traditional" PLCs.
Excellent comments Durally.
Probably already have seen, but if not and has any insights that are helpful, here ya go:
https://docs.codesys-p2cds622.com/en/latest/Example%20Projects/modbus_tcp.html
In addition, I have found this to be one of the best references to have in your library:
"Book of CODESYS" by Pratt. 2nd edition just released
Just wanted to comment on that last question about using a single variable for both modbus address and i/o.
Because our i/o has a address and so does the modbus registers, you can't map an existing variable with an address. At least for our devices anyways.
But like Durallymax says, that would be messy. I myself prefer to separate my i/o variables from modbus variables.
Edit: Sorry you can use a program variable to map to both modbus and i/o address. My initial thought you were asking is if you can map a variable created in the i/o to a modbus variable.
Doesn't work on the hardware I have either "map to existing variable with address is not allowed!"
Thanks for the feedback. Yeah there are so many ways to do things in Codesys.
I appreciate the feedback guys - all this flexibility is a little overwhelming, but it's also the reason I'm trying to migrate to Codesys in the first place.
As for why I'm using CMore with Codesys - our facility already uses CMore everywhere, so I wanted to keep consistent with the HMIs our operators are already using. The DirectLogic and CLICK controllers we have everywhere are a bit limiting though, so I opted to upgrade to the Codesys unit for my current project. I naively didn't even consider that the PLC<->HMI connection might be more complicated with this setup.
To make sure I understand correctly -- having my modbus and io addresses point to program/global variables instead of having my program variables point to modbus/io addresses during variable declaration is a valid approach then? I'll probably still have dedicated program variables point to my I/O addresses, but being able to point modbus addresses to my program variables (of compatible data types) instead of vise versa seems useful.
**edited last paragraph for clarity
Well this is where it gets interesting. For physical IO cards I put the full path to a program variable at each IO point as one of the last steps once a program is finished.
For Modbus, Ethernet/IP, etc. I like to also do this, but due to type conversion errors in some cases you're left to create a new variable in that device's I/O and point to it, then do the work from there in some sort of FB to handle the mapping.
A lot of this depends on how you're trying to write your program as well. A traditional PLC program would take a much different approach vs something using more OOP and trying to remain flexible.
"For physical IO cards I put the full path to a program variable at each IO point as one of the last steps once a program is finished." After making some tweaks to my I/O assignments, this honestly seems like the best approach. It makes things cleaner inside the variable declarations and less headache-y when I need to alter my I/O mapping.
I'll test transmission of 32-bit floats and integers between the PLC and HMI just to see what I can get the C-More to cooperate with. Hopefully I can report back with some positive results - the more I get into this, the simpler it looks, so fingers crossed.
"having my modbus and io addresses point to program/global variables instead of having my program variables point to modbus/io addresses during variable declaration is a valid approach then"
Sorry if I made things more confusing. Yes either way works with program and global variables.