Control Logix Mov or Cop to different data types

automfg

Member
Join Date
Jun 2006
Location
Kentucky
Posts
10
Hello,
I was wondering what would be the best way to transfer only the first 16 bits of a dint to a 16 bit int data type?

Controller: Control Logix 5000

Problem: I have an input card which has 16 inputs, but the Tag database for the input card is of the Dint data type (32 bits of data).

ex. for a 16 bit input card the tag would read

Local:0:I.Data.0
Local:0:I.Data.1
etc.
etc.
Local:0:I.Data.31

Now I would Like to transfer the first 16 bits only to a Int tag (16 bits of data).

What is the best method for this transfer?
 
automfg said:
Hello,
I was wondering what would be the best way to transfer only the first 16 bits of a dint to a 16 bit int data type?

Controller: Control Logix 5000

Problem: I have an input card which has 16 inputs, but the Tag database for the input card is of the Dint data type (32 bits of data).

ex. for a 16 bit input card the tag would read

Local:0:I.Data.0
Local:0:I.Data.1
etc.
etc.
Local:0:I.Data.31

Now I would Like to transfer the first 16 bits only to a Int tag (16 bits of data).

What is the best method for this transfer?

Why is your Tag Database a differnt size then your physical card?
If you move a DINT that will fit to an INT by the word, the conversion is done seamlessly with the Rockwell Software.
 
Firstly; the ControlLogix does everything in 32 bits so it pays to get used to it: converting data types takes CPU time. Bits 31-16 of your input card will always be zero's, don't worry about them.

Secondly; one of the big idea's in CLX is that you don't move I/O data into internal registers, you create alias tage for it and then use the alias tags within your code. It may be a new concept for you and therefore a little out of your comfort zone but the benefits can be huge. (If you're reading thumbwheels with the digital card then aliasing the bits doesn't make much sense but ingeneral it's the way to go)
 
Also because it is a 32 bit processor, if you move the data to an INT, next time the processor reads the INT it will have to pad bits 16-31 with zeros before it can do anything with it.

The only reason I can see for moving it to a 16 bit INT is if you are going to MSG the data to another PLC5 or SLC500 over a network. If you're not doing that, then stay in the native word size, 32 bit.

A COP or MOV instruction will both work however for making the move from a DINT to an INT when necessary.
 
I am transferring these bits to a panel view display via remote i/o. my MSG Write tag is 64 words long and type of INT (16 bits).
 
Ok, without going into the "Why do you want to do this" routine, I will offer one possible answer to your question............

Take a look at the BTD instruction. You can grab the first sixteen bits from your input module and place them in a destination INT tag.

The BTD will allow you to grab any contiguous bits in a source and copy them to contiguous bit locations in a destination.

The other posts have been trying to offer up that it may not be necessary to do any of this. In fact, it can actually slow down the system and use more memory. But, just in case, this was one way.

OG
 
Last edited:
The control logix has a feature called mapping for communicating with legacy panel views which would use N addressing. I suggest you look into using that feature.
 
I've tried the BTD approach... it still gives minor overflow errors if all all sixteen lower bits are set. I'm assuming because hFFFF as DINT is equal to 65535 and as an INT is equal to -32767. I Haven't looked too deeply into it since It causes no problems other than annoying me when I look at the PLC's fault log.

The process uses ControlLogx and a Visual Basic HMI/database. The HMI designer used CimQuest's activeX module to communicate with the PLC. They chose to do this with one big INT table that the PC checks every .5 seconds. The rungs that mov the I/O status to this table are always setting minor errors.

The process desinger also must not have known that ControlLogix is 32 bit because there wasn't a single DINT variable used. This includes two 3000 slot INT tables used for incremental encoder tracking. The scan time is still under 5 msecs though, which is more than fast enough for the application and a testament to how snappy ControlLogix is.
 
Opera Ghost is offering the best method for extracting bits from a word and inserting them in another.

MOV is not the way I would do this. The move instruction does conversions from one data type to another. Even though in this instance I think it would work I would not get in the habit of using it that way. I recommend you read up on the MOV,COP,CPS,BTD instructions. Each has a different use. The differences between them are subtle in some cases.

You can do some interesting data manipulation using the copy instructions. I have used them to fill contigous words of data before even when the data types do NOT match. I believe there is a kb document that discusses this and the precautions needed when doing it.

You should NOT be using INT or SINT data types unless it is required to communicate with certain hardware. The processor runs much faster on 32 bit data types. RIO, would be an example of when you need 16 bit words though.

Answer to your question was already given by Opera Ghost. BTD

RSL
 
NOP said:
Secondly; one of the big idea's in CLX is that you don't move I/O data into internal registers, you create alias tage for it and then use the alias tags within your code.
Works great until you get a device wired to the wrong point, or moved from one spot to another, and you realize you can't update a tag alias online.

You also have to remember that I/O data updates asynchronously to program scan. If you've got a program with particular timing/sequencing requirements you end up having to buffer your I/O data anyway or risk unexpected behaviour.

So I'm really not a fan of using tag aliases for I/O data.
 
automfg,

The best way I have found to move the data from a DINT into an INT when the data in question is on the bit level is to use a COP or CPS.

I do it this way...
Create an INT array with 2 elements.
COP MyDINT MyINTArray[0] 2
The DINT is split into two INTS with no data conversion, no sign extension, and no nuisance minor arithmetic faults.

If you need to go the opposite direction...
COP MyINTarray[0] MyDINT 1
 
optimus2861,

I am also not a big fan of using an alias for I/O data. I generally have the I/O data as part of a control module UDT. This requires rungs to map I/O data into the UDT. You get I/O buffering as part of the deal. It also makes substituting simulated I/O for real I/O a snap.
 
Optimus, I understand that not everyone's happy with asychronous I/O updates so I don't want to bang on and on about this but, in reply to your post:

Works great until you get a device wired to the wrong point
Get a better wireman!:) But seriously, if this happens (OK, when this happens) aren't you more likely to power off your plant and make offline edits? Even if you absolutely have to make an online edit you can make a new tag (with the correct alias) and substitute it into your code. Not perfect, I accept, but possible.

As for the "unexpected behaviour"; I've worked with a lot of people's CLX code in the past 5 years and never had any problems caused by this; one of my coworkers has seen it once, on PLC5 code that had been through the translation tool. I accept that it can happen but if you've read the manuals/been on the course/read PLCS.net it shouldn't be unexpected.

I think that your objections are valid and that we all have a favourite way of writing code but, for me, they don't stack up against the ability to start writing code without waiting for someone to produce an I/O schedule, the use of named Tags for each I/O channel without using code to achieve it and the fast I/O response possible by high RPI rate and/or CoS data from 1756 I/O modules. If you really don't like asynchronous I/O you could always use Function Block:ROFLMAO:

Now, when you can alias I/O straight into UDT's........🍺
 
I HATE alias tags too. I use code to map my data into UDT's also. I have never taken to alias tags and at this point probably won't.

What mellis stated about using CPS or COP is what I mentioned earlier. That works real well too.

If your destination is an array in a UDT use caution. You can get some data corruption if you don't define the length of your array's correctly. If you use COP or CPS on 2 different data types it is possible for the copy instruction to write past the end of your array into it's neighbor. This can be VERY bad. You have to get the size of your destination and the lenght of your COP instruction right. The copy instruction will not exceed the boundries of your UDT in the memory. It will gladly write over other data within the UDT though.

http://domino.automation.rockwell.com/applications/kb/RAKB.nsf/0/0648D39E84D8349B85256E5F004C0723?OpenDocument

The copy length "units" is determined by the destination you select. Meaning if the target is bit level then the length is in bits. The same is true for INT's DINT's etc. This is where the mistakes can happen.

I am about 90% sure about this, if I am wrong someone please correct me.

RSL
 
Last edited:
NOP said:
Get a better wireman!:) But seriously, if this happens (OK, when this happens) aren't you more likely to power off your plant and make offline edits?
In my experience, most of the time when I've reached the point of powering on my processor and going into run mode, there's no longer any such thing as "offline edits". Anything & everything gets done online, more often than not with the processor still in run mode. There will be something connected to the thing that'll be running and that the operator won't want to or can't shut down for the sake of making even a small program edit. I've even worked at a plant where downloading a program to a processor was forbidden -- all edits to the program were to be done online (a rule which I bent and got burned on, troubleshooting a messed-up speed control loop until 4am because the file I downloaded had some outdated register values that three of us couldn't track down to fix. Bad program, bad experience).

So I try very much to avoid anything that can't be changed while the program is running, which strictly rules out aliasing I/O.

As for the "unexpected behaviour"; I've worked with a lot of people's CLX code in the past 5 years and never had any problems caused by this;
I experienced it once and it was enough to scare me off it for good. A steam peeler that had a defined sequence of operation, somehow was getting thrown out of sequence by a rare asynchronous sensor update. Maybe once every 1000 cycles or so, rare enough that at first we dismissed the problem as a false report from the operator. Once we switched that program to buffered I/O from direct I/O to make everything synchronous -- we only got to this point for lack of anything else to try -- the problem disappeared. I never could figure out exactly at what point in the scan which sensor was changing that was causing the problem, but couldn't deny that buffering the I/O killed the problem dead.

I view it as a potential source of aggrivation that I don't need, so again, I avoid it.
 

Similar Topics

Hi Guys, Nice easy one for you...I have an array of 150 Analog Inputs. Is there an instruction I can use to move a value into a member of each...
Replies
12
Views
6,136
I am having trouble with getting no control of my analog output signal. I am using the SCL function block to control my analog output. The logic...
Replies
11
Views
257
hi all, i have a plc i need to get info from for a site im working on: I have a 1764 Micro Logix 1500 LSP Series C (See Attached Image) im...
Replies
2
Views
381
I currently have a weird issue involving Ethernet IP communication between a ABB CI873 (EthernetIP Module) and a 1756-L83ES. The Layout is as...
Replies
8
Views
762
Possible for two processors in same rack to have separate motion groups across a single Kinetix Rack using a single EN3TR? One 6500/5700 rack, 8...
Replies
1
Views
426
Back
Top Bottom