/// <summary> /// Создает новый аргумент события. /// </summary> /// <param name="tag">Текущий тэг.</param> /// <param name="oldDevice">Старое (текущая) задача устройства которое привязано к тэгу.</param> /// <param name="newDevice">Новое задача устройства к которому стоит привязать тэг.</param> public TagTaskBeginEditEventArgs(LogixTag tag, LogixTask oldDevice, LogixTask newDevice) { this.Tag = tag; this.OldDevice = oldDevice; this.NewDevice = newDevice; this.Cancel = false; }
static void WriteTag(LogixProcessor processor) { //Writing a tag is also very easy. First, create a tag... string address = GetTagAddress(); if (string.IsNullOrEmpty(address)) { return; } //Now we have to create the tag on the processor. The easiest way to //do this without knowing the underlying type is to use the //LogixTagFactory class. LogixTag userTag = LogixTagFactory.CreateTag(address, processor); if (userTag == null) { Console.WriteLine("Could not create the tag " + address + " on the processor"); return; } switch (userTag.LogixType) { case LogixTypes.Bool: WriteBool(userTag, processor); break; case LogixTypes.DInt: case LogixTypes.LInt: case LogixTypes.Real: case LogixTypes.SInt: WriteOther(userTag, processor); break; case LogixTypes.Control: case LogixTypes.Counter: case LogixTypes.Timer: case LogixTypes.User_Defined: WriteStructure(userTag, processor); break; default: Console.WriteLine("The LogixType of " + userTag.LogixType.ToString() + " is not supported in this sample"); return; } PrintTagValue(userTag); //And go back to the menu }
/* ================================================================================================== */ /// <summary> /// Добавляет новую привязку тэга контроллера с его условным идентификатором в таблицу. /// </summary> /// <param name="id">Идентификатор тэга в таблице (идентификатор возвращается удаленным устройством).</param> /// <param name="tag">Контроллерный тэг.</param> /// <returns></returns> public bool Add(UInt16 id, LogixTag tag) { if (this._Items.ContainsKey(id)) { return(false); } CLXCustomTagMemoryItem newItem = new CLXCustomTagMemoryItem(id, tag); newItem.ParrentTable = this; tag.OwnerTableItem = newItem; this._Items.Add(id, newItem); return(true); }
static void WriteOther(LogixTag tag, LogixProcessor processor) { Console.Write("Enter a value: "); string sValue = Console.ReadLine(); //Now we have to convert it to the right type... try { switch (tag.LogixType) { case LogixTypes.DInt: ((LogixDINT)tag).Value = Convert.ToInt32(sValue); break; case LogixTypes.Int: ((LogixINT)tag).Value = Convert.ToInt16(sValue); break; case LogixTypes.LInt: ((LogixLINT)tag).Value = Convert.ToInt64(sValue); break; case LogixTypes.Real: ((LogixREAL)tag).Value = Convert.ToSingle(sValue); break; case LogixTypes.SInt: ((LogixSINT)tag).Value = Convert.ToSByte(sValue); break; default: return; } //At this point the tag has not been committed to the processor. The //tag must be written, then read back for the value to change. The //easiest way to do this with a single tag is to use the processor //LogixProcessor.WriteRead() which performs the write, then the //subsequent read on the tag. processor.WriteRead(tag); } catch (Exception e) { Console.WriteLine("Could not convert " + sValue + " to the correct type for " + tag.Address); } }
static void WriteBool(LogixTag tag, LogixProcessor processor) { Console.WriteLine("Enter 1 for True, 0 for False: "); char key = Console.ReadKey().KeyChar; if (key == '1') { ((LogixBOOL)tag).Value = true; } else { ((LogixBOOL)tag).Value = false; } //At this point the tag has not been committed to the processor. The //tag must be written, then read back for the value to change. The //easiest way to do this with a single tag is to use the processor //LogixProcessor.WriteRead() which performs the write, then the //subsequent read on the tag. processor.WriteRead(tag); }
static void ReadTag(LogixProcessor processor) { //Reading a tag is very easy. First, create a tag... string address = GetTagAddress(); if (string.IsNullOrEmpty(address)) { return; } //Now we have to create the tag on the processor. The easiest way to //do this without knowing the underlying type is to use the //LogixTagFactory class. LogixTag userTag = LogixTagFactory.CreateTag(address, processor); if (userTag == null) { Console.WriteLine("Could not create the tag " + address + " on the processor"); return; } //The tag is automatically read when it is created. The LogixProcessor does this //to verify the tag exists and to get type information about the tag. From this //point on you can read/write the tag all you want, either by using tag groups //or by directly writing it with the LogixProcessor.WriteTag() function. //We'll demonstrate a read anyway... if (!processor.ReadTag(userTag)) { Console.WriteLine("Could not read the tag: " + userTag.LastError); } //Print the value out with our handy helper function PrintTagValue(userTag); //And go back to the main menu }
static void Main(string[] args) { //First we create the processor object. Typically the path is the slot //number of the processor module in the backplane, but if your communications //card is not in the same chassis as your processor, this is the path through //the chassis to get to your processor. You will have to add a 1 for every //chassis you go through, for example: //Chassis 1: ENBT card in Slot 1 (slot is irrelavent), ControlNet Card in Slot 2 //Chassis 2: L61 in Slot 4 //Path would be: { 2, 1, 4 } //Basically it's the target slot, 1 for backplane, target slot, 1 for backplane... //until you get to the processor. string hostNameOrIp = "192.168.1.10"; byte[] path = new byte[] { 1 }; LogixProcessor processor = new LogixProcessor(hostNameOrIp, path); //Connect to the PLC, you can create the events before or after the connect function if (!processor.Connect()) { Console.WriteLine("Could not connect to the processor"); Console.ReadKey(false); return; } //Tag groups allow you to group tags in a useful manner. For example in an HMI you //could create tag groups for each page. Disabling a tag group that is not in use //frees up resources on the processor and the network. //You also have to be careful about the two different kinds of Enabled properties. //There is an enabled property for the tag group, and there is an Enabled property //for the tag itself. Disabling the tag group stops it from being updated, so no //tags belonging to that group will be updated (unless they also belong to another //active tag group). Disabling the tag by setting the LogixTag.Enabled property //to false means that the tag won't accept new data or pending values, and that //any tag group that it belongs to won't update it. //First, we need to create a LogixTagGroup on the processor. The easiest way to do //this is to use the LogixProcessor.CreateTagGroup() method. This allows the //processor to create the tag group, verify it doesn't conflict with another tag //group, and manage the group. LogixTagGroup tg = processor.CreateTagGroup("MyGroup"); //Now that we've created a tag group, we can add some tags to it. Adding and removing //tags from a tag group is an expensive process. The tag group will automatically //re-optimize all the tags it's responsible for when you add or remove a tag. It's //recommended that you don't add or remove tags very often, if you don't need a tag //to be updated anymore just set the LogixTag.Enabled property to false. //Here we are going to ask the user (probably you) for some tags. The easiest way to //create tags without knowing the underlying data type in the processor is to use //the LogixTagFactory. bool quitFlag = false; LogixDINT dTag = new LogixDINT("tst_Dint", processor); dTag.TagValueUpdated += new ICommon.TagValueUpdateEventHandler(TagValueUpdated); tg.AddTag(dTag); while (!quitFlag) { Console.Write("Please enter a tag name to monitor, enter 'done' when finished: "); string tagName = Console.ReadLine(); if (tagName.ToLower() == "done") { quitFlag = true; continue; } LogixTag userTag = LogixTagFactory.CreateTag(tagName, processor); if (userTag == null) { //When the tag factory returns null, the tag was not found or some other //catastrophic error occurred trying to reference it on the processor. Console.WriteLine("The tag " + tagName + " could not be created"); continue; } //If we got here, we were able to successfully create the tag. Let's print //some information about it... Console.WriteLine("Created " + tagName + " as a(n) " + userTag.LogixType.ToString()); //Let's reference the update functions... userTag.TagValueUpdated += new ICommon.TagValueUpdateEventHandler(TagValueUpdated); //Now let's add it to the tag group... tg.AddTag(userTag); } //The processor has a feature that allows them to automatically update the tag group. This //helps to free up your logic and not worry about having to update tag groups that are //enabled or disabled. The argument for this function is the time between updates in //milliseconds. The actual time from the start of one update to the start of another is //dependant on how many tags there are and how much data needs to be transferred. processor.EnableAutoUpdate(500); Console.WriteLine("Press Enter to quit"); Console.ReadLine(); processor.Disconnect(); }
/// <summary> /// Создает новый аргумент события. /// </summary> /// <param name="tag">Текущий тэг.</param> /// <param name="oldDevice">Старое (текущая) задача устройства которое привязано к тэгу.</param> /// <param name="newDevice">Новое задача устройства к которому стоит привязать тэг.</param> public TagTaskEndEditEventArgs(LogixTag tag, LogixTask oldDevice, LogixTask newDevice) { this.Tag = tag; this.OldDevice = oldDevice; this.NewDevice = newDevice; }
/* * HOW TO USE THIS SAMPLE * * 1. First change the hostNameOrIp to the IP address or host name of your PLC * 2. Then change the path to be the path to your PLC, see comments below * 3. Create a user defined type tag in your processor called myUDT1 * 4. Create an ALARM tag in your processor called myAlarm1 * 5. Run * */ static void Main(string[] args) { //First we create the processor object. Typically the path is the slot //number of the processor module in the backplane, but if your communications //card is not in the same chassis as your processor, this is the path through //the chassis to get to your processor. You will have to add a 1 for every //chassis you go through, for example: //Chassis 1: ENBT card in Slot 1 (slot is irrelavent), ControlNet Card in Slot 2 //Chassis 2: L61 in Slot 4 //Path would be: { 2, 1, 4 } //Basically it's the target slot, 1 for backplane, target slot, 1 for backplane... //until you get to the processor. string hostNameOrIp = "192.168.1.10"; byte[] path = new byte[] { 1 }; LogixProcessor processor = new LogixProcessor(hostNameOrIp, path); //The processor has to be connected before you add any tags or tag groups. if (!processor.Connect()) { Console.WriteLine("Could not connect to the processor"); Console.ReadKey(false); return; } Console.WriteLine("6D Systems LLC\n\n"); //First create a group. Groups are much more efficient at reading and writing //large numbers of tags or complex tags like UDTs. LogixTagGroup myGroup = processor.CreateTagGroup("MyGroup"); //Ok, let's create the first tag which is some random user defined type LogixTag genericTag = LogixTagFactory.CreateTag("myUDT1", processor); LogixUDT udtTag = genericTag as LogixUDT; if (udtTag == null) { Console.WriteLine("The tag 'myUDT1' on the processor is not a structure tag"); Console.WriteLine("Press any key to quit"); Console.ReadKey(false); processor.Disconnect(); return; } //Let's print out some information about the UDT PrintStructure(udtTag); //The value of any member can also be set with the tagName[memberName] = value syntax //Now let's get information about the alarm tag that was created... LogixTag genericAlarm = LogixTagFactory.CreateTag("myAlarm1", processor); LogixUDT alarmTag = genericAlarm as LogixUDT; if (alarmTag == null) { Console.WriteLine("The tag 'myAlarm1' is not a structure tag"); Console.WriteLine("Press any key to quit"); Console.ReadKey(false); processor.Disconnect(); return; } //Print out information about it... PrintStructure(alarmTag); //Now, let's set up the tags in the group, set the group to auto update, and watch //for tag update events... myGroup.AddTag(udtTag); myGroup.AddTag(alarmTag); udtTag.TagValueUpdated += new ICommon.TagValueUpdateEventHandler(TagValueUpdated); alarmTag.TagValueUpdated += new ICommon.TagValueUpdateEventHandler(TagValueUpdated); processor.EnableAutoUpdate(500); Console.WriteLine("Press Enter to quit"); Console.ReadLine(); processor.Disconnect(); }
static void WriteStructure(LogixTag tag, LogixProcessor processor) { Console.Write("The tag is a structure called " + ((LogixUDT)tag).TypeName + ", please enter a member name: "); string memberName = Console.ReadLine(); //First we have to find out if the member exists, if it doesn't we can't write to it... List <string> memberNames = ((LogixUDT)tag).MemberNames; bool hasMember = false; for (int i = 0; i < memberNames.Count; i++) { if (string.Compare(memberNames[i], memberName) == 0) { hasMember = true; break; } } if (!hasMember) { Console.WriteLine("The specified member could not be found in the structure"); return; } Console.Write("Enter a value: "); string sValue = Console.ReadLine(); //Now we have to convert it to the right type... try { switch (tag.LogixType) { case LogixTypes.Bool: if (sValue == "1") { ((LogixUDT)tag)[memberName] = true; } else { ((LogixUDT)tag)[memberName] = false; } break; case LogixTypes.DInt: ((LogixUDT)tag)[memberName] = Convert.ToInt32(sValue); break; case LogixTypes.Int: ((LogixUDT)tag)[memberName] = Convert.ToInt16(sValue); break; case LogixTypes.LInt: ((LogixUDT)tag)[memberName] = Convert.ToInt64(sValue); break; case LogixTypes.Real: ((LogixUDT)tag)[memberName] = Convert.ToSingle(sValue); break; case LogixTypes.SInt: ((LogixUDT)tag)[memberName] = Convert.ToSByte(sValue); break; case LogixTypes.User_Defined: default: Console.WriteLine("This demo does not support writing to nested structure tags"); return; } //At this point the tag has not been committed to the processor. The //tag must be written, then read back for the value to change. The //easiest way to do this with a single tag is to use the processor //LogixProcessor.WriteRead() which performs the write, then the //subsequent read on the tag. processor.WriteRead(tag); } catch (Exception e) { Console.WriteLine("Could not convert " + sValue + " to the correct type for " + tag.Address); } }
static void PrintTagValue(LogixTag tag) { //Now we'll determine the value of the tag... switch (tag.LogixType) { case LogixTypes.Bool: Console.WriteLine("BOOL value is: " + ((LogixBOOL)tag).Value.ToString()); break; case LogixTypes.Control: //The control tag is a lot more complicated, there is no way currently to know //which member was updated, so all you can do is say it was updated, we'll print //out one of the members though. Console.WriteLine("Control.POS is: " + ((LogixCONTROL)tag).POS.ToString()); break; case LogixTypes.Counter: //Same as the counter above, we'll just print out the ACC value Console.WriteLine("Counter.ACC value is: " + ((LogixCOUNTER)tag).ACC.ToString()); break; case LogixTypes.DInt: //Print out the value. DINT's are equivalent to int in .NET Console.WriteLine("DINT value is: " + ((LogixDINT)tag).Value.ToString()); break; case LogixTypes.Int: //An INT in a logix processor is more like a short in .NET Console.WriteLine("INT value is: " + ((LogixINT)tag).Value.ToString()); break; case LogixTypes.LInt: //LINT's are equivalent to long in .NET Console.WriteLine("LINT value is: " + ((LogixLINT)tag).Value.ToString()); break; case LogixTypes.Real: //REALs are single precision floats Console.WriteLine("REAL value is: " + ((LogixREAL)tag).Value.ToString()); break; case LogixTypes.SInt: //SINTs are signed bytes Console.WriteLine("SINT value is: " + ((LogixSINT)tag).Value.ToString()); break; case LogixTypes.String: //Strings are just like .NET strings, so notice how we can skip the .StringValue //member, since the .ToString() will automatically be called, which returns the //same value as .StringValue Console.WriteLine("STRING value is: " + ((LogixSTRING)tag)); break; case LogixTypes.Timer: //Timers again are like the CONTROL and COUNTER types Console.WriteLine("Timer.ACC value is: " + ((LogixTIMER)tag).ACC.ToString()); break; case LogixTypes.User_Defined: //The only way to get the value out of a UDT, PDT, or MDT is to define the //structure or know the member name you wish to read. We'll just print that //we know its a UDT, MDT, or PDT that changed. Console.WriteLine("User defined type"); break; default: break; } }
/* ======================================================================================== */ #endregion /// <summary> /// Создает новый элемент привязки области памяти возвращаемой контроллером с тэгом контроллера. /// </summary> /// <param name="id">Идентификатор тэга.</param> /// <param name="tag">Тэг контроллера.</param> /// <param name="parrentTable">Родительская таблица.</param> public CLXCustomTagMemoryItem(UInt16 id, LogixTag tag) { this.ID = id; this.Tag = tag; this.ParrentTable = null; }