Сцепить каналы в строку

Просмотр 15 сообщений - с 46 по 60 (из 76 всего)
  • Автор
    Сообщения
  • #38547
    Mikhail
    Модератор

    В драйвере Modbus можно попробовать поставить тип элемента long (8 байт). Тогда при автоматическом создании каналов создастся канал типа Integer (8 байт). То есть в один канал получится поместить больше символов. Но это нужно пробовать, возможно, я ошибаюсь.

    #38559
    petuhovdmitry
    Участник

    Например — идентификатор линии:

    Request element group «holdregs_21000+5»
    Send (12): 02 EF 00 00 00 06 01 03 52 08 00 05
    Receive (7/7): 02 EF 00 00 00 0D 01
    Receive (12/12): 03 0A 45 54 54 53 53 2D 41 54 44 4E
    OK

    https://ncloud.interra.company/s/pGyYgdfD7853FZx

    Разберем привер, далее — попробую провести аналогии.

    #38561
    manjey73
    Участник

    Если регистры идут подряд и там всегда ASCII. Немножко универсальная формула. Для создания строки Версии не подойдет, но думаю смысл будет понятен.
    Тут применяются циклы, как раз из расчета что набор регистров представляют из себя Ascii символы.

    public string GetRegAscii(int ftNum, int quant, int paramlen = 2)
    {
    string outStr = "";
    List<string> lStr = new List<string>();
    for (int i=0; i<quant; i++)
    {
    var str = "";
    if (paramlen == 2)
    {
    ushort us = Convert.ToUInt16(Val(ftNum + i));
    byte[] buf = BitConverter.GetBytes(us);
    str = Encoding.ASCII.GetString(buf).TrimEnd((char)0);
    }
    else if (paramlen == 4)
    {
    uint ui = Convert.ToUInt32(Val(ftNum + i));
    byte[] buf = BitConverter.GetBytes(ui);
    str = Encoding.ASCII.GetString(buf).TrimEnd((char)0);
    }
    else if (paramlen == 8)
    {
    ulong ul = Convert.ToUInt64(Val(ftNum + i));
    byte[] buf = BitConverter.GetBytes(ul);
    str = Encoding.ASCII.GetString(buf).TrimEnd((char)0);
    }
    lStr.Add(str);
    } 
    if (lStr.Count > 0)
    {
    for (int x = 0; x < lStr.Count; x++)
    {
    outStr = outStr + lStr[x];
    }
    }
    return outStr;
    } 

    Настройка канала
    Результат

    При необходимости перестановка байт настройках шаблона Modbus. Тут не заморачивался.

    #38562
    manjey73
    Участник

    Да, чтобы в формулах не заморачиваться с нарезкой по 8 байт, раскладывания по массиву кусков строк, используется штатная формула SplitAscii

    SplitAscii(()=> GetRegAscii(300, 5))

    Здесь первый параметр в GetRegAscii указывает на 1-й номер канала, с которого надо проводить обработку.
    5 — количество каналов для обработки
    2 (по умолчанию можно не указывать) что берем по 2 байта SplitAscii(()=> GetRegAscii(300, 5, 2))
    Соответственно можно указать 4 и 8 если в шаблоне указываете чтение в uint или в ulong

    #38563
    manjey73
    Участник

    Вместо последнего цикла можно упростить.

    if (lStr.Count > 0)
    {
    outStr = string.Join("", lStr.ToArray());
    }
    #38592
    Mikhail
    Модератор

    Для расчётного канала с типом данных ASCII string и длиной > 1 попробуйте такую простую формулу:
    Data(101 + ArrIdx)
    Где 101 — это номер канала, который хранит начало строки.

    #38601
    petuhovdmitry
    Участник

    Data(101 + ArrIdx)

    Я, правда, пока совсем пока не понимаю, что такое ArrIdx в даннном контексте

    #38603
    manjey73
    Участник

    @petuhovdmitry смотрите документацию по использованию формул, это служебный параметр.

    Михаил, это в какой части для формулы использовать ?

    • Ответ изменён 5 месяцев, 1 неделя назад пользователем manjey73.
    #38605
    petuhovdmitry
    Участник

    ArrIdx int Индекс обрабатываемого элемента массива
    https://rapidscada.net/docs/ru/latest/configuration/scripts

    речь об этом описании?

    #38606
    manjey73
    Участник

    Да, об этом. Есть разные формулы в ядре для чтения, записи и т.д. Типа Val(), SetVal, SetData и так далее

    #38612
    Mikhail
    Модератор

    > Михаил, это в какой части для формулы использовать ?
    Это и есть сама формула.

    #38616
    manjey73
    Участник

    а при чем тут начало строки если у нас регистры из прибора с числовыми значениями, которые еще требуется преобразовать, чтобы это оказалось строкой ?

    #38622
    Mikhail
    Модератор

    В том случае, если в числовых регистрах прибора на самом деле хранятся коды символов ASCII (а такое бывает), то данная простейшая формула сработает. То есть коды символов просто перенесутся в данные канала.

    #38628
    manjey73
    Участник

    Понятно. Кстати это в тему про создание структур в драйвере Modbus.
    Там отсутствует понятие строка, а было бы неплохо в самом драйвере такое добавить, и в каком виде отдавать ASCII или Unicode.

    В добавок к множителям это все поубавило бы формул в каналах Scada.

    Одна из проблем, это когда создаешь мастером каналы. Сперва приходится (вынужден) создать кучу формул, а только потом клонировать каналы на однотипные устройства.
    А потом тебе говорят — «ой, тут не так надо» и начинаешь перелопачивать уже каналы нескольких устройств. Хотя достаточно было бы поправить только шаблон устройства в большинстве случаев.

    • Ответ изменён 5 месяцев, 1 неделя назад пользователем manjey73.
    #38701
    petuhovdmitry
    Участник

    Доброго!
    Собрали GTIN из кусков через Data(XXX + ArrIdx), савсибо!
    https://ncloud.interra.company/s/LYCf3YiT7H9JPMm

Просмотр 15 сообщений - с 46 по 60 (из 76 всего)
  • Для ответа в этой теме необходимо авторизоваться.