PDA

Просмотр полной версии : СП310-Р и Modbus TCP



andemeno
21.02.2023, 16:32
Панель СП310-Р выступает в качестве мастера Modbus TCP (адрес панели 172.16.0.100/24 шлюз 172.16.0.1).
Slave-устройство (172.16.0.11), статус связи экспортируются Конфигуратором СП300 во внутренние регистры панели (PSW256-259).
Опрос выполняется с помощью макроса 1 раз в секунду. Используется следующий код:


typedef struct regs_entry_ {
WORD addr;
WORD count;
void* tm;
} regs_entry_t;

BOOL tcpReadInputRegs(regs_entry_t entry) {
static WORD regs[256];
if(Reads(NET_0, 1, MODBUS_TCP_REGS_3X, entry.addr, entry.count, &regs)) {
memcpy(regs, entry.tm, 2*sizeof(entry.count));
return TRUE;
}
return FALSE;
}


Всё бы хорошо, но в статусе связи счетчик полученных ответов увеличивается, а счетчики неполученных ответов, ошибок и таймаутов всегда 0 даже если к панели НЕ подключен сетевой кабель.
При этом в PSB54 (Ошибка связи с TCP Slave 1) всегда 0, а приведенный макрос всегда возвращает TRUE.

Вопрос: что не так и как узнать статус связи?

andemeno
28.02.2023, 19:04
В процессе выяснения причин проблемы, обнаружилось, что функция Reads(...), в случае если ей передано в качестве параметра "Количество регистров" значение = 0, возвращает TRUE.
Считаю такое поведение некорректным, поскольку запрашивать на чтение 0-ое количество регистров - это ошибка, и функция не должна возвращать TRUE.
Если это возможно, то хотелось бы услышать комментарий разработчика.

Адрей
28.02.2023, 20:53
Ошибки есть и приходится смерится плеваться и работать. Что не возьми везде косяки с оборудованием особенно с интерфейсом.

Адрей
28.02.2023, 20:58
WORD TRM[8];


//PSW[70]=0;
Reads(PLC, 16, MODBUS_RTU_REGS_4X, 0, 10, TRM);


3х256 Момент
3х257 Задание
3х260 Время
3х261 № трубы
1х256 Авария нет связи с ТРМ
1х257 Работа




PSW[256]=TRM[0];
PSW[257]=TRM[1]; pv1
PSW[258]=TRM[2]; pv2
PSW[259]=TRM[3];
PSW[260]=TRM[4];
PSW[261]=TRM[5];
PSW[262]=TRM[6];
PSW[263]=TRM[7];
//if(PSW[70]==0){SetPSB(256);}
//if(PSW[259]==1){if(GetPSBStatus(257)==0){PSW[260]=0;PSW[261]=PSW[261]+1;for(i=0;i<=44;i++)PSW[1024+i]=0;}}
//if(PSW[259]==1)SetPSB(257);
//if(GetPSBStatus(257)) PSW[260]=PSW[260]+1;
//if(PSW[258]==1){if(GetPSBStatus(257)){ResetPSB(257);}}
return;




WORD i,TRM[11];
//COM_PLC Read TRM-202
PSW[70]=0;Reads(PLC,16,MODBUS_RTU_REGS_4X,0,11,TRM);
if(PSW[70]==1){ResetPSB(256);
PSW[256]=TRM[1];//PV1
PSW[257]=TRM[5];//SP1
PSW[259]=TRM[2];//PV2
PSW[258]=TRM[9];}//out1
if(PSW[70]==0){SetPSB(256),PSW[256]=0,PSW[257]=0,PSW[259]=50;}


if(PSW[259]==0){if(GetPSBStatus(257)==0){PSW[260]=0;PSW[261]=PSW[261]+1;for(i=0;i<=44;i++)PSW[1024+i]=0;}}
if(PSW[259]==1)SetPSB(257);
if(GetPSBStatus(257)) PSW[260]=PSW[260]+1;
if(PSW[258]==1){if(GetPSBStatus(257)){ResetPSB(257);}}
return;


может пригодится давно это было много что забыл.

Валенок
28.02.2023, 23:26
если ей передано "Количество регистров" значение = 0, возвращает TRUE.
Считаю такое поведение некорректным, поскольку запрашивать на чтение 0-ое количество регистров - это ошибка, и функция должна возвращать TRUE.
А на что жалуетесь-то ?



...


typedef struct regs_entry_ {
WORD addr;
WORD count;
void* tm;
} regs_entry_t;

BOOL tcpReadInputRegs(regs_entry_t entry) {
static WORD regs[256];
if(Reads(NET_0, 1, MODBUS_TCP_REGS_3X, entry.addr, entry.count, &regs)) {
memcpy(regs, entry.tm, 2*sizeof(entry.count));
return TRUE;
}
return FALSE;
}
..
1.Накой читать в regs а после записывать В regs ИЗ tm (а не наоборот) ?
2.Накой regs вообще ?
3.Ну видоизмените условия как считате нужным. Например:

BOOL tcpReadInputRegs(regs_entry_t entry) {
if((entry.count >= 1) && (entry.count <= 125) //это ж специфицировано протоколом
&& (еще может чего ?))
return Reads(NET_0, 1, MODBUS_TCP_REGS_3X, entry.addr, entry.count, entry.tm);
else
return TRUE; //и это логично т.к. транзакции не было, значит не было ошибки связи или другая плоскость - FALSE как результат получения данных? Разные логика вообще для связи и для получения данных
}

А если хотите большего интеллекта чем убогий BOOL, то возвращайте какой-нить код типа:
-с_голимыми_входными_в_сад
-транзакция_не_прокатила
-нормуль
и т.п.

Валенок
28.02.2023, 23:54
Ошибки есть...
Какие конкретно здесь ?

...Что не возьми везде косяки с оборудованием особенно с интерфейсом.
Примеры с местным оборудованием, схемой, проектом чтоб обсудить косяк бобины ?

PS
- Ой, этот Карузо! Столько шума - “хороший певец, хороший певец”... А он и фальшивит, и картавит!
- А ты что, слушал Карузо?
- Нет, мне Изя напел!

andemeno
01.03.2023, 19:43
А на что жалуетесь-то ?



1.Накой читать в regs а после записывать В regs ИЗ tm (а не наоборот) ?
2.Накой regs вообще ?
3.Ну видоизмените условия как считате нужным. Например:

BOOL tcpReadInputRegs(regs_entry_t entry) {
if((entry.count >= 1) && (entry.count <= 125) //это ж специфицировано протоколом
&& (еще может чего ?))
return Reads(NET_0, 1, MODBUS_TCP_REGS_3X, entry.addr, entry.count, entry.tm);
else
return TRUE; //и это логично т.к. транзакции не было, значит не было ошибки связи или другая плоскость - FALSE как результат получения данных? Разные логика вообще для связи и для получения данных
}

А если хотите большего интеллекта чем убогий BOOL, то возвращайте какой-нить код типа:
-с_голимыми_входными_в_сад
-транзакция_не_прокатила
-нормуль
и т.п.

Нет никаких жалоб. Простая констатация некорректного поведения системной функции Reads. Обратите внимание, Валенок, не самописного макроса tcpReadInputRegs(), а системной функции Reads.
Ведь мало того, что функция при запрошенном нулевом количестве возвращает TRUE, но и количество полученных ответов инкрементирует в соответствуеющем регистре. Но вы же не будете спорить, что ответ на такой запрос она не могла получить (уж тем более с неподключенным кабелем).
Надеюсь на исправление такого поведения в последующих версиях Конфигуратора.