Стартовая страница › Форумы › Взаимодействие с устройствами › Modbus › Не удается записать переменную типа real (float)
- В этой теме 44 ответа, 3 участника, последнее обновление 9 лет, 2 месяца назад сделано
manjey73.
-
АвторСообщения
-
04.04.2017 в 13:37 #5083
VitaliyATУчастникСтранно, очень странно… Холдинг регистр пишет одним порядком, а читает другим. При этом 10325476 — раскодирует не верно. Какая последовательность байт должна быть при чтении (и вообще зависит ли от неё что-либо, потому как это уже просто перебор, а не логический подбор — логически это 10325476)? Вот тут:
04.04.2017 в 14:34 #5084
VitaliyATУчастникТут уже 2 темы параллельно пошло, одна как оно работает без формулы и потом как работает формула:
Начнём с того как оно работает без формулы:
1. Требуется отправить значение …
123,456
2. В прибор необходимо записать байты … с помощью функции Модбас …
Просто — да. )) ибо какие байты, кроме как соответствующие — не знаю. И да — по МодБАС.
3. На данный момент выполнены следующие настройки …
Создан канал для чтения холдинг регистра, при этом на скрине показан сразу порядок байт, но и без него результат примерно такой же:

Создан канал для записи холдинг регистра

настроенны таблицы и переданы в веб-морду:

отправляю с неё значение (на тёмном воне можно наблюдать мильёнымильярдов — это если не трогать порядок чтения байт):

ПЛК получает значение и верно расшифровывает его в пордке байт 10325476

А коммуникатор видит 0:

4. В прибор отправляется …
123,456
5. Проблема заключается в следующем: …
СКАДА-коммуникатор неверно читает Дабл переменные записанные самой СКАДОЙ.04.04.2017 в 14:38 #5087
manjey73УчастникЕсть там настройки, запись одного регистра = 2 байта.
Запись множественного количества 2 байта * количество регистров. Поставите 2, отправится 4 байта.Формула с перестановкой от Михаила похоже вообще не фурычит, я продвинул два байта по всему массиву, передача всегда 0
-
Ответ изменён 9 лет, 2 месяца назад пользователем
manjey73.
04.04.2017 в 14:55 #5088
VitaliyATУчастникmanjey73, мы про это говорим?:

Если да то при 4х приходит:

А при 2х (как на скрине выше):

Можно констатировать что если речь об этом, то просто снижение с 4 до 2х байт даёт ошибку, так как просто приходит 2 байта, а не перевод Double в Float и последующая его отправка. Может как-то с помощью формул можно в начале перегнать Double в Float , затем запихнуть его в 2 первых байта и отправить? Решит ли это вопрос чтения СКАДА-коммуникатором или породит ещё кучку вопросов?04.04.2017 в 15:00 #5092
manjey73УчастникКак я отправляю float в Овен я писал выше, проверено на ПЛК63 и ПР200.
А фот формула Михаила у меня не взлетает почему-то.Да, про это, при чем если выбрать запись одного регистра (команда 0х06) то вообще ничего переставлять не надо, Стандартная команда отправляет все корректно.
-
Ответ изменён 9 лет, 2 месяца назад пользователем
manjey73.
04.04.2017 в 15:26 #5094
manjey73УчастникЧто-то не лады какие-то.
Например если записать не (ushort)Cmd аConvert.ToUint16(Cmd) то получим ошибку компилирования формул.
Ошибка при компилировании исходного кода формул:
Строка 658, колонка 22: error CS0117: «System.Convert» не содержит определение для «ToUint16»Такая же ошибка, если сделать переменную uint и сделать конверт ToUint32
Но если сделать переменную float и написать Convert.ToSingle(Cmd) то ошибки нет, все компилируется.Это как так ?
04.04.2017 в 16:25 #5096
VitaliyATУчастникДля себя нашёл промежуточное [РЕШЕНИЕ] по приёму-передачи float (он же REAL = 32bit). Для меня это даже лучше, так как и планировалось работать Float переменными (требование заказчика ибо).
НО! На будущее: Вопрос передачи-приёма Double (он же LREAL в ПЛК BnR = 64bit) остаётся не решённым.
1) Заносим формулу от manjey73 в формулы (немного её изменив по части порядка присвоения). Главное нам из неё получить упаковку Double в Float:

public double fRevers (int rev) { float q = Convert.ToSingle(CmdVal); byte[] f = new byte[4]; byte[] o = new byte[4]; f = BitConverter.GetBytes(q); Array.Copy(f,0,o,0,4); if (rev == 1234) { Array.Copy(f, 0, o, 0, 1); Array.Copy(f, 1, o, 1, 1); Array.Copy(f, 2, o, 2, 1); Array.Copy(f, 3, o, 3, 1); } Array.Resize(ref o, 8); Double ou = BitConverter.ToDouble(o,0); return ou; }2) Затем её вызываем в канале УПРАВЛЕНИЯ (а не входном), вот так:

3) В СКАДА-коммуникаторе настраиваем канал управления так. Главное чтоб «кол-во элементов быоло 2»:

4) А входящий канал так. Главное что float и порядок 3210 (его если менять, то в паре с формулой из п.1):

5) Далее, дополнительные действия: в ПЛК организовать расшифровку пары байт как Float. На ST в среде B+R Automation Studio это выглядит так:FUNCTION MBT2Real brsmemcpy((pReal+0), (pMBT+1), 1); brsmemcpy((pReal+1), (pMBT+2), 1); brsmemcpy((pReal+2), (pMBT+3), 1); brsmemcpy((pReal+3), (pMBT+4), 1); MBT2Real := 0; RETURN; END_FUNCTIONГде: pReal — это адрес элемента массива Real (Float) чисел, с которым потом работать логике ПЛК; pMBT — массив МодБАСа куда СКАДА скидывает значение (соответственно это Holding Registers).
04.04.2017 в 16:55 #5099
manjey73УчастникНу формулу перестановки я и применял для каналов управления а не входных.
Мне непонятно, почему формула Михаила вроде как работает в VS и не работает нифига в SCADA ??
04.04.2017 в 21:36 #5100
VitaliyATУчастникзато я её пихал во входные — для себя пометку оставил ))) Вот про формулу Михаила ничего не скажу пока. Это вообще какой язык? С?
04.04.2017 в 23:10 #5101
manjey73УчастникC#, на котором сама SCADA и писана.
05.04.2017 в 09:31 #5102
MikhailМодераторConvert.ToUint16(Cmd) то получим ошибку компилирования формул.
Ошибка при компилировании исходного кода формул:
Строка 658, колонка 22: error CS0117: «System.Convert» не содержит определение для «ToUint16»Проверяйте регистр символов.
05.04.2017 в 09:38 #5103
MikhailМодератор2. В прибор необходимо записать байты … с помощью функции Модбас …
Просто — да. )) ибо какие байты, кроме как соответствующие — не знаю. И да — по МодБАС.Имелось ввиду, сколько регистров (сколько байт) надо записать в прибор? Записать в каком формате, с плавающей точкой или как целое число?
Какой номер функции Модбас для записи согласно документации на прибор?4. В прибор отправляется …
123,456Скопируйте отправляемые данные из журнала работы линии связи.
5. Проблема заключается в следующем: …
СКАДА-коммуникатор неверно читает Дабл переменные записанные самой СКАДОЙ.Нужно скопировать принимаемые данные из журнала работы линии связи и указать, какое корректное значение Вы ожидаете.
Уточните, проблема с отправкой команды или со считыванием значения тега?P.S. Обычно решение подобных проблем требует нескольких часов времени при удалённом подключении к клиенту. Время решения проблемы — основное отличие платной поддержки от бесплатной.
05.04.2017 в 10:43 #5107
manjey73УчастникБлин, действительно, правильно UInt (I тоже заглавная)…
В любом случае предложенная вами формула для ushort почему-то не работает.
я bit[0] и bit[1] по всему массиву подвигал, все равно запись идет нуля…
без формулы у меня пишется 5100 (51 градус) и уже в ПЛК переводится как мне надо, отображаю как D.DD с двумя знаками после запятой.
Если просто писать 51, то получу 0,51.Если использовать формулу, то всегда почему-то 0 как бы я не двигал байты.
05.04.2017 в 20:24 #5108
MikhailМодераторФормулы на форуме я не тестирую, но довольно странно, что передаются нули при любой перестановке. А Вы не пробовали явно прописать в неё значения байт?
return BitConverter.ToDouble(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }, 0);05.04.2017 в 22:46 #5109
manjey73УчастникЗаработала, возможно что-то не перезагрузил.
Выйду из отпуска, проверю на флоатах. -
Ответ изменён 9 лет, 2 месяца назад пользователем
-
АвторСообщения
- Для ответа в этой теме необходимо авторизоваться.