Jump to content
OMRON Forums

Clopedandle

Members
  • Posts

    56
  • Joined

  • Last visited

Everything posted by Clopedandle

  1. If you have the EtherCAT slaves's ESI file, or the device has its own file contained on itself, the setup software automatically maps/sets up basically everything for you.
  2. Set up reporting by setting Coord[x].TPCoords to specify which axes to report and Coord[x].TPSize to the number of moves ahead you need to report. Then just use "t" to show the current target position. If you want the next target position, just query Coord[x].TPData[1].Pos[j]. Per the software reference manual, page 819, i = 0 is always the currently executing move, so i = 1 will always be the next move (i.e. while the moves are executing). Querying them after all the moves are done will not produce meaningful information.
  3. Do you by chance have a USB drive inserted into the PPMAC? If so, make sure it does not have any of the folders with names listed in this post: http://forums.deltatau.com/showthread.php?tid=572 Especially make sure you do not have a folder named "PowerPmacFactoryReset" in the USB drive.
  4. Can you explain why you would need to do that? Like Steve said, you can just use modulo to calculate the angle within 360 degrees. If you mean you need a hardware output pulse every 360 degrees, you could set up position compare and use the EQU pins.
  5. You're welcome. 1. To start the program (assuming it's capp1.out) from a PLC, you can issue system "/var/ftp/usrflash/Project/C\ Language/Background\ Programs/capp1.out"; from another C program, use popen() or fork() and the path: /var/ftp/usrflash/Project/C\ Language/Background\ Programs/capp1.out 2. pshm->P[] and Set/GetGlobalVar are fundamentally the same. I prefer the syntax of the former. 3. I think you could safely push it to 0.001, although it may be pointless if your serial device is not providing data that fast. You can always try setting it that low and checking Task Manager to see if your CPU usage is going too high. 4. I believe it is atomic, but cannot remember completely. Perhaps a member of the ODT staff could answer? Curt?
  6. You can do this. Just make sure to put nanosleep() in your infinite loop, or you'll watchdog the PPMAC. You should also create a break condition variable so you can stop the program when you want. You can write your message to a global variable for convenience. First, assign these globals in your global definitions.pmh file; something like: global MySerialPortMessage, MyBreakConditionVariable = 0.0; Then, in your C program, you can make a loop like so: while(pshm->P[MyBreakConditionVariable] < 1.0) { //Write out the command to read display on meter... ret = write(SerialPort, SampleCommand, strlen(SampleCommand)); //If write() does not return the requested number of bytes to write, we have a problem. //Pass return code on to the calling routine. if(ret != strlen(SampleCommand)) { Send(1, "Problem writing to port!"); // Send to PPMAC's Send1 port return ret; } //Read back the string into the "msg" buffer... ret = ReadSerialLine(msg, EXAMPLE_CODE_RESPONSE_MAX, '\n', SerialPort, 10.000); if(ret) { Send(1, "Did not get a response from port!"); // Send to PPMAC's Send1 port return ret; } pshm->P[MySerialPortMessage] = atof(msg); MySleepSec(0.1); // sec } Where void MySleepSec(double SleepTimeSeconds) { struct timespec Timer; Timer = Sec2TimeSpec(SleepTimeSeconds); nanosleep(&Timer,NULL); } and struct timespec Sec2TimeSpec(double TimeSec) { struct timespec Timer; Timer.tv_sec = (long int)TimeSec; Timer.tv_nsec = (long int)((TimeSec-(double)Timer.tv_sec)*1000000000.0); return Timer; } To break your loop, just write MyBreakConditionVariable=1 from any program or the Terminal window.
  7. If you are not already, I suggest setting your drive to torque mode and letting the CK3E govern the control loop. It will likely be much easier to troubleshoot that way as you would then not have any of the drive's gains polluting your servo effort. I also remember in the past that there was a way to check if the distributed clocks were working by monitoring ECAT[n].DCClockDiff - see attached from the IDE manual, page 67. I am not sure if this still applies, however.
  8. I suggest you run the System Setup utility and set the system up from scratch. Assuming everything is wired correctly, you should be able to finish the setup and jog your motor within 30 minutes. For detailed instructions on using the System Setup utility (in the IDE, click Delta Tau-->Tools-->System Setup), download the Power PMAC IDE manual from FileDepot: http://forums.deltatau.com/filedepot/download.php?f=Power%20PMAC/Manuals/Power%20PMAC%20IDE.pdf [FILE REMOVED] System Setup starts on page 22. This is likely a much faster approach than watching the online tutorials. It would also be smart to get the Power Brick LV manual. If you want to set up the motor manually, start on page 110 and follow the instructions until page 154.
  9. The Position Compare feature would be more reliable for this, although its output comes from a dedicated connector, not from GPIO. See "Hardware Position-Compare Functions" starting on page 789 of the PPMAC User's Manual. It allows for digital outputs to be toggled at the exact programmed encoder count and will not miss any as the comparison is performed in hardware, not software. You just have to program your on/off positions (CompareA/CompareB) before you move to the "on" position. If you have uneven spacing, you have to set each one up beforehand. A common practice is to precompute all of the on/off positions, load them into Sys.IData[] elements beforehand and load them in to the CompareA/CompareB registers as you reach each position. This can be done in a simple subprogram call or you can use the capture-compare interrupt service routine (ISR) to do this. If you have even spacing, you can set up auto-increment, and PMAC automatically toggles the output as your motor counts pass through the preset spacing.
  10. Try using Motor[x].SlewMasterPosSf.
  11. Jack, Motor[x].SlewMasterPosSf limits the rate that the command is injected to the follower motor upon enabling the following feature. It basically ramps up to the ratio between master and follower specified by Motor[x].MasterPosSf.
  12. If you poll the velocity in a background script PLC, PMAC will guarantee that the polling will not affect servo/phase/RTI performance. It literally only polls "in the background" (i.e. when the CPU has completed all performance-critical tasks and has time to do other things). This will not be quite as accurate as polling at a set frequency, but for the purposes of tracking lifetime distance traveled (we're talking big numbers probably), it should be OK. Make sense?
  13. Yes, like Dave said, use a background PLC to integrate the absolute velocity value, write it to a global variable, and use the Fsave feature to write the value to memory periodically so that it persists across power cycles. See page 1090 for the fsave entry in the PPMAC SRM.
  14. I noticed this happened a ton when I had a large number of "send" commands in Script PLCs. You could try commenting those out if you have any to see if it helps. I never did get a solution from Tech Support on that, come to think of it.
  15. Unless I am mistaken, PMAC will automatically convert your M-Variable to a double equivalent when passing it to CfromScript, so you should have nothing about which to worry. As for using "null" as a return value, that looks wrong, but maybe it is something new with which I am not familiar. If I were you, I would just create a local variable named "dummy" or something to catch the CfromScript output as I have the feeling null might be reserved.
  16. For this kind of application, a basic Background C Application is the way to go. You can trap startup and exiting pretty easily that way. Just have your startup code run as the first block or function call inside where the template basically says "put your code here," trap your main communication loop in a while loop with a nanosleep() of some duration, a timeout condition, and a "check for kill flag," condition. If the timeout or kill flag go true, run your cleanup code block/function before you exit. I do not suggest using CPLCs for communication code.
  17. To the OP, yes, Sys.Cdata is the way to do this. Use char* pointers to write to this array in C and sprintf to write to it in PLCs. As for reading this and passing it to a start command in a PLC, I believe you can use the string formatting features of cmd"" to transfer the string living in Sys.Cdata to your "R" command. Another way around is to parse /usrflash/Project/Database/pp_prog.sym for all program name-to-number equivalencies at startup in a C program (in your case RTICPLC, so this would have to be the first of its tasks at powerup, and once done, never repeat that in further iterations), store those in a big array in user space, write the corresponding number of the program name you want to use to a Sys.UData array element, and call that using the start command in a PLC. This would mean a bigger startup, but ultimately probably less "communicating" for your RTICPLC to do.
  18. To be honest, in recent history (i.e. in the last two or so years), I have not needed such a fast servo rate as our applications are generally simple pick and place. However, just doing a quick check of the OMRON 1S product site, I see that they support a 125 us distributed clock, which would correspond to an 8 kHz transmission rate of EtherCAT packets, but like Curt said, that would translate to 4 kHz "actual" servo. I am not aware of another drive that can go faster, but perhaps one exists. To comment further on my experiences, basically the frustration emerges in having to learn so many different servo loop tuning tools if you are using drives from different manufacturers (e.g. Yaskawa, OMRON, Copley, Teknic, Panasonic, etc.), the quality of which varies greatly (OMRON/Copley are quite easy to use, however), as Curt said. These pieces of software usually drag you through a multistep process of selecting your mechanism, asking you what kind of application you have, and then doing potentially 1+ hours of auto-tuning moves before you can even start using the drive. This may be handy for a beginner, but once you understand how to tune each gain manually, it's basically a waste of time, in my opinion. Not only that, to change even a single gain from that point forward requires you to open the cabinet again, connect to the product again (usually through USB), load the drive's software, navigate through the menus until you reach the list of parameters, try to identify what a parameter is based on some parameter name that varies between manufacturers, adjust it, disconnect, possibly power cycle to retain the change, and then you can (probably) move forward. It's so much simpler to do all of the tuning right from PMAC if you know how. You can govern the velocity loop entirely through the velocity loop gains in PMAC's servo loop. Curt's really the expert on all of these kinds of topics, but I am happy to answer any other question from personal experiences.
  19. Personally, always putting the drive in torque mode so that you can control all the loop gains directly from PMAC is greatly preferable and generally much more convenient and flexible than plugging into 3rd party drives and using their tuning tools.
  20. You could also make a thread in a "background program" that that is scheduled to run at 2 kHz. Check out this document for details: http://forums.deltatau.com/filedepot/download.php?f=Power%20PMAC/Application%20Notes/Library%20for%20Custom%20Threading/Manually%20Scheduling%20Threads%20in%20Power%20PMAC.pdf [FILE REMOVED] Under Library for Custom Threading on FileDepot. Dump the packets you receive into a queue and process them in another thread (background is OK) to save computation time.
  21. Shawn, I've actually gotten it to work through Paramiko, but cannot share the code due to company restrictions. I can share some tips though. Create the paramiko SSH client Issue client.connect() with the PPMAC IP and port 22, default login and pass To issue basic Linux shell commands (such as "ls" or "top", "one and done" commands that do not require a sequence of inputs), you can use client.exec_command() To create a synchronous gpascii connection, it's a bit more tricky. First: gpascii_client=client.invoke_shell(term="vt100") gpascii_client.send("gpascii -2\r\n") wait a bit, about a second response = gpascii_client.recv(2048) response = response.decode() // need import sys if you get "STDIN Open for ASCII Input" in the response, you succeeded. If not, you did not. Then you can stringToSend = command + "\r\n" try: n = gpascii_client.send(stringToSend) Wait a bit (technically you should wait for recv_ready() == True) and then you can responseBytes = gpascii_client.recv(2048) Decoding the response is a little confusing so here: response = responseBytes.decode() response = response[(n-2):] # remove echoed command response = response.replace("\r","") response = response.replace("\n","") response = response.replace("\x06","") response here should be the final, human-readable response to the command you issued. If you issued echo 7 before, it might be easier to decode as it does some of the stripping for you. Also multi-step operations, such as changing directories and navigating through the shell, also must use the invoke_shell(), send(), recv() approach used above. Good luck and let me know if you have questions.
  22. The ModBoss strikes again.
  23. I encountered this too. Fixed it by making a new project and importing all the old project files through Add Existing.
  24. You can use the DLL with C++, but it is not native C++ code. To use C++ directly, you would have to write your own library, basically. Not impossible, but you have to be familiar with PPMAC, for sure. Getting the DLL to work with C++ is a bit of a hack (I got it to work years ago mostly just for fun), so C# is definitely preferable like KEJR said.
  25. My suggestion for clearer code is make more use of subprograms. You could give a subprogram name to each type of move you are trying to achieve (like that long PVT move you showed), and then calling then condenses to a single line in your motion program. You can also throw your conditionals inside the subprograms so they do not clutter up the top level motion program.
×
×
  • Create New...