1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 <2024> 2025 | Index | 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 <2024> 2025 |
<== Date ==> | <== Thread ==> |
---|
Subject: | Re: RE: [SPAM] Re: autoConnect could not connect when reading a register by modbus relative addressing |
From: | Mark Rivers via Tech-talk <tech-talk at aps.anl.gov> |
To: | "shenzb at ihep.ac.cn" <shenzb at ihep.ac.cn>, Mark Rivers <rivers at cars.uchicago.edu> |
Cc: | "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov> |
Date: | Sat, 23 Nov 2024 17:32:21 +0000 |
You should look at testClient.cpp:
You could use the main() function as a model for your constructor. It will be passed just the IP address of the modbus server (ipAddr). The constructor will then have lines like this:
drvAsynIPPortConfigure("DMC2_IP", ipAddr, 0, 0, 0);
modbusInterposeConfig("DMC2", modbusLinkTCP, 5000, 0);
drvModbusAsyn *pModbus = new drvModbusAsyn("DMC2", "DMC2_IP", 0, 2, -1, 256, dataTypeUInt16, 0, "DMC2_stepper");
You now have a pointer to a modbus driver, and can call its public functions.
Your driver then just makes calls like this to do the actual Modbus IO:
epicsInt16 data[45];
pModbus->doModbusIO(0, MODBUS_READ_MULTIPLE_REGISTERS, 0x6000, data, 45);
I think this should be simpler than the model you are using now.
Mark
From: Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of Mark Rivers via Tech-talk <tech-talk at aps.anl.gov>
Sent: Saturday, November 23, 2024 10:01 AM To: shenzb at ihep.ac.cn <shenzb at ihep.ac.cn> Cc: tech-talk at aps.anl.gov <tech-talk at aps.anl.gov> Subject: Re: RE: [SPAM] Re: autoConnect could not connect when reading a register by modbus relative addressing
If you look at the startup script for the ANG1 example IOC, you will see that the poll time is set to 100 ms.
That means that the modbus driver has created a background thread that is polling those registers at 10 Hz. I believe that the purpose of the pasynUserForceRead_ is to force an immediate read in case the 10 Hz poller data is too stale.
Note that around the time that this motor driver was written I added support for "absolute" addressing to the Modbus driver. That is documented here:
You enable absolute addressing by passing -1 as the start address in the drvModbusAsynConfigure command. In that case your driver can call this function in the driver:
asynStatus doModbusIO(int slave, int function, int start, epicsUInt16 *data, int len);
In the mode you are currently using you need to create multiple modbus drivers in your startup script, each for a single function code and address range. That is convenient when using Modbus with standard EPICS records (ai, ao, mbbi, mbbo, etc.). However,
in the case of a motor driver absolute addressing may be better.
In the absolute mode you can create a single driver and use if for any function code and any address. That might make more sense for this application. You can even create the modbus driver inside the constructor of your motor driver, hiding it from the user.
You just need to pass the asyn port name of the IP port to your constructor.
Mark
From: shenzb at ihep.ac.cn <shenzb at ihep.ac.cn>
Sent: Saturday, November 23, 2024 2:38 AM To: Mark Rivers <rivers at cars.uchicago.edu> Cc: tech-talk at aps.anl.gov <tech-talk at aps.anl.gov> Subject: Re: RE: [SPAM] Re: autoConnect could not connect when reading a register by modbus relative addressing Dear Mark,
In the ANG1Axis::poll method, the first step is to execute a forced read operation.
ANG1Driver.cpp: line 546 >> status = pasynInt32SyncIO->write(pasynUserForceRead_, 1, DEFAULT_CONTROLLER_TIMEOUT);
I would like to ask why this operation must be performed in order to start a new communication. What is the purpose of the member pasynUserForceRead_?
The comment in ANF2Driver.cpp at line 504 mentions it, but it also says not sure why this is necessary.
Could you help explain the principle behind it?
By the way, regarding the modbus slave simulator mentioned before, since I haven't received the motor controller yet, the simulator is quite useful for me to start coding.
This is the simulator I am using:
https://modbustools.com/modbus_slave.html
Best regards, Zhibang
|