УкраїнськаEnglishmRussian
Вхід/Новий
У темі немає нових постів

[BugFixed] Обработка регистров ModBus


Автор Повідомлення
Повідомлення створено: 14. 05. 2014 [13:18]
fido_max
Maxim Kochetkov
Contributor
Автор теми
Зареєстрован(а) с: 28.10.2010
Повідомлення: 129
Обнаружил такой момент:
В модуле сбора данных ModBus есть такой параметр:

R_f:500:w:val:val

Этот параметр только для записи. При попытке записи в этот атрибут пишется не два регистра, а один, причем не по адресу 500, а по адресу ноль.
Если параметр описать как:

R_f:500,501:w:val:val

то все пишется нормально.

Это происходит потому, что в void TMdPrm::enable( ) есть кусок:

unsigned flg = (awr=="rw") ? TVal::DirWrite|TVal::DirRead :
((awr=="w") ? TVal::DirWrite : TFld::NoWrite|TVal::DirRead);
if(atp.size() >= 2 && atp[1] == 'I') flg = (flg & (~TVal::DirWrite)) | TFld::NoWrite;
p_el.fldAt(el_id).setFlg(flg);
p_el.fldAt(el_id).setDescr(anm);

if(flg&TVal::DirRead)
{
int reg = strtol(ai.c_str(), NULL, 0);
owner().regVal(reg, atp_m);
if(atp[0] == 'R')
{
if(atp_sub == "i4" || atp_sub == "f")
{
int reg2 = TSYS::strParse(ai,1,",").empty() ? (reg+1) : strtol(TSYS::strParse(ai,1,",").c_str(),NULL,0);
owner().regVal(reg2, atp_m);
ai = TSYS::strMess("%d,%d", reg, reg2);
}
else if(atp_sub == "s")
{
int rN = vmax(0,vmin(100,strtol(TSYS::strParse(ai,1,",").c_str(), NULL, 0)));
if(rN == 0) rN = 10;
for(int i_r = reg; i_r < (reg+rN); i_r++) owner().regVal(i_r, atp_m);
ai = TSYS::strMess("%d,%d", reg, rN);
}
}
}
p_el.fldAt(el_id).setReserve(atp+":"+ai);

в котором второй регистр для R_f параметр добавляется только в случае, если flg&TVal::DirRead та же самая проблема имеет место и для всех остальных типов, которые не умещаются в одном регистре.
Повідомлення створено: 14. 05. 2014 [18:25]
roman
Roman Savochenko
Moderator
Contributor
Developer
Зареєстрован(а) с: 12.12.2007
Повідомлення: 3750
"fido_max" wrote:

в котором второй регистр для R_f параметр добавляется только в случае, если flg&TVal::DirRead та же самая проблема имеет место и для всех остальных типов, которые не умещаются в одном регистре.

Регистры как раз и не должны добавляться в блоки опроса если там только на запись, иначе будут проблемы с устройствами, которые ругаются на чтение того, что можно только писать.

А проблема в том, что p_el.fldAt(el_id).setReserve(atp+":"+ai); при этом не заполняется корректно дополненым "ai", почему и пытается писать дважды в 0.

Исправил это, выгружу позже.

За одно сразу и добавлю новых комплексных типов: "_u4", "_i8", "_d".

Learn, learn and learn better than work, work and work.



0867