Остановка опроса по массиву байт или байту

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

Просмотр 15 сообщений - с 31 по 45 (из 50 всего)
  • Автор
    Сообщения
  • #13925
    manjey73
    Участник

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

                    readCnt = Connection.Read(buffer, 0, MaxRxDLen, ReqParams.Timeout,
                        testStop, out stopReceived, CommUtils.ProtocolLogFormats.String, out logText); // EtxStopCond
    
    

    Ругается «Аргумент 5: не удается преобразовать из «Scada.Comm.Devices.KpM61107Logic.MyStopCond.MyStop» в «Scada.Comm.Channels.Connection.BinStopCondition»

    Получается как то и чтение надо переделывать, а это уже фигня будет, под каждый чих создавать свои функции чтения и для Serial и для TCP, UDP

    Либо через встроенный класс передавать нельзя, хз…

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

    Не работает ваш код, попробовал иначе.

            private class MyStopCondition : Connection.BinStopCondition // TEST логики остановки по двум массивам
            {
                public MyStopCondition(byte[] stop0) : base(stop0)
                {
                }
    
                public MyStopCondition(byte[] stop0, byte[] stop1) : base(stop0)
                {
                }
    
                public byte[] Stop0 { get; protected set; }
                public byte[] Stop1 { get; protected set; }
    
                public override bool CheckCondition(byte[] buffer, int index)
                {
                   bool checkCond = false;
                    for (int d = 0; d < 2; d++)
                    {
                        if (d == 0)
                        {
                            StopSeq = Stop0;
                            //MyStopCondition tt = new MyStopCondition(Stop0);
    и так пробовал - ни шиша
                            checkCond = base.CheckCondition(buffer, index);
                        }
                        else if (d == 1)
                        {
                            StopSeq = Stop1;
                           //MyStopCondition tt = new MyStopCondition(Stop1);
                            checkCond = base.CheckCondition(buffer, index);
                        }
                    }
                    return checkCond;
                }
            }
    
            MyStopCondition testStop = new MyStopCondition(new byte[] { 0x0D, 0x0A }, new byte[] { 0x03 });
    

    Срабатывает только по тому коду, который укажу тут внутри в base(stop0 или stop1)

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

    Хотя не так, в общем оно не работает и связано это кажется частично с родительским объектом.

    Потому что надо передать в него StopSeq а их два и оба разные, в том числе и по длине.

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

    В общем для начала этот :base(переменная) все портит.

    Если выбрать stop1 но перед вызовом написать StopSeq = Stop0 то ни сработает ни одно из условий. Я уже упростил код до одного вызова для проверки…
    И наоборот, указываем :base(stop0) а потом StopSeq = Stop1 то же не будет совпадений.

    в итоге можно убрать StopSeq = чего-то и будет искать то, что прописано в :base(что тут)

    #13932
    manjey73
    Участник

    И опять нет…. наличие StopSeq = StopX приводит к тому, что там нули и поиск останавливается…

    только если удалить то ищет по :base(stopX)

    получается не выходит у меня массивы байт передать, там пустота…

    Еще одна проблема, надо после остановки проверять предыдущий байт, предшествующий массиву остановки. Только сейчас это осознал… например у меня остановка по 0x10, 0x03 но так как числа в блоке данных являются Int16 то и в блоке данных возможна такая комбинация. Нужно проверить предшествующий байт и в случае определенного значения (у меня это так же 0x10) продолжить чтение то следующей пары остановки 0х10, 0х03

    з.ы. в общем механизм останова надо как-то дорабатывать, раз в своем методе или классе не выходит выполнять таких извратных проверок…

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

    Ругается «Аргумент 5: не удается преобразовать из

    Скорее всего был вариант без наследования класса.

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

    #13935
    manjey73
    Участник

    Если можно, нужно как то точно понять, передались массивы в родительский класс или нет. Без base точно ошибка, я добавлял в BinStopCondition пустой конструктор, тогда можно без base сделать, но там явно что то ещё требуется. Либо что то ещё блокирует передачу данных в родительский класс.
    И ещё, Connection.Read то сам примет подчинённый класс? Он то все равно принимает именно Connection.BinStopCondition а не мой MyStopCondition ? А там он не может преобразовать несколько входных переменных и так же наверное требует base…
    В общем непонятно где затык происходит….

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

    1. Скомпилировать драйвер в конфигурации Debug
    2. Скинуть DLL в папку Коммуникатора
    3. Запустить службу Коммуникатора
    4. В VS выбрать Debug — Attach to Process, затем выбрать процесс ScadaCommSvc.exe
    5. Можно поставить точку останова, кликнув мышкой на левом поле на нужной строке. Дебаггер должен остановиться на этой точке останова.
    6. Кнопка F10 выполняет один оператор без захода внутрь метода. F11 выполняет один оператор с заходом внутрь метода.

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

    Чтобы выполнять отладку, исходный код должен компилироваться.

    #13944
    manjey73
    Участник

    Вы лучше код понимаете, как будет работать Connection.Read, если туда передать 2 массива байт при помощи MyStopCondition : Connection.BinStopCondition

    А то мне сдается толку сейчас от попыток что-то замутить в дочернем классе никакого…

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

    Выложите куда-нибудь Ваш готовый класс целиком. Иначе нет однозначного понимания, какой вариант кода мы обсуждаем.

    #13949
    manjey73
    Участник
            public class MyStopCondition : Connection.BinStopCondition // TEST логики остановки по двум массивам
            {
                public MyStopCondition(byte[] stop0, byte[] stop1) : base(stop0)
                {
                }
    
                public byte[] Stop0 { get; protected set; }
                public byte[] Stop1 { get; protected set; }
    
                public override bool CheckCondition(byte[] buffer, int index)
                {
                    bool checkCond = false;
    
                    //StopSeq = Stop0;
                    //StopSeq = Stop1;
    
                    checkCond = base.CheckCondition(buffer, index);
                    return checkCond;
               }
            }
    

    лог при работе
    Отправка (5): /?!<0D><0A>
    Test Stop = True === — — 0D0A
    Приём (12): /Els6EK270<0D><0A>
    Отправка (6): <06>061<0D><0A>
    Test Stop = False === — — 0D0A
    Приём (15): <01>P0<02>(1234567)<03>P
    Отправка (5): <01>B0<03>q

    между — должны быть значения переданных массивов

    
    MyStopCondition testStop = new MyStopCondition(new byte[] { 0x0D, 0x0A }, new byte[] { 0x03, 0x50 });
    string fgfg = string.Concat(ScadaUtils.BytesToHex(testStop.Stop0), " -- ", ScadaUtils.BytesToHex(testStop.Stop1) + " -- " + ScadaUtils.BytesToHex(testStop.StopSeq));
    
    bool stopReceived;
                    readCnt = Connection.Read(buffer, 0, MaxRxDLen, ReqParams.Timeout,
                        testStop, out stopReceived, CommUtils.ProtocolLogFormats.String, out logText);
    
    WriteToLog("Test Stop = " + Convert.ToString(stopReceived) + "  ===  " + fgfg);

    Но в логах пустота вместо значений. Почему нет доступа для чтения переменных из testStop.Stop0 и Stop1 ?????

    1. без указания :base(переменная) будет ошибка
    2. при base передается только один массив байт и по нему происходит поиск.
    Если передаем stop0 а в коде сделаем StopSeq = Stop1;

    то в логе будет False на обоих массивах.
    Пробовал сделать внутри еще класс для передачи двух массивов в переменные Stop0 и Stop1 без участия base и уже рулить потом, ошибка была уже в Connection.Read — не могу сконвертировать testStop в Connection.BinStopCondition.

    #13950
    manjey73
    Участник

    Так вот судя по логам StopSeq показывает, а новые Stop0 и Stop1 не показывает… Что очень странно.

    Подозреваю, что StopSeq берется из родительского объекта уже, а Stop0 и Stop1 пропадают в небытие по каким-то причинам, потому что они не могут быть сконвертированы в Connection.BinStopCondition при вызове Connection.Read

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

    Так, немного проехало, забыл добавить сами переменные внутрь.

                public MyStopCondition(byte[] stop0, byte[] stop1) : base(stop0)
                {
                    Stop0 = stop0;
                    Stop1 = stop1;
                }
    
                public byte[] Stop0 { get; protected set; }
                public byte[] Stop1 { get; protected set; }
    

    теперь хоть base и указан stop0, но в коде StopSeq = Stop1 и ищет по Stop1
    Теперь вот непонятность с кодом, который вы предлагали…

    В логе мне теперь выводи данные переменных.

    #13953
    manjey73
    Участник

    Ура, вроде заработало по двум массивам. Видимо где-то в прошлый раз напортачил…
    И работает ваш код… надо правда немного будет переделать, чтобы можно было больше 2-х массивов отправлять для проверки…

    • Этот ответ был изменен 4 года, 6 месяцев назад от manjey73.
Просмотр 15 сообщений - с 31 по 45 (из 50 всего)
  • Вы должны авторизироваться для ответа в этой теме.