PDA

Просмотр полной версии : Многомерный массив в Modbus Соотнесение входов/выходов



MichailG
16.10.2024, 08:21
Здравствуйте! Есть двумерный массив X[0..5, 0..50] of real_; real_ - это структура Real_Word. Пытаюсь 1-й элемент массива соотнести со входом - пишу X[0]. Выдает ошибку "C0048: Для массива требуется ровно 2 индексов". Я ожидал, что по старшему разряду 0-го элемента будут прочтены элементы 0..50, когда использую одномерный массив, все работает нормально. Подскажите пожалуйста, как обойти это? Пока вижу программный способ реализации обмена. Спасибо!

Валенок
16.10.2024, 08:54
array[0..5] of array[0..50] of..
тогда подтип вычленяется явно если нужно присвоить целиком 51 элемент real_

вангую
а нахрен real_ из вордов а не просто real?
union с real и dword решит проблему перестановки регистров
или pointer to dword натянутый на real

MichailG
16.10.2024, 09:24
Попробовал [0][0] писать, выдает это:
[ERROR] СПК110 П23: C0032: Невозможно конвертировать тип 'Неизвестный тип: 'ADR(PLC_PRG.RTP2A_FInp[0][0])'' в тип 'POINTER TO BYTE'
[ERROR] СПК110 П23: C0077: Неизвестный тип: 'PLC_PRG.RTP2A_FInp[0][0]'
[ERROR] СПК110 П23: C0048: Для массива требуется ровно 2 индексов
[ERROR] СПК110 П23: C0047: Невозможно применить индексацию с [] к выражению типа 'real_'
[ERROR] СПК110 П23: RTP2A_RV2A [Device: RS485_1: Modbus_Master_COM_Port]: C0077: Неизвестный тип: 'PLC_PRG.RTP2A_FInp[0][0]'
Так мне то нужен не конкретный элемент младшего разряда, а целиком "столбец".
Регистры я не переставляю, просто тип word должен быть в соотнесении входов, вот я и преобразую его.
TYPE real_ :
UNION
RealVal:REAL;
modbusReal:ARRAY[0..1] OF WORD;
END_UNION
END_TYPE

МихаилГл
16.10.2024, 09:36
X[0, 0].modbusReal[0]

MichailG
16.10.2024, 09:53
А что мне это даст, мне целиком X[0] прочесть нужно. Извлекать modbusReal[0] не нужно. Так то работает с одномерным массивом, когда пишу просто X.

МихаилГл
16.10.2024, 09:59
А что мне это даст, мне целиком X[0] прочесть нужно. Извлекать modbusReal[0] не нужно. Так то работает с одномерным массивом, когда пишу просто X.

Вам нужно word со входом соотнести, или что то иное?

PS Ваш массив не массив одного типа, там 3 переменные. Я даже не пойму как вы входу word, например, пытаетесь присвоить 3 переменные

MichailG
16.10.2024, 10:19
Ну если конкретно, то вот так у меня организовано (рабочий вариант):
RTP2A_FInp:ARRAY[0..GVL.RTP2APerems] OF real_; - объявление в PLC_PRG
RTP2APerems:INT:=26; - в GVL VAR_GLOBAL CONSTANT
Application.PLC_PRG.RTP2A_FInp - Соотнесение входов/выходов Modbus Slave.
тип real_ описан выше - это union из Real и Word.
Работает все нормально, но когда пишу
RTP2A_FInp:ARRAY[0..5, 0..GVL.RTP2APerems] OF real_; - объявление в PLC_PRG
и везде в коде соответственно, а в Соотнесение входов/выходов Modbus Slave пишу
Application.PLC_PRG.RTP2A_FInp[0]
компилятор ругается...

MichailG
16.10.2024, 10:26
В рабочем варианте я соотносил массив из real_. Функция Read Holding Registers. По примерам делал, тип real объединял в 2 word и работало. А тут я захотел несколько одномерных массивов объединить в 2-мерный и думал с указанием индекса будет записываться нужный массив данных...

kondor3000
16.10.2024, 10:28
RTP2A_FInp:ARRAY[0..5, 0..GVL.RTP2APerems] OF real_; - объявление в PLC_PRG
и везде в коде соответственно, а в Соотнесение входов/выходов Modbus Slave пишу
Application.PLC_PRG.RTP2A_FInp[0]
компилятор ругается...
Зачем вы в соотнесении пытаетесь каждый вход присвоить ?

Просто укажите адрес в объявлении AT%IW0 какой там у вас адрес
RTP2A_FInp AT%IW0 :ARRAY[0..GVL.RTP2APerems] OF real_;

МихаилГл
16.10.2024, 10:32
Ваш рабочий вариант при этом работает только до 49 элемента массива? Т.е. на 50 % (ну или по другому - не работает)... У меня например так это работает...79438

MichailG
16.10.2024, 10:44
Работает нормально вот скрины.
79439
79440
79441
Переменных 27 шт, все отображаются корректно

MichailG
16.10.2024, 10:49
каждый элемент я не заполнял, просто в канал FloatInp в корневом элементе я указал массив и все

МихаилГл
16.10.2024, 10:52
каждый элемент я не заполнял, просто в канал FloatInp в корневом элементе я указал массив и все

Это я понял. Только у вас в переменных, например, 26 значений, следовательно 52 ворда, и во входах как минимум должно быть уже массив из 52 входов.
Я бы сделал так и не мучился:
79442

Валенок
16.10.2024, 11:00
Регистры я не переставляю,..
накой тогда ворды а не просто real



Так мне то нужен не конкретный элемент младшего разряда, а целиком "столбец".
(cds2, но в 3 тоже самое, at% - сами)

МихаилГл
16.10.2024, 11:06
накой тогда ворды а не просто real...

Ну ТС же в модбас это пересылает, потому и ворды. Но то что к массиву регистров из 100 элементов соотносится массив из другого количества элементов... Думаю это может закончиться плачевно... Хотя ХЗ.

MichailG
16.10.2024, 11:10
26 значений, 52 ворда. Сначала я создал объединение из 1 real и 2 word. Потом посчитал кол-во регистров, и записал константу в GVL, потом объявил массив, указав размер из константы, потом этот массив указал в соотнесении входов/выходов.
79444
79445

Валенок
16.10.2024, 11:11
Ну ТС же в модбас это пересылает, потому и ворды..
модбас регистры пересылает а не ворды. А что в регистрах лежит - пофиг


Но то что к массиву регистров из 100 элементов соотносится массив из другого количества элементов....
где?

Валенок
16.10.2024, 11:14
Сначала я создал объединение из 1 real и 2 word.
Аффтар! см п#14, строка 1..

МихаилГл
16.10.2024, 11:15
26 значений, 52 ворда. Сначала я создал объединение из 1 real и 2 word. Потом посчитал кол-во регистров, и записал константу в GVL, потом объявил массив, указав размер из константы, потом этот массив указал в соотнесении входов/выходов.
79444
79445

Да это понятно. Только во входах у вас массив [0..53] и вы его соотносите с массивом [0..26].
Через пол года начнете вспоминать, почему это так, и не вспомните... Зачем себя путать.

Помню на роквеле был такой момент, массив в программе одной размерности, в скаде другой. До 2016 года все работало. А потом накатили обновление, и система встала колом, потому что этот "косяк" в обновлении спустя 10 лет наконец убрали.
Придется вам переделывать это на новый контроллер и столкнетесь с такой проблемой... Так не лучше ли сразу правильно сделать.

МихаилГл
16.10.2024, 11:18
...

где?

7 и 11 посты. В переменных объявлено константой 26+1 переменных (ну и размерность массива), в модбас соотнесениях в настройках 54 холдинг регистра.

Когда-нибудь это встанет боком.

Валенок
16.10.2024, 11:30
Помню на роквеле был такой момент...
Я не помню. В новостях показывали?


массив в программе одной размерности,
Слейв? (N1)

в скаде другой.
Мастер (N2)

N1 > N2 скада работата норм и о [N2+1..N1] просто ничего не знала
N1 < N2 если скада обращалась к [N1+1...] то:
- illegal address
- левые данные, если область слейва еще что-то имела за массивом.


.. спустя 10 лет наконец убрали
Если области данных обмена проверяются через sizeof в онлайн при первом пуске - то на первом пуске всё и выявляется.
10лет - профи, чо

MichailG
16.10.2024, 11:31
МихаилГл, понятно, вы бы заполнили массив из word по циклу, как в #13, размер этого массива совпадал бы с каналом modbus и вопросов не возникло, правильно я понял? Ну я надеюсь, что разработчики codesys не сделают таких изменений в работе union и др...

Валенок
16.10.2024, 11:38
Когда-нибудь это встанет боком.
определяется в 1 пуске (см. выше).



В переменных объявлено константой 26+1 переменных (ну и размерность массива), в модбас соотнесениях в настройках 54 холдинг регистра.
CDS3 не дает возможность вычислять константу используя другую константу?
CDS3 не дает разместить по адресу %at сразу real, да накой эти регистры-то вам уперлись?

MichailG
16.10.2024, 11:39
накой тогда ворды а не просто real


(cds2, но в 3 тоже самое, at% - сами)

адрес at %, нужно будет вручную считать адрес каждого старшего разряда, начала данных так сказать. Как это будет работать ещё? Компилятор не будет снова ругаться, если объявлю этот RTP2A_FInp[0..5... а в адресе как указывать надо будет? Может выложить 2 проекта - рабочий и не рабочий, вы покажете?

МихаилГл
16.10.2024, 11:40
10лет - профи, чо...
Этот косяк был в утилите FTTM, не модбас, но работа именно с массивами... Я это для примера указал.
Там даже интеграторы поседели, когда этот косяк увидели и начали звонить на объекты чтоб роллап апдейты не накатывали, пока размерность не поправят. Колом конечно вставала только отчетность, все остальное работало.

МихаилГл
16.10.2024, 11:45
CDS3 не дает разместить по адресу %at сразу real, да накой эти регистры-то вам уперлись?

https://owen.ru/forum/showthread.php?t=40356&page=2&p=448413&viewfull=1#post448413

Скрин 1. В версии кодесиса 3 это так выглядит, может и можно как то реал прикрутить, но я не изучал этот вопрос. Там в настройках пишешь количество регистров и он сразу формирует на этой вкладке массив вордов...

Валенок
16.10.2024, 11:46
Этот косяк был в утилите FTTM, не модбас, но работа именно с массивами...
Проверка размеров структур после их разработки - это как руки вымыть после туалета.

Я это для примера указал.
тоже для примера указал - как

Валенок
16.10.2024, 11:50
Скрин 1. В версии кодесиса 3 это так выглядит, может и можно как то реал прикрутить, но я не изучал этот вопрос....
Может изучить? А то какое-то маниакальное желание какие-то ворды-шморды пихать в область обмена, хотя дальше нужны реалы
Или аффтор не читатель а писатель?

MichailG
16.10.2024, 11:51
Проще наверно мне будет создать столько массивов "Регулятор"_FInp:ARRAY[0..GVL."Регулятор"Perems] OF real_; и конфигурировать канал каждого слейв устройства, все равно конфигурировать придется, хоть индекс массива менять приходилось бы, но все равно это делать нужно. Другое дело, если бы я программно обмен данными реализовывал, тогда можно было бы проще сделать...

МихаилГл
16.10.2024, 11:57
Может изучить? А то какое-то маниакальное желание какие-то ворды-шморды пихать в область обмена, хотя дальше нужны реалы
Или аффтор не читатель а писатель?

Дайте направление, я готов прочитать...

Валенок
16.10.2024, 11:57
Дайте направление, я готов прочитать...

адрес at %, нужно будет вручную считать адрес каждого старшего разряда, начала данных так сказать. Как это будет работать ещё?
Дак объявите для области обмена
X at %.... : array[1..10] of real;
Ругается КДС?

MichailG
16.10.2024, 12:05
Дак объявите для области обмена
X at %.... : array[1..10] of real;
Ругается КДС?

Сейчас попробую поэкспериментировать

МихаилГл
16.10.2024, 12:06
Дак объявите для области обмена
X at %.... : array[1..10] of real;
Ругается КДС?

Работает, спасибо, не знал этого:
79451

MichailG
16.10.2024, 12:07
Объявить в коде программы X at %.... : array[1..10] of real; для каждого массива?

Валенок
16.10.2024, 12:08
Работает,
Ну а с учетом этого можно глянуть картинку в п#14 и прочитать 1-й пост ТС
(про пост#2 я стесняюсь напоминать)


.....

Объявить в коде программы X at %.... : array[1..10] of real; для каждого массива?
тоже про пост#14 и Ваш же вопрос с каким зашли
(и опять же про пост 2)

---------------------------------

VAR CONSTANT
N1 : INT := 10;
N2 : INT := N1 * 2;
END_VAR
А так в КДС3 ?

МихаилГл
16.10.2024, 12:16
...

Ну я тупо вижу WORD и как бы не заморачиваюсь... Тем более с кодесис 2.3 и не работал много, таких тонкостей не знал. А вот такой "финт ушами" правда заинтересовал. Но вот момент, я писал на 3.6.14, потом перешел 3.5.17, с его замутой с перестановкой бит в регистре. Т.е. я не только реал использовал, и поэтому с перестановкой справился за 5 минут в прошлый раз. При такой реализации пришлось бы подумать как выкручиваться...

MichailG
16.10.2024, 12:23
в программе понятно это работает, если массив например X[0..5, 0..50], а в аргументе объявлено X[0..50]. На входе просто ставишь X[0] и все, все элементы старшего 0-разряда будут переданы. А вот в конфигурации Modbus Соотнесение входов/выходов такое не проходит. И объявлять в программе нет смысла массив для области обмена. У меня на каждом слейв такой массив, я хотел наоборот объединить все области обмена в двумерный массив, в программе обрабатывать этот массив и распихивать данные по таблицам.

МихаилГл
16.10.2024, 12:32
в программе понятно это работает, если массив например X[0..5, 0..50], а в аргументе объявлено X[0..50]. На входе просто ставишь X[0] и все, все элементы старшего 0-разряда будут переданы. А вот в конфигурации Modbus Соотнесение входов/выходов такое не проходит. И объявлять в программе нет смысла массив для области обмена. У меня на каждом слейв такой массив, я хотел наоборот объединить все области обмена в двумерный массив, в программе обрабатывать этот массив и распихивать данные по таблицам.
Валенок предложил вариант, где можно без соотнесения прожить, главное области %QW0 и пр. не перепутать. Вполне рабочее решение.

MichailG
16.10.2024, 12:46
Понятно. Так я еще не делал, хотя где-то слышал про такое. С адресами работу я избегал всегда, предпочитал соотносить переменные. Спасибо всем, буду мозговать дальше.

Валенок
16.10.2024, 13:55
..я хотел наоборот объединить все области обмена в двумерный массив, в программе обрабатывать этот массив и распихивать данные по таблицам.
Для КДС2, но пример с мастером
https://owen.ru/forum/showthread.php?t=10555&page=1104
пост#11035


С адресами работу я избегал всегда, .
И правильно. Прямые адреса - зло. Но потому что если сказать что норм, то начинают пихать сотнями и по всем закоулкам. Это как с goto

capzap
16.10.2024, 14:10
array[0..5] of array[0..50] of..
тогда подтип вычленяется явно если нужно присвоить целиком 51 элемент real_
этот совет вполне работает 79462