EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

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  <20232024  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  <20232024 
<== Date ==> <== Thread ==>

Subject: Re:Re: Re:Re: Re:Re: Re:Re: Re:Re: some motor driver 3 questions
From: lynn via Tech-talk <tech-talk at aps.anl.gov>
To: "Mark Rivers" <rivers at cars.uchicago.edu>
Cc: tech-talk <tech-talk at aps.anl.gov>
Date: Thu, 8 Jun 2023 17:34:46 +0800 (CST)
Hi Mark,
    Thanks for you help about the motor driver.
 
    I met something strange when testing the driver.
    Moving, limit was normal, then I moved the motor to limit, click ioc:m1.TWF several times, the thing happened.

    Let me introduce it clearly.
    Motor.opi showed :
    IOC:m1.RBV was 42.4792, IOC:m1.VAL was 42.4792 also, limit+ staus show red.
    IOC:m1.TWV was 10(i try 0 and 20, more or less), then I continued to clicke IOC:m1.TWF.
    IOC:m1.VAL was changed to 0.000 after several clicks.(I mean continue 3-15 times, not same each time. and about 1 seconds interval each click )

    Now the status was:
    IOC:m1.RBV was 42.4792, IOC:m1.VAL was 0.0000, limit+ staus was still red.

    If i clicked IOC:m1.TWF once more, after IOC:m1.VAL was 0.0000.
    The motor would run. I mean it did run both in opi and in real.
    
    Motor would run to 10.000 or it move back a little then arrive to limit+ again.
    But i clicked the IOC:m1.TWF, the limit+ logic was no problem. It run towards IOC:m1.TWR, after I clicked IOC:m1.TWF.
    
    I know that click TWF button too many times was not suitable, especially after limit+ show.
   
    But it was strange.
    I could not find anything wrong from trace. And ioc did send the move command.
    I know it would not affect the experiment, but i hope it would be done.
    Could you give me some help.

    P.S. My substitutions was MRES=0.0001, EGU=mm.

Regards,
Lynn





在 2023-06-01 20:39:44,"Mark Rivers" <rivers at cars.uchicago.edu> 写道:

Hi Lynn,

I found IOC:m1_able.VAL was disconncet in motorx_all.opi.
Since the name(" _able "), it should have a link with motor enable. There are two places i use the enable motor command.(MO=1).
First was initialization when constructor.  Second was in poll() function below.
I think neither of them was the reason, why IOC:m1_able.VAL was disconnected.

That record is loaded via the databases that are provided with the motor module.  It allows you to enable and disable the motor, so that it temporarily cannot be moved.  For example:

If you load asyn_motor.db then you will get that record and it will be connected in the OPI screen.

  if (comStatus) goto skip;
  driveOn = (pC_->inString_[0] == '1') ? 1:0;     //get "MO=1;" mean motor disable;get "MO=0;" mean motor enable;

That code in the driver can turn the motor drive power on and off.  It is different from the _able which sets the SDIS field in the motor record to completely disable the record.

Mark



From: lynn <lynn0703 at yeah.net>
Sent: Thursday, June 1, 2023 3:45 AM
To: Mark Rivers <rivers at cars.uchicago.edu>
Subject: Re:Re: Re:Re: Re:Re: Re:Re: some motor driver 3 questions
 
Hi Mark,

 done = (temp > 0.010)?1:0;

The logic there is wrong.  That will set done=1 (true) if temp if greater than 0.01.  That is the opposite of what you want.  I think you should also be testing the absolute value, since the error could be negative?

I think it should be this:

 done = (fabs(temp) < 0.010)?1:0;

Are you sure the controller does not have a better way to ask if a move is complete?  Looking for a small error does not seem very elegant.

You remind me, i choose "(temp > 0.010)" for limit status, since my poor c language.
Now I could use better way after your give directions.
And the driver work well now except some qustion.

I found IOC:m1_able.VAL was disconncet in motorx_all.opi.
Since the name(" _able "), it should have a link with motor enable. There are two places i use the enable motor command.(MO=1).
First was initialization when constructor.  Second was in poll() function below.
I think neither of them was the reason, why IOC:m1_able.VAL was disconnected.
1) So how to make it connect?
2)  "the drive power status in poll()" was the same meaning with "motor enable status" ?
  *************** Part of poll() ************
  // Read the drive power on status
  sprintf(pC_->outString_, "MO");
  comStatus = pC_->writeReadController();
  comStatus = pC_->readController();
  if (comStatus) goto skip;
  driveOn = (pC_->inString_[0] == '1') ? 1:0;     //get "MO=1;" mean motor disable;get "MO=0;" mean motor enable;
  setIntegerParam(pC_->motorStatusPowerOn_, driveOn);
  setIntegerParam(pC_->motorStatusProblem_, 0);





From trace output bellow, I found some commands send twice, which i just send once. Such as "SP=70000; SP=70000;"

2023/05/30 15:43:47.544 192.168.1.5:5001 udp write 9
SP=70000;
2023/05/30 15:43:47.546 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 9
SP=70000;
2023/05/30 15:43:47.546 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 1
           ;

Actually I don't see SP=70000 being sent twice.  I see it being written once, and then read back.  That is just the controller echoing the command, right?

Mark


From: lynn <lynn0703 at yeah.net>
Sent: Tuesday, May 30, 2023 5:26 AM
To: Mark Rivers <rivers at cars.uchicago.edu>
Subject: Re:Re: Re:Re: Re:Re: some motor driver 3 questions
 
Hi Mark,
   Thank you!
   I did as you said, it worked and motor run successfully.
   May I ask for your advice about some detail. Most was poll() function.

***** This is poll() function Now *******************
asynStatus MCB4BAxis::poll(bool *moving)
{
  int done;
  int driveOn;
  int limit;
  double position;
  float temp;
  int temp1;
  asynStatus comStatus;

  // Read the current motor position
  sprintf(pC_->outString_, "PX");
  comStatus = pC_->writeReadController();
  comStatus = pC_->readController();
  if (comStatus) goto skip;
  // The response string is of the form  first:"PX;"   second: "10000;"
  position = atof(&pC_->inString_[0]);
  setDoubleParam(pC_->motorPosition_, position);

  // Read the moving status of this motor
  sprintf(pC_->outString_, "ID");
  comStatus = pC_->writeReadController();
  comStatus = pC_->readController();
  if (comStatus) goto skip;

  temp = atof(&pC_-> inString_[0]);
  done = (temp > 0.010)?1:0;
  setIntegerParam(pC_->motorStatusDone_, done);
  *moving = done ? false:true;

  // Read the limit status
  sprintf(pC_->outString_, "IP");
  comStatus = pC_->writeReadController();
  comStatus = pC_->readController();
  if (comStatus) goto skip;
  // The response string is of the form "ip;65536;"
  temp1 = atoi(&pC_-> inString_[0]);
  limit = (temp1 == 131138) ? 1:0;
  setIntegerParam(pC_->motorStatusHighLimit_, limit);
  limit = (temp1 == 65666) ? 1:0;
  setIntegerParam(pC_->motorStatusLowLimit_, limit);

  // Read the drive power on status
  sprintf(pC_->outString_, "MO");
  comStatus = pC_->writeReadController();
  comStatus = pC_->readController();
  if (comStatus) goto skip;
  // The response string is of the form "mo=1;"
  driveOn = (pC_->inString_[0] == '1') ? 1:0;     //get "MO=1;" mean motor disable;get "MO=0;" mean motor enable;
  setIntegerParam(pC_->motorStatusPowerOn_, driveOn);
  setIntegerParam(pC_->motorStatusProblem_, 0);

  skip:
  setIntegerParam(pC_->motorStatusProblem_, comStatus ? 1:0);
  callParamCallbacks();
  return comStatus ? asynError : asynSuccess;
}
 
    1)
    Position was good. Move was good, limit status was good.
    But moving status was not correct.

******* output of ID command(ID was about status of moving), when motor was stop. ********
-960255;
2023/05/30 17:59:27.991 192.168.1.5:5001 udp write 3
ID;
2023/05/30 17:59:27.994 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 3
ID;
2023/05/30 17:59:27.994 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 8
0.00451;
2023/05/30 17:59:27.994 192.168.1.5:5001 udp write 3
IP;
2023/05/30 17:59:27.996 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 5
IP;2;
2023/05/30 17:59:27.996 192.168.1.5:5001 udp write 3
MO;
2023/05/30 17:59:27.998 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 5
MO;1;
2023/05/30 17:59:32.999 192.168.1.5:5001 udp write 3
PX;
2023/05/30 17:59:33.001 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 3
PX;
2023/05/30 17:59:33.001 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 8
-960255;
2023/05/30 17:59:33.001 192.168.1.5:5001 udp write 3
ID;
2023/05/30 17:59:33.003 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 3
ID;
2023/05/30 17:59:33.004 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 8
0.00159;

    when i execute move command, it finished.
    The output come from stopped status, and the ID value was less then 0.01, but status was "moving".
    I tried to exchange false and true in this word: "*moving = done ? false:true;" of poll().
    but the effect was more or less.
 
    I think there is device quesiton here. So could you help me with the function and words.
    I need to know the function was good, then I would debug the device.

   2)
    I don't think it's a question. it would not impact actual effect.
    I just wonder it.
    From trace output bellow, I found some commands send twice, which i just send once. Such as "SP=70000; SP=70000;"
    Does it matter?
****************** Part of output *******************
2023/05/30 15:43:47.541 192.168.1.5:5001 udp write 3
MO;
2023/05/30 15:43:47.543 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 5
MO;1;
2023/05/30 15:43:47.544 192.168.1.5:5001 udp write 9
SP=70000;
2023/05/30 15:43:47.546 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 9
SP=70000;
2023/05/30 15:43:47.546 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 1
;
2023/05/30 15:43:47.546 192.168.1.5:5001 udp write 12
AC[1]=30000;
2023/05/30 15:43:47.548 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 12
AC[1]=30000;
2023/05/30 15:43:47.548 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 1
;
2023/05/30 15:43:47.549 192.168.1.5:5001 udp write 11
PA=-220000;
2023/05/30 15:43:47.550 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 11
PA=-220000;
2023/05/30 15:43:47.551 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 1
;
2023/05/30 15:43:47.551 192.168.1.5:5001 udp write 3
BG;
2023/05/30 15:43:47.553 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 4
BG;;
2023/05/30 15:43:47.553 192.168.1.5:5001 udp write 3
BG;
2023/05/30 15:43:47.555 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 4
BG;;
2023/05/30 15:43:47.555 192.168.1.5:5001 udp write 3
PX;
2023/05/30 15:43:47.557 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 11
PX;-200420;
2023/05/30 15:43:47.557 192.168.1.5:5001 udp write 3
ID;
2023/05/30 15:43:47.559 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 3
ID;
2023/05/30 15:43:47.560 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 9
-0.03487;


******** The SP command part, only in here. **************
asynStatus MCB4BAxis::sendAccelAndVelocity(double acceleration, double velocity)
{
  asynStatus status;
  int ival;
  ival=70000;  // give it a constant number
  if (ival < 2) ival=2;
  if (ival > 2147483647) ival = 2147483647;

  sprintf(pC_->outString_, "SP=%d", ival);
  status = pC_->writeReadController();
  status = pC_->readController();
  ival = NINT(acceleration);
  if (ival < 1) ival=1;
  if (ival > 7000000) ival=7000000;
  sprintf(pC_->outString_, "AC[1]=30000");  //constant number
  status = pC_->writeReadController();
  status = pC_->readController();      // read twice
  return status;
}


Regards,
Lynn




在 2023-05-29 22:05:47,"Mark Rivers" <rivers at cars.uchicago.edu> 写道:

Hi Lynn,

  >   First, I tried as you said "this->writeReadController();   this->readController();", but something wrong when make.

That was my mistake, the asynMotorController class actually did not have a readController() method, only writeController() and writeReadController().  I have now added readController() methods.  Please get the master branch from Github and try again.

Your device appears to echo every command, and then send the response.  So every time you send a command you need to do this for calls from the MCB4BController class:

this->writeReadController()
this->readController()

or this for calls from the MCB4BAxis class:

pC_->writeReadController()
pC_->readController()

In your poll() function change this:
  comStatus = pC_->writeReadController();
  comStatus = pC_->writeReadController();    //read the second time,first for px,second for pos

to this:
  comStatus = pC_->writeReadController();
  comStatus = pC_->readController();    //read the second time,first for px,second for pos

The following code code is not correct.  You first need to convert the string to a float.
  • done = ((float)(pC_->inString_[3]) > 0.009) ? 1:0;  // i added the "float" before the pc_->inString
It should be:

float temp = atof(&pC_->inString_[3]);
done = (temp > 0.009) ? 1:0; 

Mark


From: lynn <lynn0703 at yeah.net>
Sent: Monday, May 29, 2023 8:17 AM
To: Mark Rivers <rivers at cars.uchicago.edu>
Subject: Re:Re: Re:Re: some motor driver 3 questions
 
Hi Mark,
     There is some problem.
     First, I tried as you said "this->writeReadController();   this->readController();", but something wrong when make.

****** Make Error ***********
MC4BDriver.cpp
../MCB4BDriver.cpp:331:33: warning: character constant too long for its type
   limit = (pC_->inString_[3] == '131138') ? 1:0;
                                 ^~~~~~~~
../MCB4BDriver.cpp:333:33: warning: character constant too long for its type
   limit = (pC_->inString_[3] == '65666') ? 1:0;
                                 ^~~~~~~
../MCB4BDriver.cpp: In constructor ‘MCB4BController::MCB4BController(const char*, const char*, int, double, double)’:
../MCB4BDriver.cpp:63:9: error: ‘class MCB4BController’ has no member named ‘ReadController’; did you mean ‘MCB4BController’?
   this->ReadController();
         ^~~~~~~~~~~~~~
         MCB4BController
../MCB4BDriver.cpp: In member function ‘virtual asynStatus MCB4BAxis::home(double, double, double, int)’:
../MCB4BDriver.cpp:220:30: warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat=]
     sprintf(pC_->outString_, "#%02dH+");
                              ^~~~~~~~~
../MCB4BDriver.cpp:222:30: warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat=]
     sprintf(pC_->outString_, "#%02dH-");
                              ^~~~~~~~~

      Then I delete the lines: "this->writeReadController();   this->readController();". make and Run.
      This is constructor of my driver file.
***********************************
MCB4BController::MCB4BController(const char *portName, const char *MCB4BPortName, int numAxes,  double movingPollPeriod, double idlePollPeriod)
  :  asynMotorController(portName, numAxes, NUM_MCB4B_PARAMS,
                         0, // No additional interfaces beyond those in base class
                         0, // No additional callback interfaces beyond those in base class
                         ASYN_CANBLOCK | ASYN_MULTIDEVICE,
                         1, // autoconnect
                         0, 0)  // Default priority and stack size
{
  int axis;
  asynStatus status;
  MCB4BAxis *pAxis;        // newFocus and Newport did not have this
  static const char *functionName = "MCB4BController::MCB4BController";

  /* Connect to MCB4B controller */
  status = pasynOctetSyncIO->connect(MCB4BPortName, 0, &pasynUserController_, NULL);
  if (status) {
    asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
      "%s: cannot connect to MCB-4B controller\n",
      functionName);   //newfocus add a driverName
  }
  epicsThreadSleep(0.5);  //added

  for (axis=0; axis<numAxes; axis++) {     //create the axis object
    pAxis = new MCB4BAxis(this, axis);     // newfocus
  }

  //for test
  sprintf(this->outString_,"MO=1");
  this->writeReadController();     //read two times, first is "MO=1;" second is ";"
//  this->ReadController();
//  status = pC_->writeReadController();
  // asynPrint(this->inString_);
  // less than newfocus

  startPoller(movingPollPeriod, idlePollPeriod, 2);
}


The is corresponding output:
*************************************
#errlogInit(5000)
< envPaths
epicsEnvSet("IOC","iocAcs")
epicsEnvSet("TOP","/opt/epics/motorAcs-master/iocs/acsIOC")
epicsEnvSet("SUPPORT","/opt/epics")
epicsEnvSet("MOTOR","/opt/epics/motor")
epicsEnvSet("ASYN","/opt/epics/asyn")
epicsEnvSet("EPICS_BASE","/opt/epics/base")
epicsEnvSet("SNCSEQ","/opt/epics/seq")
epicsEnvSet("MOTOR_ACS","/opt/epics/motorAcs-master/")
# Tell EPICS all about the record types, device-support modules, drivers, etc.
dbLoadDatabase("../../dbd/acs.dbd")
acs_registerRecordDeviceDriver(pdbbase)
# Port 2 on a Moxa
#drvAsynIPPortConfigure("serial1", "192.168.1.5:5001",0,0,0)
drvAsynIPPortConfigure("serial1", "192.168.1.5:5001 udp",0,0,0)
#
asynOctetSetInputEos("serial1",0,";")  
asynOctetSetOutputEos("serial1",0,";")
asynSetTraceIOMask("serial1", 0, 0x2)
asynSetTraceMask("serial1", 0, 0x9)
MCB4BCreateController("MCB4B1", "serial1", 1, 100, 5000)
2023/05/29 20:52:54.633 192.168.1.5:5001 udp write 5
MO=1;
2023/05/29 20:52:54.635 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 5
MO=1;         # it looks right? But it did have ";", when i test the command using network debug assistant.
### Motors
dbLoadTemplate "motor.substitutions.mcb4b"
dbLoadRecords("/opt/epics/asyn/db/asynRecord.db","P=IOC:,R=serial1,PORT=serial1,ADDR=0,OMAX=80,IMAX=80") #  OMAX and IMAX mean?
iocInit
Starting iocInit
############################################################################
## EPICS R7.0.6.1
## Rev. 2022-07-23T08:14+0000
############################################################################
2023/05/29 20:52:54.635 192.168.1.5:5001 udp flushed 1 bytes
2023/05/29 20:52:54.635 192.168.1.5:5001 udp write 3
PX;
2023/05/29 20:52:54.638 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 11
PX;-194693;    # The PX command didn't  have a single ";" at the end, just "px;" and " -1964693;". Only "MO=1" or maybe sometimes of "mo=1", it would have a single ';'
2023/05/29 20:52:54.638 192.168.1.5:5001 udp write 3
PX; 
2023/05/29 20:52:54.640 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 3
PX;    # and this is the reason why i need to deal with it, it would distrub the latter command.
and i would show the corresponding part of PX command in my driver at the bottom.
2023/05/29 20:52:54.640 192.168.1.5:5001 udp write 3
ID;
2023/05/29 20:52:54.641 192.168.1.5:5001 udp (from 192.168.1.5:5001) read 8
-194693;
2023/05/29 20:52:54.641 192.168.1.5:5001 udp write 3


This is the corresponding PX and ID command part.
***************** PX and ID command****************
asynStatus MCB4BAxis::poll(bool *moving)
{
  int done;
  int driveOn;
  int limit;
  double position;
  asynStatus comStatus;

  // Read the current motor position
  sprintf(pC_->outString_, "PX");
  comStatus = pC_->writeReadController();
  comStatus = pC_->writeReadController();    //read the second time,first for px,second for pos
  if (comStatus) goto skip;
  // The response string is of the form  first:"PX;"   second: "10000;"
  position = atof(&pC_->inString_[0]);
  setDoubleParam(pC_->motorPosition_, position);

  // Read the moving status of this motor
  sprintf(pC_->outString_, "ID");
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;

  done = ((float)(pC_->inString_[3]) > 0.009) ? 1:0;  // i added the "float" before the pc_->inString
  setIntegerParam(pC_->motorStatusDone_, done);
  *moving = done ? false:true;


Regards,
Lynn





在 2023-05-29 20:22:58,"Mark Rivers" <rivers at cars.uchicago.edu> 写道:

Please send the complete output when the IOC starts and it does the communication at initialization.

You need to send writeReadController once, and then readController.  That should read the second ";" without sending the command again.

  this->writeReadController();
  this->readController();



From: lynn <lynn0703 at yeah.net>
Sent: Monday, May 29, 2023 5:50 AM
To: Mark Rivers <rivers at cars.uchicago.edu>
Cc: tech-talk <tech-talk at aps.anl.gov>
Subject: Re:Re: some motor driver 3 questions
 
Hi Mark,
    Thank you so much for you help.
    I modified startup script, using (';') as the terminator.
    Then added the initialiation command in construct MCB4BController::MCB4BController like bellow.
    it worked except some problems.

MCB4BController::MCB4BController(....)  : asynMotorController()
{
  sprintf(this->outString_,"MO=1");
  this->writeReadController();
//  this->writeReadController();
}
 
    The problem:
    i send "mo=1;", device would sendback "mo=1;" ,then sendback ";".
    There is many place like these, this motor. not because the outputEos.
    My C was poor. I tried to add line "this->writeReadController();", it became write twice command and read twice.
    How should i readout twice in one command?   

Regards,
Lynn




在 2023-05-26 21:27:03,"Mark Rivers" <rivers at cars.uchicago.edu> 写道:

1) why command "ID;" did not work? Both "PX;" and "ID;" were in MCB4BAxis::poll function. Obviously, "PX;" was send ,"ID;" didn't.

You see this in the output:
2023/05/24 18:30:14.350 serial1 read 11 bytes eom=0
PX;-106202;
2023/05/24 18:30:14.350 192.168.1.5:5001 udp read.
2023/05/24 18:30:16.352 serial1 read from low-level driver returned 1

So the low-level read returned 1, which is asynTimeout.  This is interpreted as an error condition.  It expects 0, asynSuccess.

The code is here:
 sprintf(pC_->outString_, "PX;");
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;

So if comStatus is not 0 it jumps to "skip" and does not send the ID command.  

I don't see any \r or \n in the response from the device.  Does it use a semicolon (';') as the terminator?  If so you need to set that with asynOctetSetInputEos in your startup script.

    2) how to achieve it, if I want to send some initialization command ?

You can send an initialization command in the axis or controller constructor code.
 
   3) 
    When I send "px;". Device would not send "PX=15926;" back.
    It would send "px;" first,then "15268;". I means, they are not send together.
    Does I need to change some in my code?

I think you need to set the terminator to ;.  Then you need to do 2 reads to read the response.  The first will read px, the second will read the value.

    4)
    Device required command "PR=1000;", then  send "BG;". it would not work if send together.
    How to write these code ?

    if (relative) {    sprintf(pC_->outString_, "PR=%d;", NINT(position));   
    sprintf(pC_->outString_, "BG;");                                   // I added a line here. Does it ok?
  } else {
    sprintf(pC_->outString_, "PA=%d;", NINT(position));
    sprintf(pC_->outString_, "BG;");
  
That code is not correct.  You need to change it to this:

   if (relative) {    sprintf(pC_->outString_, "PR=%d;", NINT(position));   
     comStatus = pC_->writeReadController();
     sprintf(pC_->outString_, "BG;");     
     comStatus = pC_->writeReadController();
  } else {
    sprintf(pC_->outString_, "PA=%d;", NINT(position));
    comStatus = pC_->writeReadController();
    sprintf(pC_->outString_, "BG;");
    comStatus = pC_->writeReadController();

Mark



From: Tech-talk <tech-talk-bounces at aps.anl.gov> on behalf of lynn via Tech-talk <tech-talk at aps.anl.gov>
Sent: Wednesday, May 24, 2023 7:11 AM
To: tech-talk <tech-talk at aps.anl.gov>
Subject: some motor driver 3 questions
 
 Hi all,
    Nowadayas i was writing elmo motor driver.
    i modified from MCB4BDriver.cpp (model 3 example).

    I found it was in a loop from AsynTrace message, after starting st.cmd.

********************* AsynTrace out, Begin*************************

2023/05/24 18:30:14.347 wrote 3 to 192.168.1.5:5001 udp, return asynSuccess.
2023/05/24 18:30:14.347 asynOctetSyncIO wrote:
PX;
2023/05/24 18:30:14.347 192.168.1.5:5001 udp read.
2023/05/24 18:30:14.350 192.168.1.5:5001 udp (from 192.
168.1.5:5001) read 11
PX;-106202;
2023/05/24 18:30:14.350 serial1 read 11 bytes eom=0
PX;-106202;
2023/05/24 18:30:14.350 192.168.1.5:5001 udp read.
2023/05/24 18:30:16.352 serial1 read from low-level driver returned 1
2023/05/24 18:30:16.352 serial1 queueUnlockPort
2023/05/24 18:30:16.352 serial1 asynManager::queueUnlockPort waiting for event
2023/05/24 18:30:16.352 serial1 queueUnlockPort unlock mutex 0x7f605c000e90 complete.
2023/05/24 18:30:16.452 serial1 asynManager::queueLockPort locking port
2023/05/24 18:30:16.452 serial1 asynManager::queueLockPort taking mutex 0x7f605c000e90
2023/05/24 18:30:16.452 serial1 asynManager::queueLockPort queueing request
2023/05/24 18:30:16.452 serial1 addr -1 queueRequest priority 0 not lockHolder
2023/05/24 18:30:16.452 serial1 schedule queueRequest timeout in 2.000000 seconds
2023/05/24 18:30:16.452 serial1 asynManager::queueLockPort waiting for event
2023/05/24 18:30:16.452 asynManager::portThread port=serial1 callback
2023/05/24 18:30:16.452 serial1 asynManager::queueLockPortCallback signaling begin event
2023/05/24 18:30:16.452 serial1 asynManager::queueLockPortCallback waiting for mutex from queueUnlockPort
2023/05/24 18:30:16.452 serial1 asynManager::queueLockPort got event from callback
2023/05/24 18:30:16.452 serial1 flush
2023/05/24 18:30:16.452 192.168.1.5:5001 udp flush
2023/05/24 18:30:16.452 192.168.1.5:5001 udp write.
2023/05/24 18:30:16.452 192.168.1.5:5001 udp write 3
PX;

2023/05/24 18:30:16.452 wrote 3 to 192.168.1.5:5001 udp, return asynSuccess.
     Another loop begin.
*************   AsynTrace out, End ******************


    Since loop was about "px;", I checked driver.cpp, found that "PX" only came out in MCB4BAxis::poll function.
    Here is the code of MCB4BAxis::Poll.
********************* MCB4BAxis::poll Begin *************************
asynStatus MCB4BAxis::poll(bool *moving)
{
  int done;
  int driveOn;
  int limit;
  double position;
  asynStatus comStatus;

  sprintf(pC_->outString_, "PX;");
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;
  position = atof(&pC_->inString_[3]);
  setDoubleParam(pC_->motorPosition_, position);

  // Read the moving status of this motor
  sprintf(pC_->outString_, "ID;");
  comStatus = pC_->writeReadController();
  if (comStatus) goto skip;

  done = (float(pC_->inString_[3]) > 0.009) ? 1:0;
  setIntegerParam(pC_->motorStatusDone_, done);
  *moving = done ? false:true;

********************* MCB4BAxis::poll End *************************

   
    Could someone help me with these questions:
    1) why command "ID;" did not work? Both "PX;" and "ID;" were in MCB4BAxis::poll function. Obviously, "PX;" was send ,"ID;" didn't.
    2) how to achieve it, if I want to send some initialization command ?
    3) 
    When I send "px;". Device would not send "PX=15926;" back.
    It would send "px;" first,then "15268;". I means, they are not send together.
    Does I need to change some in my code?
    4)
    Device required command "PR=1000;", then  send "BG;". it would not work if send together.
    How to write these code ?

    if (relative) {
    sprintf(pC_->outString_, "PR=%d;", NINT(position));   
    sprintf(pC_->outString_, "BG;");                                   // I added a line here. Does it ok?
  } else {
    sprintf(pC_->outString_, "PA=%d;", NINT(position));
    sprintf(pC_->outString_, "BG;");
  
   Any suggestion was appreciate.
   Thanks.

Regards,
Lynn



References:
some motor driver 3 questions lynn via Tech-talk
Re: some motor driver 3 questions Mark Rivers via Tech-talk
Re:Re: some motor driver 3 questions lynn via Tech-talk
Re: Re:Re: some motor driver 3 questions Mark Rivers via Tech-talk

Navigate by Date:
Prev: Re: setInteger64Param Gofron, Kazimierz via Tech-talk
Next: Is it possible to know if current field is the last node of parent struct in PVXS Wang, Lin via Tech-talk
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  <20232024 
Navigate by Thread:
Prev: Re: Re:Re: some motor driver 3 questions Mark Rivers via Tech-talk
Next: modbus wang Ewen via Tech-talk
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  <20232024 
ANJ, 08 Jun 2023 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·