Объединение тегов внутри драйвера

Стартовая страница Форумы Разработка и интеграция Объединение тегов внутри драйвера

Просмотр 5 сообщений - с 1 по 5 (из 5 всего)
  • Автор
    Сообщения
  • #13289
    manjey73
    Участник

    Устройство свободно программируемый контроллер. Одним запросом проводится опрос пачки переменных. В одном запросе переменные имеют один тип, в данном случае integer (Int16). По усмотрению программиста это может быть например Температура с требуемым множителем
    | 11 | Temperature | -4,700 | |

    А может быть набор из двух переменных
    +———+————————————+————-+——-+
    | 3 | Config Word #1 | 6 828,000 | |
    +———+————————————+————-+——-+
    | 4 | Config Word #2 | 5,000 | |
    +———+————————————+————-+——-+

    | 7 | Alarm Word #1 | 16 896,000 | |
    +———+————————————+————-+——-+
    | 8 | Alarm Word #2 | 0,000 | |
    +———+————————————+————-+——-+
    | 9 | Status Word #1 | 256,000 | |
    +———+————————————+————-+——-+
    | 10 | Status Word #2 | 18 688,000 | |

    то есть переменные DWORD запихнутая в две последовательных переменных Int16.
    Как бы так красиво запихнуть две переменных в одну полноценную, раз уж в Scada все переменные double и в списке тегов их сделать с номерами сигналов 3, 7, 9 (пропустив 4, 8, 10) ???
    При этом чтобы не пострадали индексы тегов !!!!

    Как это можно реализовать на этапе формирования тегов, например добавив в конфиг доп параметр ? Конфиг выглядит так.
    <Vals Signal=»3″ Active=»true» ValName=»Config Word #1″ Range=»1″ Value=»6828″ />
    <Vals Signal=»4″ Active=»true» ValName=»Config Word #2″ Range=»1″ Value=»5″ />

    объединить на этапе чтения буфера я не могу. Например идет запрос 58 байт, что соответствует 29 переменным Int16, но так как устройство ПЛК, то объединить можно только потом. Понятно, что это можно выполнить в самой Scada, но это потеря одного канала, даже двух, так как надо будет сделать промежуточный и т.д. К тому же, я могу из этой всей пачки деактивировать переменные, чтобы они вообще не попадали в Scada. Например по причине что выполнить групповой запрос удобнее, чем раздельное чтение.

    Сейчас формирование тегов происходит строго по полям активных Vals

    вот как можно реализовать идею на лету, не прибегая к дополнительным шаманствам. Например добавив в конфиг по аналогии параметра Active ну например Split…

    з.ы. вот опять всплывает нюанс неудобства работы с индексами тега на уровне Коммуникатора 🙁 опять что-то мудрить приходится.

    • Эта тема была изменена 4 года, 8 месяцев назад от manjey73.
    #13293
    Mikhail
    Модератор

    Если я правильно понял, нужно объединить 2 тега Int16
    Config Word #1
    Config Word #2
    в один тег Int32.

    Это можно сделать в коде драйвера примерно так:

    Int16 val1 = 1;
    Int16 val2 = 2;
    Int32 tagInt = (val1 << 16) + val2;
    double tagDbl = (double)tagInt;
    #13294
    Mikhail
    Модератор

    Пропустить номера сигналов вполне можно при инициализации тегов в драйвере. Вы можете создать тег с любым сигналом.

    #13299
    manjey73
    Участник

    Сейчас у меня так

    if(devTemplate.ValGroups[vgID].Vals[vID].Active)
    {
    
    tagGroup.KPTags.Add(new KPTag(devTemplate.ValGroups[vgID].Vals[vID].Signal, devTemplate.ValGroups[vgID].Vals[vID].ValName));  // Заносим в тег Коммуникатора
    if (!SigTag.ContainsKey(devTemplate.ValGroups[vgID].Vals[vID].Signal))   // Ключ = # Сигнала - Значение = Индекс тега
    {
    SigTag.Add(devTemplate.ValGroups[vgID].Vals[vID].Signal, cntTag); // Должен быть счетчик индексов тегов
    }
    cntTag++; // Добавить счетчик тегов и создать словарь соотношений
    }
    

    В словарь заношу номер сигнала и индекс тега по счетчику cntTag.
    То есть тег для Коммуникатора формируется.

    При передаче в Сервер код такой. Сперва по 2 байта закидываются и буфера в значения

    devTemplate.ValGroups[idCnt].Vals[idVal].Value = val;
    idVal++;

    То есть как бы прозрачный режим для драйвера, сделал я активной переменной или нет, пачка то вся прилетает. А уже потом

    for (int c = 0; c < devTemplate.ValGroups[idCnt].Vals.Count; c++)
    {
    if (devTemplate.ValGroups[idCnt].Vals[c].Active)
    {
    int tagidx = SigTag[devTemplate.ValGroups[idCnt].Vals[c].Signal];
    SetCurData(tagidx, devTemplate.ValGroups[idCnt].Vals[c].Value * devTemplate.ValGroups[idCnt].Vals[c].Range, 1);
    }
    }
    

    Проверяю, активировал ли я переменную для сервера и выдаю серверу

    И получается как на этапе формирования тегов объединить в DWORD, при этом изменить индексирование тегов, и как при опросе выполнить ту же процедуру…

    • Этот ответ был изменен 4 года, 8 месяцев назад от manjey73.
    • Этот ответ был изменен 4 года, 8 месяцев назад от manjey73.
    #13308
    manjey73
    Участник

    Спасибо за пример, решил задачку как при создании тегов, так и при чтении…

    Номера сигналов у меня и так можно редактировать. По умолчанию драйвер делает их последовательными при создании файла, создает имена по шаблону и просит перезагрузку.
    Но так как ПЛК свободно программируемый, потом требуется их обозвать как задумано программистом, изменить множитель, если это требуется и перегрузить.

    Вроде работает. Объединение word в dword просто бонус..

Просмотр 5 сообщений - с 1 по 5 (из 5 всего)
  • Вы должны авторизироваться для ответа в этой теме.