One shot modbus write

More
1 month 2 weeks ago #9 by jds
One shot modbus write was created by jds
First "real" question on the new forum:
Is there a possibility to do a one shot modbus write?
For now I do the control with setting "continuous" to no in the modbus_module and "sendop" high when I want the write enabled.
This works like it should do but I want to create a class where this is needed. The problem which than rises is connecting this attribute from in a class. Maybe there's a possibility to link the attribute through a parameter in the main plc object, but for now I don't know how to achieve this?
This class eventually will be part of an aggragate so it would be nice to find a solution. The only solution I can think of for now is creating a output at the plcfo of the class and the aggragate and link the out of the aggragate to a stodp in the plc, but I hope there's a better way 

Please Log in or Create an account to join the conversation.

More
1 month 2 weeks ago #10 by claes
Replied by claes on topic One shot modbus write
Hi jds,

The reference to the IO can be found in the IoConnect attribute, if there is one, or in SigChanCon in any of the signals. It is possible to fetch this in a DataArithm connected to a GetData pointing at $PlcMain. Below is some (untested) example code where d1 input is connected to the send condition

classdef Da1 MyComponent;
static pwr_tBoolean *sendop = 0;
static pwr_tStatus sts = 0;

if (sts == 0 && sendop = 0) {
pwr_tAName aname;
char *s;

// Get name of a channel and replace the channel with SendOp
sts =gdh_AttrefToName(&Da1>SomeSignal.SigChanCon, aname, sizeof(aname), cdh_mName_volumeStrict);
if (ODD(sts)) {
s = strrchr(aname, ”.”); // or "-" if channel is a child
if (s)
*s = 0;
strcat(aname, ”.SendOp”);
sts = gdh_NameToPointer(aname, (void **)&sendop);
}
}
if (d1 && sendop && ODD(sts))
*sendop = 1;

/Claes

Please Log in or Create an account to join the conversation.

More
1 month 2 weeks ago #12 by jds
Replied by jds on topic One shot modbus write
Ok, I'll have to look deeper into this, this is not as simple (to me) as I first thought ;-)
Thanks already for the right direction.

Please Log in or Create an account to join the conversation.

More
3 weeks 2 days ago #70 by jds
Replied by jds on topic One shot modbus write
Claes,
since I first didn't know of the existance of the Data arthm and the first one of a kind for me was the alarm part, I've dared to try out the suggested code.
With some minor adjustments it compiled but it doesn't work (yet) as suspected.
to use the volume strict mask I also neede to add the header file, get a lot of complaint from the compiler concerning the other vars, but it runs.
With the '.' in the strrchr nothing happens at all, when using the '-' the description gets overwritten by, probably, the "1" from the sendop.

Since I'm totaly not formiliar with the build in functions can you help me out any further?

The code looks now like htis (one & was missing and a - in the -> pointer):
Code:
#include "co_cdh.h"

classdef Da1 BaseFcXylem;
static pwr_tBoolean *sendop = 0;
static pwr_tStatus sts = 0;

if (sts == 0 && sendop == 0) {
pwr_tAName aname;
char *s;

// Get name of a channel and replace the channel with SendOp
sts = gdh_AttrrefToName( &Da1->ExStrt.SigChanCon, aname, sizeof(aname), cdh_mName_volumeStrict);

if (ODD(sts) ){
s = strrchr(aname, '-');  // or '-' if channel is child

if (s) 
*s = 0;

strcat(aname, ".SendOp");
sts = gdh_NameToPointer(aname, (void **)&sendop);
}
}

if (d1 && sendop && ODD(sts))
*sendop = 1;

The hierachy of the signal refered to by ExStrt is as follows:
 

Please Log in or Create an account to join the conversation.

More
3 weeks 2 days ago #71 by claes
Replied by claes on topic One shot modbus write
Hi jds,

Sorry, my mistake. gdh_NameToPointer() doesn't handle attributes and will point to the whole object. One has to use gdh_AttrRefToPointer() instead.
Also co_cdh.h should be included in ra_plc_user.h, not in the DataArithm code.
Code:
classdef Da1 BaseFcXylem; static pwr_tBoolean *sendop = 0; static pwr_tStatus sts = 0; if (sts == 0 && sendop == 0) {   pwr_tAName aname;   char *s;   [color=#c0392b]pwr_tAttrRef aref;[/color]   // Get name of a channel and replace the channel with SendOp   sts = gdh_AttrrefToName( &Da1->ExStrt.SigChanCon, aname, sizeof(aname), cdh_mName_volumeStrict);   if (ODD(sts) ){     s = strrchr(aname, '-');  // or '-' if channel is child     if (s)     *s = 0;     strcat(aname, ".SendOp"); [color=#e74c3c]    sts = gdh_NameToAttrref(pwr_cNObjid, aname, &aref);     if (ODD(sts))       sts = gdh_AttrRefToPointer(&aref, (void **)&sendop);[/color]   } } if (d1 && sendop && ODD(sts)) *sendop = 1;

/Claes

Please Log in or Create an account to join the conversation.

More
3 weeks 2 days ago #72 by jds
Replied by jds on topic One shot modbus write
Top, works like intended, thanks!

Now lets see if I can get the status from the modbus module and the modbus tcp slave fetched the same way.
The tcp slave to fetch the status of the tcp connection towards the tcp/rtu convertor, the slave to fetch the rs485 connection. A good excersize for me :-)

Please Log in or Create an account to join the conversation.

Time to create page: 0.440 seconds
Powered by Kunena Forum