Чтение строки s7 ПЛК Siemens на C # с помощью S7netplus

У меня проблемы с чтением данных в БД Siemens PLC S7 1500 с помощью S7netplus.

Ситуация:

  • У меня запущено приложение C #.
  • Я очень хорошо подключаюсь к ПЛК.
  • Я могу читать такие данные, как Boolean, UInt, UShot, Bytes

Но я не знаю, как читать данные String (см. Изображение ниже)

Данные ПЛК

Чтобы прочитать другие данные, такие как Boolean, я использую этот вызов:

plc.Read("DB105.DBX0.0")

Я понял, что это чтение в блоке данных 105 (DB105) с логическим типом данных (DBX) со смещением 0,0. Я хотел бы применить тот же тип чтения для строки. Поэтому я попробовал в своем примере "DB105.DBB10.0". Но он возвращает значение «40» в байтовом типе (и у меня должно быть что-то еще).

Увидел, что есть еще один способ чтения

plc.ReadBytes(DataType DB, int DBNumber, int StartByteArray, int lengthToRead)

Но мне трудно понять, как применить это к моему примеру (я знаю, что потом мне нужно преобразовать его в строку).

ДЛЯ резюме: - Есть ли простой способ с помощью строки, подобной «DB105.DBX0.0», для чтения строковых данных в ПЛК Siemens? - Если нет, то как использовать функцию ReadBytes в моем примере?

Спасибо за вашу помощь


person Seb    schedule 02.10.2019    source источник


Ответы (1)


Мне удалось прочитать мое строковое значение методом ReadBytes. В моем примере мне нужно было передать такие значения:

plc.Read(DataType.DataBlock, 105, 12, VarType.String, 40);

Почему 12? Потому что 2 первых октета байтовой строки предназначены для длины. Таким образом, от 10 до 12 возвращают значение 40, которое является длиной.

Я переопределил метод чтения, чтобы принять вызов «простой строки» следующим образом:

    public T Read<T>(object pValue)
            {
                var splitValue = pValue.ToString().Split('.');
                //check if it is a string template (3 separation ., 2 if not)
                if (splitValue.Count() > 3 && splitValue[1].Substring(2, 1) == "S")
                {
                    DataType dType;

                    //If we have to read string in other dataType need development to make here.
                    if (splitValue[0].Substring(0, 2) == "DB")
                        dType = DataType.DataBlock;
                    else
                        throw new Exception("Data Type not supported for string value yet.");

                    int length = Convert.ToInt32(splitValue[3]);
                    int start = Convert.ToInt32(splitValue[1].Substring(3, splitValue[1].Length - 3));
                    int MemoryNumber = Convert.ToInt32(splitValue[0].Substring(2, splitValue[0].Length - 2));

                    // the 2 first bits are for the length of the string. So we have to pass it
                    int startString = start + 2;
                    var value = ReadFull(dType, MemoryNumber, startString, VarType.String, length);
                    return (T)value;
                }
                else
                {
                    var value = plc.Read(pValue.ToString());

                    //Cast with good format.
                    return (T)value;
                }
}

Итак, теперь я могу вызвать свою функцию чтения следующим образом: с помощью существующего базового вызова:

  • var element = mPlc.Read<bool>("DB10.DBX1.4").ToString(); => прочитать в блоке данных 10 логическое значение байта 1 и октета 4
  • var element = mPlc.Read<uint>("DB10.DBD4.0").ToString(); => прочитать в блоке данных 10 значение типа int в байте 4 и октете 0

с переопределенным вызовом для строки:

  • var element = mPlc.Read<string>("DB105.DBS10.0.40").ToString() => прочитать в блоке данных 105 строковое значение в байте 10 и октете 0 длиной 40

Надеюсь, это поможет кому-нибудь еще :)

person Seb    schedule 03.10.2019