Register COP, MOV, MVM Unsigned to Signed, Etc.

AMarks95

Member
Join Date
Jul 2018
Location
South Dakota
Posts
224
I'm having to make an AOI to use with a generic ethernet device because the manufacturer does not provide an AOP. I just want to do a sanity check to make sure I'm copying/moving/masking things correctly to get the results I expect, since these are not things I typically do.

The bits are easy enough to handle, it's just the combining of SINTs and conversion to other datatypes.

The input data structure is an array of SINTS. Here's an example:

Breakdown of Data | type SINT[12] :
Bytes 0/1 - UINT Trip Code
Bytes 2/3 - Trip Bits | [2].2 = Ground Current, [2].3 = Thermal Overload, [3].0 = comm trip
Bytes 4/5 - INT Temperature (deg C)
Bytes 6/7/8/9 - UDINT Current (x0.01 A)
Bytes 10/11 - Misc. Stats and Current | [11].0 - [11].5 ( 0 - 63 )


Trip code:
COP(Source = Data[0], Dest = TripCode, Length = 1) | where TripCode is type INT
Not worried about signed vs unsigned here because the code will never be larger than 555.


Trip Bits:
GroundCurrentTrip = XIC(Data[2].2)
ThermalTrip = XIC(Data[2].3)
CommTrip = XIC(Data[3].0)


Temperature:
COP(Source = Data[4], Dest = Temp_INT, Length = 1) | where Temp_INT is type INT
MotorTemp = ( Temp_INT * 9/5 ) + 32 | where MotorTemp is type REAL


Current:
COP(Source = Data[6], Dest = Current_Temp, Length = 1) | where Current is type DINT
Current = Current_Temp / 100 | where Current is type REAL
Less confident about this one because of the unsigned/signed thing. Should Current_Temp be type UDINT? - COP doesn't like the datatype UDINT, and UDINT is not allowed inside CPT


Misc. Stats and Current:
COP(Source = Data[11], Dest = Temp_SINT[0], Length = 1) | where Temp_SINT is type SINT
MVM(Source = Temp_SINT[0], Mask = 2#11111100, Dest = Temp_SINT[1])
Current2 = ( Temp_SINT[1] / 32 ) * 100 | where Current2 is type REAL
I realize the COP is an extra step, but I like it for readability's sake.


Any help is much appreciated. Thanks!
 
Last edited:
COP() is a great choice for mapping bytes of incoming data, since it is bit-wise work.

I would argue it’s the best choice.

You can take it a step further:
- construct a UDT that matches their layout
- then simply COP(Device:I, UDT, 1)
 
COP() is a great choice for mapping bytes of incoming data, since it is bit-wise work.

I would argue it’s the best choice.

You can take it a step further:
- construct a UDT that matches their layout
- then simply COP(Device:I, UDT, 1)

What do you mean by a UDT that "matches their layout"?
If I created a UDT with data elements in the exact same order accounting for every bit, but not necessarily the same type, I can copy directly?

So, for instance in this case, my UDT would be:
Data_UDT :
TripCode type UINT
Trip_Bits type SINT[2]
Temperature type INT
Current type UDINT
Misc type SINT[2]


Then do a COP(Device:I, Data_Map, 1) | Data_Map is type Data_UDT

Will it copy the data over in order and then I can go from there?
So, essential the COP operation would just fill up TripCode with the first 16 bits, then Trip_Bits with the next 16, then Temperature with the next 16, then Current with the next 32, and Misc with the next 16?
 
COP() is a great choice for mapping bytes of incoming data, since it is bit-wise work.

I would argue it’s the best choice.

You can take it a step further:
- construct a UDT that matches their layout
- then simply COP(Device:I, UDT, 1)

Combine trip bits into an INT or UINT, same for MiscType.

Right, but that's pretty much optional and personal preference. It'll still work, right? The basic understanding is the same.
 
It will work, yes.

Dealing with an array sub-element instead of a matched INT/DINT can become cumbersome later when you go to use it in code:
- Data.Status[0].4 or Data.Status.4?
- Data.Status[1].3 or Data.Status.11?

Then there's MiscType:
- Is it really just INT/UINT from the device?
- If so, you'll be doing another COP(Data.MiscType[0], AnotherMiscTypeTag, 1) instead of just using Data.MiscType directly.
 
Last edited:
I've got a UINT now with the first 8 bits being status bits, the next 6 being an INT, and last 2 being status bits. How do I go about extracting those 6 bits from the center?
 
I've got a UINT now with the first 8 bits being status bits, the next 6 being an INT, and last 2 being status bits. How do I go about extracting those 6 bits from the center?

In that case, you can take a small step back in your UDT and make the UINT two USINT.

First one is StatusBits, second one gets ANDed with 0x3F mask, and remaining pair of bits can be addressed directly (byte.6, byte.7).
 

Similar Topics

I am attempting to reject a bottle If the label fails. The rejection works fine at normal line speed but at low speed the rejector fires (air...
Replies
35
Views
1,149
Hi everyone, I am working on a project that needs to expose the SV (Set Value) of a temperature controller to a SCADA system. SCADA <-...
Replies
4
Views
162
I'm pretty new to PLC's, so forgive me if I use the wrong terminology and whatnot. We have an issue at work where we have a flow meter that is...
Replies
10
Views
291
I would like to copy register N61:131 thru N61:147 into ST252:0 I keep failing What happens is I copy into ST252:0,1, 2 etc. What am i missing...
Replies
18
Views
586
Hello Siemens experts. I am trying to register a GSDML file for an Endress & Hauser's Profinet IO over APL (Profile 4.0) compliant device. TIA...
Replies
2
Views
210
Back
Top Bottom