Closed csharpsithlord closed 9 months ago
Good afternoon I understand that I haven’t described the library enough, but I’ll try to describe the idea step by step.
Example:
// Creating of Tag Handlers.
List<LogixTagHandler> logixTagHandlers = new List<LogixTagHandler>();
LogixTagHandler logixTagHandler1 = new LogixTagHandler("plc_tag_1");
logixTagHandler1.ReadMethod = TagReadMethod.Simple; // Is simple method from AB Manual.
//logixTagHandler1.ReadMethod = TagReadMethod.Fragmet; // Is simple method from AB Manual for Array reading.
//logixTagHandler1.ReadMethod = TagReadMethod.Table; // Is method use by AB Devices as HMI, is not described in manuals, was fully
// studied by wireshark. Advanteges - high update rate for big count of tags.
logixTagHandler1.ReadUpdateRate = 500;
logixTagHandlers.Add(logixTagHandler1);
LogixTagHandler logixTagHandler2 = new LogixTagHandler("plc_tag_2");
logixTagHandler2.ReadMethod = TagReadMethod.Simple;
logixTagHandler2.ReadUpdateRate = 1000;
logixTagHandlers.Add(logixTagHandler2);
// Creating of Device.
LogixDevice logixDevice1 = new LogixDevice();
logixDevice1.Name = "My_PLC_1";
logixDevice1.Family = DeviceFamily.ControlLogix; // or DeviceFamily.Micro800
logixDevice1.Address = IPAddress.Parse( "192.168.1.10");
// Creating of Task.
LogixTask logixTask = new LogixTask(logixDevice1 );
//logixTask.Message += LogixTask_Message; // Your events for Log Messages.
//logixTask.TagsValueWasChanged += LogixTask_TagsValueWasChanged; // Your events for New readed tag values (if changed).
//logixTask.TagsValueWasReaded += LogixTask_TagsValueWasReaded; // Your events for New readed tag values (if updated).
logixTask.Begin(logixTagHandlers);
// Reading status of Task.
TaskProcessState taskProcessState = logixTask.ProcessState; // General Status of Task
ServerState serverState = logixTask.ServerState; // Status/step of process.
// Reading status and values of Tag Handlers.
long? actualUpdateRate1 = logixTagHandler1.ReadValue.Report.ActualUpdateRate;
bool? operationResult = logixTagHandler1.ReadValue.Report.IsSuccessful;
List<byte[]> rawBytes = logixTagHandler1.ReadValue.Report.Data; // List<> - is array containers, byte[] - is Item bytes of array.
// For simple tag (int) List<> count == 1, byte[] Length == 4.
Thank you.
For writing also
logixTagHandler1.WriteMethod = TagWriteMethod.Simple;
logixTagHandler1.WriteValue.RequestedData = /* value for write */;
logixTagHandler1.WriteUpdateRate = 0; // Set 0 for writing once, if logixTagHandler1.WriteEnable == true
// after writing logixTagHandler1.WriteEnable will reset.
// For cycling Writing - set your update rate.
logixTagHandler1.WriteEnable = true; //
Is there a way to read / write without creating a LogixTask and adding LogixTagHandler to it? A way to directly use the LogixDevice ReadTag, ReadTags, WriteTag, WriteTags to perform a single read or write command?
Please try this. In my library I not used Exception conception because it was many time ago.
// Creating of Tag Handlers.
List<LogixTag> logixTags = new List<LogixTag>();
LogixTag logixTag1 = new LogixTag();
logixTag1.SymbolicEPath = new EIP.EthernetIP.EPath();
logixTag1.SymbolicEPath.Segments.Add(new EIP.EthernetIP.EPathSegment("plc_tag_1")); // Your Controller Tag!
logixTags.Add(logixTag1);
LogixTag logixTag2 = new LogixTag();
logixTag2.SymbolicEPath = new EIP.EthernetIP.EPath();
logixTag2.SymbolicEPath.Segments.Add(new EIP.EthernetIP.EPathSegment("plc_tag_2")); // Your Controller Tag!
logixTags.Add(logixTag2);
// Creating of Device.
LogixDevice logixDevice1 = new LogixDevice();
logixDevice1.Name = "My_PLC_1";
logixDevice1.Family = DeviceFamily.ControlLogix; // or DeviceFamily.Micro800
logixDevice1.Address = IPAddress.Parse("192.168.1.10");
//logixDevice1.Message += LogixDevice1_Message; // Your events for Log Messages.
logixDevice1.Connect();
logixDevice1.RegisterSession();
logixDevice1.ForwardOpen();
// **********************************************************************************************
logixDevice1.ReadTag(logixTag1); // Simple reading Tag
bool? resultOfReading = logixTag1.ReadValue.Report.IsSuccessful; // True -> is Success.
List<byte[]> tagValue = logixTag1.ReadValue.Report.Data; // Raw Bytes.
// option : convert value to string;
logixTag1.Radix = TagValueRadix.Decimal;
string valueString1 = logixTag1.GetReadedValueText(); // Value as string.
// **********************************************************************************************
logixDevice1.ReadTags(logixTags); // Simple reading Tags.
// **********************************************************************************************
logixTag1.WriteValue.RequestedData = new List<byte[]>() { BitConverter.GetBytes((int)1) }; // Writing Int32 tag value (you shure about type).
logixDevice1.WriteTag(logixTag1); // Simple write Tag
bool? resultOfWriring = logixTag1.WriteValue.Report.IsSuccessful;
// **********************************************************************************************
logixDevice1.WriteTags(logixTags); // Simple writing Tags.
Thank you very much. This is a great implementation of the protocol.
What has to be different to read a UDT tag like "HexConverters[0].Decimal_Value" or to read String data types?
Do I understand correctly that the question is how to set the path for UDT or String and how to get value for it?
That is correct. I tried the previously mentioned method and the data returns null.
Ok! I see! For UDT try this:
logixTag1.SymbolicEPath = new EIP.EthernetIP.EPath();
logixTag1.SymbolicEPath.Segments.Add(new EIP.EthernetIP.EPathSegment("HexConverters")); // Your UDT Tag !
logixTag1.SymbolicEPath.Segments.Add(new EIP.EthernetIP.EPathSegment(EIP.EthernetIP.EPathSegmentHeader.Local_MemberID, 0););
logixTag1.SymbolicEPath.Segments.Add(new EIP.EthernetIP.EPathSegment("Decimal_Value"));
For String I will update little bit later.
Just checking back to see if you found anything for string type? Reading and writing.
Sorry for the long delay. To me, a string is a System UDT structure. Either way you will get a few bytes (ASCII encoding). I suggest reading it using the ReadTagFragment method. One note. I not checked is code, because I don't have any Allen Bradley device (PLC) now.
LogixDevice logixDevice1 = new LogixDevice();
logixDevice1.Address = IPAddress.Parse("192.168.1.1");
logixDevice1.Name = "My_PLC_1";
logixDevice1.Family = DeviceFamily.ControlLogix;
//logixDevice1.Message += LogixDevice1_Message; // Your events for Log Messages.
logixDevice1.Connect();
logixDevice1.RegisterSession();
logixDevice1.ForwardOpen();
/* Reading of Tag 'MyUDT.MyString', where MyString - is String (for eaxmple Length = 8 bytes) */
LogixTag logixTag1 = new LogixTag();
logixTag1.Type.ArrayDimension.Dim0 = 8; // Length of reading is 8 chars (Single dimension of array).
logixTag1.SymbolicEPath = new EIP.EthernetIP.EPath();
logixTag1.SymbolicEPath.Segments.Add(new EIP.EthernetIP.EPathSegment("MyUDT")); // Your UDT Tag !
logixTag1.SymbolicEPath.Segments.Add(new EIP.EthernetIP.EPathSegment("MyString")); // Your String member.
logixTag1.SymbolicEPath.Segments.Add(new EIP.EthernetIP.EPathSegment("DATA")); // Is Array with bytes as ASCII chars.
logixDevice1.ReadTagFragment(logixTag1);
if (logixTag1.ReadValue.Report.IsSuccessful == true)
{
var data = logixTag1.ReadValue.Report.Data;
// Convert to string.
if (data != null)
{
byte[] stringBytes = data.Select(x => x.First()).ToArray();
string readedString = Encoding.ASCII.GetString(stringBytes);
}
}
How could I create, say a new winforms app, and add a controller then read / write data from / to tags? Using just the EIP library.