Получить несколько значений OPC
Вот код для получения нескольких значений с OPC-сервера.
private void getData()
{
try
{
int count = 1;
opcServer.Connect("OPCTechs.SiemensNet30DA", "");
opcGroup = opcServer.OPCGroups.Add("MP");
opcGroup.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(opcGroup_DataChange);
//Get First String
for (int i = 40; i <= 47; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
//Get Second String
for (int i = 80; i <= 91; i++)
opcGroup.OPCItems.AddItem("D104.B" + i, count++);
opcGroup.OPCItems.DefaultIsActive = true;
opcGroup.UpdateRate = 1000;
opcGroup.IsSubscribed = opcGroup.IsActive;
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Alert");
}
}
private void opcGroup_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
try
{
string temp = "";
int count = 1;
for (count = 1; count <= NumItems; count++)
{
if (Convert.ToInt32(ClientHandles.GetValue(count)) == 47)
temp += ItemValues.GetValue(count).ToString();
}
Textbox1.Text = temp.ToString();
temp = "";
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Alert");
}
}
Как вы можете видеть в коде, я пытаюсь получить значение if (Convert.ToInt32(ClientHandles.GetValue(count)) == 47)
из ClientHandle
47, но каждый раз вместо этого я получаю другие значения. Когда я напечатал все значения, я увидел, значение на 47
приходил в случайных местах. Я не понимаю, почему это происходит случайно?
Значение в месте 47 должно прийти только на это место. Это хороший способ получить несколько значений с сервера OPC?
1 ответ
Так работает OPC. Вы указываете дескриптор клиента для каждого элемента, на который вы подписаны. Всякий раз, когда на сервере появляются новые данные для некоторых элементов, вы получаете уведомление с одним или несколькими элементами. Поскольку невозможно предсказать, когда какие данные изменятся, также нельзя указать, какие элементы будут содержаться в уведомлении и какой порядок.
Вам необходимо просмотреть все элементы, содержащиеся в уведомлении, и на основе их дескрипторов клиента решить, что делать с каждым из них. Порядок может меняться каждый раз, но это не проблема: допустим, вы ищете клиентский дескриптор 47. В первом уведомлении вы найдете его в ClientHandles с индексом 10; во втором уведомлении его может вообще не быть; в третьем уведомлении оно может быть с индексом 15. Вы просто определяете позицию, а затем вы находите данные для этого в той же позиции в других массивах: то есть для первого уведомления, с индексом 10 в массивах ItemValues, Качества и метки времени; и для третьего уведомления - по индексу 15 в тех же массивах.