Jump to content
OMRON Forums

Fairly Simple Move until bit question


Recommended Posts



First, let me say that this need not be fast, software capture is just fine. My motion program skills are very basic, so if there is a more obvious and simple solution please advise.


I'd like to do a closed loop move in one axis in a C.S. from a C program until a Ptr variable is set from zero to one (i.e. digital IO ptr var). I'd like the PPMAC to sit at the point of contact once the bit is set. I prefer not to write a motion program for this as it will become a generic C API function I am writing.


Is this as simple as doing a CPX command followed by motion program commands?


I'm just rattling off the top of my head here:


move X axis in CS1 from 0.000 units to 1.234 units and record current position until M100 is set. Once M100 is set move to the contact position.


I don't know the syntax for reading current feed position in the X axis in a motion program command, so I just used "CurrentPos" below as a placeholder.


"CPX &1; ABS; F1; X 1.234; while(M100 == 0) { P100=CurrentPos;} X P100"


alternatively is there a way to do this in two different C calls:

cmd("CPX &1; ABS; F1; X 1.234");
while(M100 == 0.000)
cmd("CPX &1; ABS; F1; X P100");



For brevity I excluded error handling checks.


Am I unknowingly making life difficult or is this what you have to do?




Link to comment
Share on other sites

  • Replies 16
  • Created
  • Last Reply

Top Posters In This Topic

I wanted to add that I would be willing to use JOG commands through a cmd() call if this is an easier solution to this problem. My second example code could easily be replaced with jog commands for instance.
Link to comment
Share on other sites

I think you are going to want to use our "move until trigger" functionality, either a motor jog-until-trigger, or an axis rapid-mode move-until trigger. These work like a homing search move except they do not reset motor zero position.


Since you are OK with software capture accuracy, you do NOT need to use one of the channel flags that is capable of hardware trigger -- you can use a general-purpose I/O point. The trigger DOES have to be on the 0-to-1 transition of the input bit.


(That said, many people use the encoder channel's USER flag input for this type of functionality. In that case, the only change from default you need for this is to set Gaten.Chan[j].CaptFlagSel to 3.)


To use a general-purpose input for this, you will want to have setup element values like the following for the motor:


Motor[x].CaptureMode = 1; // Hardware trigger, software capture

Motor[x].pCaptFlag = Acc68E[0].DataReg[2].a; // Address of input trigger bit

Motor[x].CaptFlagBit = 11; // Bit number of trigger on 32-bit bus


Then, for a motor command, you just need to issue a jog-until-trigger command something like:




This would go to motor position 1234 in the absence of a trigger, but if a trigger is found, it would return to the trigger position with offset 0.


Or for an axis command, you would issue a command like:


&1 cpx rapid abs x1.234^0

Link to comment
Share on other sites



Thank you for your reply. First let me say that I am a fan of the Power PMAC and respect the work you all do. I can appreciate that you folks did a lot of work to make the PPMAC as close to the PMAC2/Turbo as possible on the surface. I can also appreciate that you need to go to the register/bit level when configuring your ASIC chips to do hardware capture.


It would be great if in the future the PPMAC motion programming could get further away from the hardware when we can tolerate software performance. Maybe something like "until " command or "stop-if ", etc could be added to the motion parser? Expression could be something like "(MyGlobalVar = 1)" for instance. IMO these little things could be very helpful to aid in programming and readability of the code. Food for thought.


I will probably do a function call in C and hard-code the trigger to a dedicated external input for this application. If I need to re-use this code for something else I will have to change the trigger setup, but it is doable.


Thank you for your help.

Link to comment
Share on other sites



We do have those types of constructs in the motion program syntax. For example, you could use:


do {

inc X10 tm100


while (MyGlobalVar == 1)



But we think that providing an integrated structure like:




is much simpler for most uses for most people, even those who do not need the precision of hardware capture.

Link to comment
Share on other sites

Hi Curt,


User preference can be a real fickle thing! :o)


Is there any reason I couldn't send something similar to your code:


"&1 cpx do { inc X10 tm100 } while (MyGlobalVar == 1) dwell0"


in a command sent from C environment?


Also, am I correct in saying that code would stop within up to ten units (X10) from the point where MyGlobalVar changes value?. Is it just a matter of setting the increment units small enough such that the error is acceptable?


e.g. using inch units, with a 0.001" tolerance (and adding 0.0005" margin):


   X0.0005 tm50
} while (MyInput == 0)


I'll have to go for the training one of these days to get my head wrapped better around the more complicated moves. I've typically only done very simple point to point rapid moves in a single axis which doesn't require much of PMAC motion programming skill!


Most of my work with the Power PMAC has been in making it work as our entire machine controller and now I'm trying to refine our C++ API to include some of these basic motion tasks so that we can re-use more and more code and stay in our C++ editor for all but the most complex motion requirements.


Thanks again.

Link to comment
Share on other sites

I just wanted to say that I put everything in a buffered motion program and just abandoned the idea of putting all this in my C library. My end goal is to bump off of a hole to find center in XY. I have to say that the PPMAC's ability to have easy to use local variables scoped to a motion prog is very nice.


I scoured the manuals last night and really didn't find a good way to get X and Y position (actual or commanded) from any of the coordinate system commands or data structures and save it to the local variables. I can get motor position from the data structures but is there a way to get C.S. position directly when in a motion program? I found the pread command but that seems more for reporting to something like the send() command (i.e. text string).


Thank you.

Link to comment
Share on other sites

From within a motion program, the pread command would be the best way of getting present axis positions.


But I'm still trying to figure out why you are not using our triggered move constructs, which do this automatically for you. It seems to me you are trying to re-invent the wheel...

Link to comment
Share on other sites

The question about reading position is not related to the stop at input problem. I have that working well now and plan on rewriting it for the triggered move as discussed.


My end goal is to bump against the side of a hole with an electrical contact and get positions for X Center and Y Center. I need the absolute positions of +X, -X, +Y, and -Y to do this. Basically an electronic center find algorithm. How is pread used to get only one axis' position data?



XPlus = pread   //How does pread know to return only the X axis value??


I hope this makes more sense?

Link to comment
Share on other sites

Yes, that is how you would want to use the "pread" command.


For the center-finding algorithm, you may want to look at this Turbo PMAC application note that is on the forum:




It uses 3 move-until-triggers, with each post-trigger move coming back to the trigger position, and the X and Y final positions are read each time. From these 3 points, the center can be derived. Rather than using a single motion program, you could if you want command each move individually from C.

Link to comment
Share on other sites

Last night I went to rewrite my motion code to use your triggered moves as suggested and I had a heck of a time trying to get the IDE to digest the addressing for an IO bit on my ACC11E opto 24In/24Out card. 


My Mvar definition is:



ptr TouchSensor		->u.io:$A00000.11.1;	


but the IDE doesn't seem to let me assign u.io:$A00000  to the capture address. I've tried all the different combinations of this to no avail. 

Does the trigger register only work for axis card addresses? the reason I ask is that we are moving toward and all ethercat system down the road (Henry's Lx86) and I'd like to know if the triggered move solution works for EtherCat IO addresses as well as the ACC11E that we are using now.

Link to comment
Share on other sites

The correct syntax for this would be:




Here the "sys.piom", which is the value of the base I/O address in Power PMAC memory, performs the same effective function as "u.io:" in the M-variable definition.


As an old card, the ACC-11E does not have the circuitry for auto-detection by the CPU, so you have not been able to use Acc11E or GateIo data structures. But in V2.0 firmware, we added the capability for you to "manually detect" older cards like this, so you can access them through these data structures. If you make the following assignments:


GateIo[0].PartNum=603307 // ACC-11E part number

GateIo[0].PartType=8 // IO card


and issue a save command, then your ACC-11E can be used just like newer cards (ACC-65E, ACC-68E) that have the auto-detect circuitry.


So then you could use:






ptr TouchSensor->Acc11E[0].DataReg[0].3.1 // DataReg starts at bit 8 on 32-bit bus

Link to comment
Share on other sites

This topic is now closed to further replies.

  • Create New...