Jump to content
OMRON Forums

KEJR

Members
  • Posts

    297
  • Joined

  • Last visited

Everything posted by KEJR

  1. Update: I tried just typing in "#define foo 2" into the global definitions.pmh file and it *half* worked. It made it into the PLC program I used it in. It did not work when I used it in a C program and naturally the compiler rejected the "foo" label. I'm going to file something with Bugzilla on this because it should either be easy to add this feature to C programs as the script that generates the .h header file from the pmh file jsut has to pass it on unmodified. KEJR
  2. I'll keep the Q var in mind if we go that route. I've been trying to find information on Ncalc and Nsynch but they don't appear in the online command or program command help or C library help. What are these features and where would I go to find the information about using them? Thanks, KEJR
  3. Brad, I like your method of using a handshake variable. It is clever but simple. In other systems I've used it was not possible because we were using bit flags and IO lines. If possible I would still like to use the built in methods so that we can develop our library such that a Machine programmer (including me) doesn't have to think about it. It looks like the possibility is there. I'm taking away from your reply that the status of Coord[].TimerEnabled is true when a motion program is running in the specified C.S? So yes if we wait one RTI and then wait for Coord[].TimerEnabled to be reset it will tell us that the motion program completed and that we are either completed the motion prog or bailed out of the motion prog due to an error. If we then check for errors we will cover all bases. While the Appware you mentioned seems like a good thing for diagnostics and such I would prefer to use a method that is in the C library or through the data structures if possible. The code I'm writing will be called from realtime threads. Is it just a matter of inspecting certain elements in the coordinate system data structures? Any advice on which ones to inspect would be appreciated. Thank you for your help, KEJR
  4. The July release IDE won't let me add a C header file. I just tried it and it barked about the fact that the file must end in .c or .h even though my file did ened in ".h" Besides, if you do a "#define" in a .h file can you use that from within your script programs (using the same file)? KEJR
  5. Hi Charles, Thanks for the link. I had contributed to that thread ;) I'm using global *variables* now already. What I'm after is a way to define global *constants* that get used like C preprocessor statements in both script and C programs. In fact when used in C it [preferably] could just be a "#define" directive. If I use a global var I have to be careful to both initialize it and then call GetGlobalVar() to return the constant when working in C. While this can be done, it is alot more dangerous and involved than using a preprocessor directive. I'm open to any ideas. Thanks, KEJR
  6. Hello, Is there a way to define constants in the global definitions.pmh file? I want to refer to many things by name such as motor numbers, Coordinate systems, and motion/PLC Programs. I want access to these in script programs as well as C programs. I might be able to get by in my C programs by referring to the motion and PLC programs as strings and using the command interpreter. I'll need constants on the motors and C.S.'s though since I'll be accessing them through the data structures, function parameter passing, etc. Thanks, KEJR
  7. Hello, I would like to develop a generic C function call that starts a script motion program and then monitors for the motion program to be completed and with no errors. One could say it is simple as the following: - command motion via command interpreter - wait for motion to start by monitoring some status - wait for motion program to be ended. - Check for errors and optionally in-position. There is kind of a catch 22 situation with motion controllers when the motor happens to already be at the end point. Depending on timing if you use the above method your motion program could end before your calling thread can recognize the "motion start" or "motion in process" signal. Alternatively a short motion might have the same problem. On other "primitive" motion controllers I've had the motion program delay 10ms or so if it was already at the end point when the program was called. Besides making the motion prog more complicated than it needs to it adds time delay for no reason. So my question is that is there a tried and true method for doing what I described above without having to declare additional handshake interlock variables? Thanks, KEJR
  8. I'm running a C#.net program on that PPMAC using mono that queries variables every 100ms currently. I'm not experiencing the memory growth. I'm using DllImport though. While I don't know a solution to your problem exactly, let me make a few suggestions. I'm not 100% familiar with VB.net syntax, so some suggestions might not be spot on: - Don't initialize the PPMAC library from your method. While I can't say this is a problem, it is certainly inefficient to be calling those functions every time you want to run a Pmac method. I created a static "Pmac" class that gets initialized at program start and closed at program end using methods in that class. Then create wrappers so you can do "Pmac.GetVar()" and "Pmac.GetResponse()" and that kind of thing. - Check to see if the string that you return every gets cleaned up. I am not a .net or PPMAC expert, these are just my observations. KEJR
  9. Thanks Charles, I had been thinking originally of doing exactly what you suggested but I was cautioned against it because it could have undesired results. What I have been thinking of in light of all this information is to do a smart detection of the cards, and if there is not a card detected at a certain address just go ahead and assume it is an older card and clear its registers. I have to do more testing but I don't see how clearing an input register would be a problem as it should get overwritten by the status of the real input words. I thought I tested this even without setting the control word and it worked OK. I think I'll need more testing. Thank you, KEJR
  10. Do you have DNS set up properly? You should be able to test this by pinging your remote computer by name: e.g. ping SomeComputer instead of ping 192.168.0.1 KEJR
  11. We are using the older IO cards. We use all sinking drivers (company wide) and from what it says on the website the newer cards are all sourcing. I'm checking with our distributor to see if these might be available. The Website doesn't list the old 48 bit input and output cards which is disturbing unless I find an equivalent replacement with sinking IO. I'm using these assembly numbers: 603307-101 (24IN/Out Sinking 24VDC) 603283-100 (48 bit input card 24VDC) 603299-101 (48 bit sinking Output card 24VDC) Thanks for the help though. If I get into the newer cards this information will help. KEJR
  12. I want to reset output cards generically. The 24In/Out and the 48 bit output cards are the ones we have used in the past and are likely to use again. For now it looks like we will be stuck defining Ptr vars for 8 bit access and resetting all of them manually in a startup script. Its not horrible but something our machine programmers will have to do that we don't currently have to do on other systems (PLCs, robots, etc). I was hoping for something that would be generic such that my C library could zero the IO memory at all possible base addresses, or have a way to query which IO boards were installed (similar to how PCI boards are done) and initialize only the output cards. For a machine with one or two cards its not a big deal, but if you have 3-5 cards that is a lot of inline coding that is quite redundant and prone to cut/paste mistakes. Any ideas? Thank you, KEJR
  13. After reading the manual about "$$$" and doing a test this is definitely not what we want. This command reloads the project from flash memory in addition to resetting everything. In addition the "$$$" seems to lose some connections with the IDE. I at least lost connection with the unsolicited messages window. I'd hate to lose my testing code just to reset all of my output cards. Is there a command to just initialize the IO cards (in a generic sense)? Thanks, KEJR
  14. Thanks Sina, This is exactly what I was looking for. I am familiar with $$$ from the turbo processors, but it is sometimes odd translating that to PPMAC since it is such a different animal. Doing a global reset at program start is something we will definitely want to do. KEJR
  15. I got an internet link to these instructions (I think from BradP originally) for a similar problem with "FogBugz" add-in, but if you replace the fogbugz add-ins for the PPMAC addins the instructions are identical. I think I got this from Brad in an email a while back: Cause: The add-in is installed on a network drive, probably because your home directory ("My Documents") is located on a server on your Intranet. Solution: Copy the add-in to a local hard drive, by following these steps: 1. Say "No" to the error message -- do not remove the add-in. 2. Exit Visual Studio. 3. Make a directory on your hard drive, for example c:\Program Files\FogBugzForVisualStudio. The name doesn't matter but it does need to be on a local hard drive, not on the intranet. 4. Find the two files that make up the add-in. They should be located in "My Documents" in a subdirectory called Visual Studio 2005\Addins. The two files are: o FogBugzForVisualStudio.AddIn o FogBugzForVisualStudio.dll 5. If the .AddIn file ends with an underscore (FogBugzForVisualStudio.AddIn_), rename the file to remove the underscore. 6. Move those two files into the directory you created. 7. Run Visual Studio 2005. 8. Choose Tools | Options 9. Go to the Environment | Add-in / Macros Security tab 10. Click Add and point to the directory where you put the add-in 11. Click OK 12. Restart Visual Studio 13. Choose Tools | Add-in Manager and check the box next to FogBugz for Visual Studio. Also check the box in the Startup column. 14. FogBugz for Visual Studio should load. More details: FogBugz for Visual Studio is a .NET assembly. When Visual Studio loads add-ins in the form of .NET assemblies over a network from the Intranet zone, it does not completely trust them. This generates a security violation.
  16. Hello, I would like the ability to clear the contents of all IO boards in the system upon program start (in a C program). Is there anything provided for this, or is it as simple as doing a clear of memory for all possible cards in the "io" address space? Since am trying to provide this as a library call across various machines I don't want to assign M variables and "manually" clear each byte one by one. Assigning 0s to io space would only work if potential IO cards would respond to this in a safe way. We would do any "non default" initialization of the IO cards after they are cleared. Any ideas? Thank you, KEJR
  17. Sorry for the inconvenience, I solved my own problem. I forgot that the delta tau IO cards run the LED's off of the 24V supply which I did not have hooked up on my "software development" rack. I seem to be able to address all of my outputs now (and presumably the inputs too although I have yet to test). Thank you, KEJR
  18. I am having issues in using my ACC-11E 24In/24Out card. I have mapped ptr vars to the bits by using the suggested m var definitions document, but I can't get an LED to turn on on my outputs (simple test to see if I'm addressing the board properly...). Here is how my card is configured: E1 (ON) E2-E4 (OFF) E5 (2-3) E6A-E6H (1-2) On a turbo system this would start at: Y:$078C00 I believe. For lack of any other documentation (That I am aware of) I assigned the suggested mvar definitions for IO card 0, such as: "ptr IoCard0Pt00->u.io:$A00000.8.1; // I/O Card 0 I/O00" Now using the terminal I'm trying to write 1 to the different addresses and nothing seems to happen to the LEDs. Do I have the board address wrong? For kicks I also wrote $07 to the control register to make 0-23 input and 24-47 output. This did not seem to help any. Any ideas? The only other card in the system is a macro card if this is important to know. I have not programmed the macro card at all yet. Thank you, KEJR
  19. KEJR

    M Variable Access

    I agree with what Curt said. Just to elaborate a little on my past posts, If you are trying to figure out what is actually going on in your C code add a test global to your "global definitions.pmh" file: global footestglobal; global foo2; Now hit build, and then open "../../Include/pp_proj.h" in a text editor. you will see something like this: #define footestglobal 8192 #define foo2 8193 This is because the IDE by default starts allocating globals at 8192. This is what is automatically generated by the IDE and it happens at compile time. Now in your C code you are including "../../Include/pp_proj.h" so now your function call to get global variable will evaluate to something like this after the C preprocessor : MyScaledResult = (200* GetGlobalVar(8192)) / 3; Make no mistake, however, don't refer to your variable in any shape by P8192, or 8192 directly. Refer to it always by "footestglobal", or whatever name you give it. The 8192 is auto generated, so forget its there, it just is a way to give the C compiler the name in a C friendly way (#define directive in an include file). KEJR
  20. KEJR

    M Variable Access

    See edlay's response in a previous thread: "In your "global definitions.pmh" you have your M-ptr definition ptr MyPtrVar1->*; " Of course to make it do anything of much use you would want to map the M variable to something useful. KEJR
  21. KEJR

    M Variable Access

    In my example the MyPtrVar1 is defined in the delta tau IDE under global definitions. (PMAC Script Language / Global Includes / global definitions.pmh) What happens is that the IDE auto assigns unallocated P var indexes to your text name. The cool thing is that it is useable in the script programs, terminal, and C programs. The way they get brought into your C program is with the following include: #include "../../Include/pp_proj.h" There are other posts on here regarding global variables I believe, and there are some example C app projects installed with the IDE I think. KEJR
  22. Hello, Do you guys have any issues with the compile time on the IDE? I have a Pentium 4 (D) 2.8GHz machine and it takes at least a minute to compile and download a very minimal C application. I know this is an older machine, but on linux a GCC session normally compiles in less than a dozen seconds. I don't know if this is my machine or if the IDE is that slow. My other applications seem to run at a decent speed. My IDE version is 7/22/2010 and the version is 1.1.0.26 Thanks, KEJR
  23. KEJR

    M Variable Access

    The global vars are nice, you don't have to type in hard M or P vars. I just want to point out that you don't have to declare another double in your code. You can do this kind of thing: MyScaledResult = (200* GetPtrVar(MyPtrVar1)) / 3; it makes a difference if you are using alot of Ptr vars or global vars. I personally don't like the GetPMACVar() function because of its possibility of throwing a run time error if you misspell the string. It is considerably slower too. Something to note if you are doing alot of global var manipulation. KEJR
  24. I apologize but I haven't been able to recreate the problem. I tried changing the case on the spelling and the IDE caught the mispelling and threw an appropriate error. I'll report back if/when the problem comes back and try to note what it was that I did differently. Thanks, KEJR
  25. I haven't prettied up this code yet, but I thought I'd post it as it could be real useful for someone doing general purpose Xenomai programming that just needs to create a bunch of periodic threads. I found that there weren't alot of Xenomai example programs that were simple and used the POSIX skin. This code gives the following: - C routine for getting time in seconds (same result as in script languages) - "Sendf()" ... DT's "Send()" meets "Printf()" - CreateThread() routine that deals with the nasty POSIX calls for you Any feedback is welcome as I would like to improve my code if there are mistakes. To use this code copy it into your "Background Programs" section of the IDE and select "Build and download". Once the code is executed you should see some output in the unsolicited messages window such as this: Port 1: Told to run 103 loops at 1ms periods, Elapsed time: 0.1030 seconds Port 1: Told to run 201 loops at 1ms periods, Elapsed time: 0.2010 seconds Ultimately I will be stripping this code into its own "C" file and only exposing the few routines in a header file that will get used in a machine program. Right now it is ugly all in one file but I thought it would be simple to post to the forum this way. ***** Start of file **** //-------------------------------------------------------------------------------- #include #include // Global Rt/Gp Shared memory pointers //------------------------------------------------------------- // The following is a projpp created file from the User defines //------------------------------------------------------------- #include "../../Include/pp_proj.h" #define SEND_MAX 128 //Define some global variables... static const int ThreadRetOK = 1; static const int ThreadRetFail = -1; //Global pointer to shared memory which is useful for Delta Tau //data structure retrieval. SHM *pSHM; //This structure is used to pass this information to our thread shell routine. struct thread_parameter { void (*func)(void *); void * arg; const char * name; }; //Returns current time in 64 bit floating point 'seconds' //Ths is useful for general purpose timing.. double GetTimeSec(void) { return 1e-6*pSHM->ClockSF*u64btod(fclock()); } //Formats a message to send to the Send port, up to 'SEND_MAX' chars... void Sendf(int SendPort, const char *fmt, ...) { char msg_buf[SEND_MAX]; va_list args; /* format string */ va_start(args, fmt); vsnprintf(msg_buf, SEND_MAX, fmt,args); va_end(args); Send(SendPort, msg_buf); } //This function is passed to pthread_create(). It is a wrapper around the //user called function. This wrapper is important so that normal users need //not be concerned with the POSIX services, etc. //Since pthread_create() expects ths function prototype we had to abide //by it. The argument passed to it is in fact a structure pointer //so we are able to use that to pass this routine alot of information such as //the user function name and arguments, as well as the thread name so we can //make more meaningful error messages. void * thread_shell(void * arg) { struct timespec start; struct timespec period; int retval=0; struct thread_parameter *param; param = (struct thread_parameter *)arg; //Set up some time parameters needed to make thread periodic... start.tv_sec = 0; start.tv_nsec = 0; period.tv_sec = 0; period.tv_nsec = 1000000; //Wake thread every ms //Now that thread is created we want to make it a periodic task //so that it wakes up every period if it is suspended. if(retval = pthread_make_periodic_np (pthread_self(), &start, &period)) Sendf(1, "Failed to make thread '%s' periodic. ret: %d, ESRCH: %d, ETIMEDOUT: %d\n", param->name, retval, ESRCH, ETIMEDOUT); (*param->func)(param->arg); //execute the real thread function now that we have gotten it ready... return ((void *) &ThreadRetOK); } int CreateThread(pthread_t *ThreadID, const char* name, void (*ThreadFunction)(void *), void * arg) { struct thread_parameter param; int retval=0; pthread_attr_t attr; size_t stackdefault; //Copy parameters in so we can pass it to thread shell function... param.func = ThreadFunction; param.arg = arg; param.name = name; //Set attributes of thread, such as stacksize and scheduler type pthread_attr_init(&attr); //Set Scheduler policy retval = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); if(retval != 0) Sendf(1, "pthread_attr_setschedpolicy()' for thread: %s. Returned: %d\n", name, retval); //Do the actual thread creation... retval = pthread_create(ThreadID, &attr, thread_shell, (void *)¶m); if(retval != 0) Sendf(1, "Failed 'pthread_create()' for thread: %s. Returned: %d\n", name, retval); //Give the thread a name so that we can identify it... retval = pthread_set_name_np (*ThreadID, name); if(retval != 0) Sendf(1, "Failed 'pthread_set_name_np()' for thread:%s. Returned: %d", name, retval); //return the threadID so that calling routine can reference it return retval; } void InitMain(void) { /* Avoids memory swapping for this program */ mlockall(MCL_CURRENT|MCL_FUTURE); InitLibrary(); //Init DT library. pSHM = GetSharedMemPtr(); //Initializing the pointer to the shared memory } void CloseMain(void) { CloseLibrary(); //Close DT library } //Example test thread void ThreadCode(void * arg) { double StartMeasure; int i; int retval; int NumLoops = (int)arg; StartMeasure = GetTimeSec(); for(i=0; i
×
×
  • Create New...