Jump to content
OMRON Forums

daves

Members
  • Posts

    261
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by daves

  1. I'll start by admitting I think that after looking at the manual, I have made a bad assumption about the syntax structure of while (and possibly if) statements. What would you expect to happen on running this code? open plc 3 p4 = 0; p3 = 0; p2 = 0; p1 = 0; while (p4 == 0) if (p3 == 0) p2++; p1++; disable plc 3 close I see p2 and p1 incrementing. I would expect only p2 to increment (until p4 is set non-zero). Please, someone tell me if I have made an obvious mistake ;) I know strictly speaking the manual describes single commands on the same line as the condition or blocks enclosed in braces. I think my code should at least fail the download as it produces (seemingly) illogical results. If you don't have the if statement then it functions as expected. This fact combined with the purported C-style script syntax led me to believe this was OK, and took a confused period of time to spot. Can anyone explain the logic of the p1++ line getting dragged into the while loop? I would like to understand the script flow better. Really I would like this to function as it would in C, or can the downloader fail with an error? Cheers Dave
  2. GetPmacRunTime() from the API seems to be the same as Sys.Time. I use GetCPUClock() from the API to time things which returns the current time in microseconds. These are some time related functions in the API if useful: /// Get Pmac Time of Day in seconds since Jan. 1, 1970 extern double GetPmacTimeOfDay(void); /// Get Pmac Run Time in seconds since Pwr On or $$$ extern double GetPmacRunTime(void); /// Get CPU Clock in micro-seconds extern double GetCPUClock(void);
  3. The timing/sleeping method advised to be used in C loops etc seems to have broken in the latest firmware. After a lot of investigation into freezing downloads and failed reboots I have narrowed the problem down to a repeatable example: int main(void) { struct timespec SecSleeper = {0}; // Initialize time structure SecSleeper.tv_sec = 1; // 1e9 nanoseconds, which equals 1 sec SecSleeper.tv_nsec = 0; // 1e9 nanoseconds, which equals 1 sec InitLibrary(); pshm->P[1] = 0; // Main loop just keeps us running while (1) { printf("Dummy\n"); pshm->P[1]++; pshm->P[2] = nanosleep(&SecSleeper, NULL); pshm->P[3] = errno; } CloseLibrary(); return 0; } Run capp1.out on v1.4.0.27 from a putty terminal and you see "Dummy" output once a second, looking in watch window shows P1 incrementing once a second. The return value P2=0 (success) and errno P3=0 (no error) Run capp1.out on v1.5.3.0 from putty terminal and you see "Dummy" output constantly, looking in watch window shows P1 incrementing almost 100,000 time a second. The return value P2=-1 (failure) and errno P3=1 (EPERM, operation not permitted) This looks like a Xenomai error saying the calls are coming from an invalid context. Reverting to 1.4.027 fixes the problem. I will have to do this as I have many C apps and CPLCs which rely on this method. Or is there a new method for timing in PPMAC? Can you confirm you see the same issue? The August IDE complains about the firmware now so please can I have instructions on how to downgrade the IDE cleanly?
  4. The FileDepot "Power PMAC Suite (08-09-2012).zip" file under the SplitZipped folder tries to download the full 1GB file rather than the initial part of the split zip (on my system anyway). I got the correct file from the FTP download.
  5. How do I implement an early exit from a sub procedure (in a motion program)? I can't get it to work or the script parser can't handle it. I want the following: sub: MoveDOffLimit(ID, PerEU, HomeVel, &Error) local iLim; if (AxisSimulate(ID)) return; callsub sub.GetDOnLimit(ID, &iLim); if (iLim) // Code removed return; This gave error "invalid parameter number in equation : R0=ID CALLSUB 10003 iLim=R1" I thought that was a hint to move iLim... sub: MoveDOffLimit(ID, PerEU, HomeVel, &Error) if (AxisSimulate(ID)) return; local iLim; callsub sub.GetDOnLimit(ID, &iLim); if (iLim) // Code removed return; but that just gave error "invalid parameter number in equation : R0=ID CALLSUB 10001 L0=R1" so I ended up having to do sub: MoveDOffLimit(ID, PerEU, HomeVel, &Error) local iLim; if (AxisSimulate(ID) == 0) { callsub sub.GetDOnLimit(ID, &iLim); if (iLim) // Code removed } return; but this doesn't seem ideal
  6. Hi, thanks, here is more info Pro1: PComm32.dll 10.48.0.0 Pmacusb.sys File: 4.2.4.1 Product: 4.0.0.0 PmacServer.exe 1.0.1.745 USB That function is Pro2 and we are currently interested in an explanation of the problem found using Pro1 drivers. When we 'attach' to the PmacGetResponseA function in the DLL we use the following prototype and code typedef long (CALLBACK* GETRESPONSEMETHOD)(DWORD Device, PCHAR Response, UINT MaxChar, PCHAR Command); FGetResponse = (GETRESPONSEMETHOD)GetProcAddress(hPMACLib, "PmacGetResponseA"); I have not seen PMACDownload() but Download() is also Pro2. We attach to PmacDownloadA using the following prototypes and code: typedef long (FAR WINAPI *DOWNLOADGETPROC)(long nIndex, LPTSTR lpszBuffer, long nMaxLength); typedef void (FAR WINAPI *DOWNLOADPROGRESS)(long nPercent); typedef void (FAR WINAPI *DOWNLOADMSGPROC)(LPTSTR str, BOOL newLine); typedef long (CALLBACK* DOWNLOADMETHOD)(DWORD Device, DOWNLOADMSGPROC msgp, DOWNLOADGETPROC getp, DOWNLOADPROGRESS prgp, PCHAR FileName, BOOL Macro, BOOL Map, BOOL Log, BOOL Download); FDownload = (DOWNLOADMETHOD)GetProcAddress(hPMACLib, "PmacDownloadA"); As described these work most of the time. But we now have a type of PC which repeatedly fails with the originally highlighted line of code removed and repeatedly works with the line in. Previous attempts at coding a downloader in Delphi, C++Builder, and also VC++ using the Pro2 interface have always been unsuccessful (we use all the other API functions easily). That is why I requested some example projects using the download functionality (Pro1 or Pro2). I guess we will revisit the Pro2 drivers as maybe we understand more now than we did then. However some explanation of the original phenomenon would be appreciated to rebuild confidence... and our customer wants some reassurance. Thanks Dave
  7. We have a utility we wrote to download code upgrades to our customers so they do not have to get involved with the intricacies of PEWin and multiple commands/downloads. They just click a button. It uses uses the old PMACServer DLL library communications method. We build it in Borland C++ Builder 3. I know these are old. Now we are in the situation where an important customer found it didn't work on their PC and are now broadcasting our system is poor. We narrowed down the differences in the program on their system between working and not working to one section. Basically in simplified pseudocode we have: Initialisation Code FPMAC->GetResponse("m800", &Response, &Error) Check response is good FPMAC->GetResponse("ver", &Response, &Error) !!!!! Check response is good FPMAC->GetResponse("$$$", &Response, &Error) Sleep 2s FPMAC->GetResponse("p7001..7109", &Response, &Error) Store response FPMAC->GetResponse("$$$***", &Response, &Error) Sleep 2s FPMAC->GetResponse("PASSWORD=xxxxxxxx", &Response, &Error) FPMAC->GetResponse("i5=0", &Response, &Error) Sleep 1s FPMAC->DownloadFile(MsgProc, ProgProc, "#XXOMNI.PMC", True, True) etc On particular PCs (these happen to be Intel Atom PCs) the program fails if the line marked !!!!! is not included. The failure symptom is that based on the output from the message callback and log file, the file is compiled ok but when download occurs we get 'Downloaded 0 lines'. Then no warnings no errors. The PMA file is zero bytes. Put the ver command back in and all is fine again. We cannot see how that line and the position it is in could affect anything unless it is clearing a buffer or something. We have lost all confidence in using this library. Can anyone explain this? Also do you have any examples which actually use the DLL PmacDownloadA function we can see in case we are not doing something quite right? Thanks Dave
  8. Is there an easy way to zero all Ptr and Global variables on download? I find that I am running a project using lots of variables, then I need to add a new one, so I put it in my pmh file (say in the middle). I think this is then getting assigned a P/M number in the middle of the list (say 8836) which causes all the ones following that in the file to get shifted. I think (my investigations have lead me this far but I could be wrong) this is causing variables to start with unsatisfactory values from the previously preceding variables (in my case this blows up some filters) I know I should be initialising my variables to safe values but I wonder if zeroing the memory on download (like seems to happen on power up) would be a nice safe condition?
  9. Oops, my Friday brain wrote that second line of code which doesn't actually do anything. In reality I have a global utilities h file with amongst other things void DoPLCC(int PLCC, int Value) { char buffer[25]; sprintf(buffer, "UserAlgo.BgCplc[%d]", PLCC); SetPmacVar(buffer, Value); } void DisablePLCC(int PLCC) {DoPLCC(PLCC, 0);} void EnablePLCC(int PLCC) {DoPLCC(PLCC, 1);} So I can just call DisablePLCC(THISPLCC);
  10. I would be interested to know if there is a simple system variable for this too. Currently I use the following define at the top of the file which isn't too bad #define THIS_PLCC 3 and then use SetPmacVar((char *)"UserAlgo.BgCplc[THIS_PLCC]", 0); to self-disable. Also I think you should know I had various crashes after manipulating pshm->UserAlgo.BgCplc[iNDEX] in C code (reading is OK) and was told to use the above syntax (see post http://forums.deltatau.com/showthread.php?tid=604&pid=2128&mode=threaded for a good discussion on this and other CPLC flow control issues. If you really need a generic method, a messy option for CPLCs (I guess not PLCs) may be to parse the __FILE__ macro which gives "bdccplc03.c" etc on my system, assuming you haven't renamed the file...? Dave
  11. I think this is very nice. Thanks for the idea. Now I just have to decide when is a good time to go through and delete all the GetGlobalVar/SetGlobalVar calls!
  12. Hi Firstly I am really pleased about the script mode and enum access to global variables. I would like to suggest an improvement and it looks like the code is almost in the pp_proj.h but not quite finished... In the _PPScriptMode_ section you have 'enum globalP' and the XXXEnumGlobalXXX() functions, but they seem to be pointless (the enum is not generated). Is this right? In my code I use a structure representing an axis and store references to my variables for that axis in the structure. I currently store the P or M number, then I can pass instances of the structure to a function which can then call SetGlobalVar on the reference to perform actions common to each axis. For example... struct AxisObject { int Param1; // A parameter each of my axes has }; struct AxisObject A1; // Two instances of an axis struct AxisObject A2; void InitAxes() // Set up the references { A1.Param1 = axis1Param1G; // Reference to 'global axis1Param1G' A2.Param1 = axis2Param1G; // Reference to 'global axis2Param1G' } void AxisWork(struct AxisObject A) // Do something to an axis { SetGlobalVar(A.Param1, 100); } Now I cannot use the script mode access (and I really want to) as I cannot pass a reference to a P variable anymore. Also trying to use the script mode GetGlobalVar as defined in pp_proj.h does not work, so you cannot mix modes. My solution (which works, I have manually coded it) is to fill the global enum as well (as it appears your intention may have been?) and give the option of calling both methods (Note the _ID suffix for the enum access): New pp_proj.h generation (similar to what _EnumMode_ does): enum globalP {_globalP_=-1 ,axis1Param1G_ID=8192 ,axis2Param1G_ID=8193}; #define axis1Param1G pshm->P[axis1Param1G_ID] #define axis2Param1G pshm->P[axis2Param1G_ID] Then: struct AxisObject { enum globalP Param1; }; struct AxisObject A1; struct AxisObject A2; void InitAxes() { A1.Param1 = axis1Param1G_ID; A2.Param1 = axis2Param1G_ID; } void AxisWork(struct AxisObject A) { SetGlobalVar(A.Param1, 100); } This works beautifully for my needs (and has some type-safety), does not affect 'normal' script mode access, and seems to fill the missing code in pp_proj.h. What do people think? (I have not considered arrays) Dave
  13. Hi KEJR I just thought I would add that your example works (script and enum) on my (Sept 1.4.0.62 IDE, 1.4.0.27 firmware) system where I did an uninstall-reinstall. I do remember seeing the _PPScriptMode_ not working at some point on my systems and I think that was with an upgraded IDE. Does your pp_proj.h file only have entries for foo and bar in the 'bottom section'? Mine contains the following (edited): #ifdef _PPScriptMode_ ... #define foo pshm->P[8192] #define bar pshm->P[8193] ... #else #ifdef _EnumMode_ enum globalP {_globalP_=-1 ,foo=8192 ,bar=8193}; ... #else // ***** Standard default mode ***** #define foo 8192 #define bar 8193 #endif #endif I would also mention I found uninstalling and reinstalling a bit of a hassle to get past the "Cannot find one or more components" "CreateFile failed" errors, deleting registry keys, InstallShield folders, MySQL installs and reinstalling VS shell stuff which are mentioned in other posts... I really like the fact that the script mode has far more readable lines of code and uses the fastest P[] access method. I do however have some other questions/requests for my purposes but I won't hijack your thread. Dave
  14. Hi Henry I think I remember this UDP example being developed with/for us and I see our company name still in one of the comments! I also spotted a bug on line 134 of the host: memcpy((unsigned *) + pEthCmd->wValue,pEthCmd->bData,pEthCmd->wLength); I think should be memcpy((unsigned *)pushm + pEthCmd->wValue,pEthCmd->bData,pEthCmd->wLength); Otherwise you get a segmentation fault on the first SETMEM Dave
  15. 1) My TCP server logic structure is very different from the UDP example (see below). I modified the UDP example to call every 2ms and only saw 10% CPU, this was using the loopback client. I'm not sure how you made your test. 2) I made the UDP example transfer 32767 bytes (I had to enlarge the buffers to allow this, I assume you did too. My TCP program splits large commands into 1400 byte packets). This gave an apparent rate of 10MBytes/s, but it is hard to know where to do the timings on this to get a representative value. I have not got those numbers on my server performance but I am running 6hr intensive test (~10x my requirements) without problem. 3) I gave up on the RTDM sockets as after I fixed a bug I was seeing acceptable performance. My TCP server uses some of the ideas in the UDP example. In particular I use EthernetCmdProc and the PETHERNETCMD structure Henry posted as the core processing of packet data (GetMem, SetMem, and I also implemented a GetResponse). Here is my TCP architecture in pseudocode (there is a lot more error checking and breaking out of loops correctly). It took a long time and a lot of research to combine all the various examples on the web which seemed to deal with one aspect whereas for robustness you need all aspects! --- INITIALISATION signal(SIGPIPE, SIG_IGN); --- Ignore errors writing to broken pipe and take as disconnection --- MAIN LOOP --- to recover from broken server socket while (1) { --- Set up socket socket(AF_INET, SOCK_STREAM, 0) bind() listen() --- Server is only active socket to listen to at first FD_ZERO(&sactive); FD_SET(sockfd, &sactive); --- INNER LOOP --- to wait for data/keep track of clients while (1) { --- Check for data (no timeout gives low CPU...) sready=sactive --- select on copy of active set as it gets modified select(FD_SETSIZE, &sready, NULL, NULL, NULL) for (i = 0; i < FD_SETSIZE; i++) if (FD_ISSET(i, &sready)) --- Data from someone if (i == serversock) --- It's a client talking to the server accept FD_SET(csock, &sactive); --- Store as an active client else --- It's a message from an existing client read() EthernetCmdProc write() --- FD_CLR() on any failures to treat as disconnect } } The key points are A) understanding the select() mechanism, I would try and google it as much as possible. Of course there are other mechanisms (multi-threaded, forking) but I found the blocking select() approach to be very good. B) Using a fd_set to keep track of clients. C) Handling all error conditions and dropping back to a recovery state, I want my server to run on PPMAC and never need to be manually restarted no matter what abuse comes down the network. I use a combination of all errors I've seen on my google-sourced examples (the examples usually handle one type of error) I hope this makes some sort of sense and helps you on your way... Dave
  16. Hi Steven I would like to help out but I am unsure what my company would think about giving all the code out (my boss is away). Plus I am still finding and fixing bugs in it so wouldn't necessarily want to inflict it on anyone! I will try and put together an outline of what it does without giving away our 'secrets' until I find out about publishing some code. When I get chance I will reply again... Dave
  17. Sorry, after some recoding I think the high CPU usage was due to inefficiency in my code. This post can probably be ignored unless out of interest you think I should have been able to compile the RTDM stuff (might it be necessary when code complexity or my network traffic increases?)
  18. I have implemented my own TCP library so my Windows application can get and set blocks of user shared memory (basically a Dual Port Ram emulator). This works well. However I am seeing a process called 'gatekeeper/0' running at high CPU (20%). I have read up on xenomai real-time socket programming and discovered I am having a lot of unwanted Mode SWitches. The recommended approach is to use the RTDM functions (access the drivers using rt_dev_* functions). The rtdm.h header appears on the PC folders: "C:\Program Files (x86)\Delta Tau Data Systems Inc\2.0\Power PMAC Suite\powerpc-460-linux-gnu\opt\eldk-4.2\debian_rootfs\usr\local\xenomai-2.4.10\include\rtdm" and "C:\Program Files (x86)\Delta Tau Data Systems Inc\2.0\Power PMAC Suite\powerpc-460-linux-gnu\opt\eldk-4.2\debian_rootfs\usr\src\xenomai-2.4.10\include\rtdm" On the PPMAC it is in "./usr/local/xenomai-2.4.7/include/rtdm/rtdm.h" "./usr/local/x3/include/rtdm/rtdm.h" "./usr/local/xenomai-2.4.10/include/rtdm/rtdm.h" But I cannot get it to build. I get errors of the form "C:\ABD\PowerPMAC\SPMM\Centre\Centre\Centre.ppproj(249,5): Error : tcptest.o: In function `SetUpSocket': C:\ABD\PowerPMAC\SPMM\Centre\Centre\C Language\Background Programs\tcptest\/cygdrive/c/ABD/PowerPMAC/SPMM/Centre/Centre/C Language/Background Programs/tcptest/tcptest.c(27,0): Error : undefined reference to `rt_dev_socket'" and "C:\ABD\PowerPMAC\SPMM\Centre\Centre\Centre.ppproj(249,5): Error : tcptest.o: In function `rt_dev_bind': C:\ABD\PowerPMAC\SPMM\Centre\Centre\C Language\Background Programs\tcptest\/opt/eldk-4.2/debian_rootfs/usr/local/xenomai/include/rtdm/rtdm.h(389,0): Error : undefined reference to `rt_dev_ioctl'" What do I need to do to code properly for xenomai? Also I wonder if it possible to move to a xenomai version where rt_dev_select was added to RTDM (it happened in 2008 I think, although I see your xenomai is from 2009 so I don't quite get that). Cheers Dave
  19. daves

    Action on $$$

    Calling "reboot" instead of $$$ in my test case gives the following in the terminal: reboot Sending notification to all controls to stop communication Rebooting PowerPMAC Disconnected from PowerPMAC Please wait!!! PowerPMAC reset in progress Trying to reconnect to PowerPMAC Trying to reconnect to PowerPMAC Trying to reconnect to PowerPMAC Trying to reconnect to PowerPMAC Trying to reconnect to PowerPMAC Trying to reconnect to PowerPMAC PING Failed! PowerPMAC is not responding The card did its click-click booting sound during the fifth message about reconnecting. Restarting the IDE managed to reconnect so I think the card was ready, just the re-initialisation loop after reboot doesn't seem to work. Concerning my original problem, the system no longer exhibits the non-running/frozen CPLC after reboot. But this is no different to a power-cycling if I have to exit the IDE and reboot takes as much time. Hope this information is useful... Dave
  20. daves

    Action on $$$

    Is there any way to define actions which happen just after $$$ is issued and before the reset, in a configuration file for example (like the disable/startup scripts)? I am finding that unless I manually disable my CPLCs then a $$$ breaks PPMAC. I would like to insert UserAlgo.BgCplc[31]=0 etc before the reset automatically. I have filed a bug report (#591) with test cases to get this properly fixed, but I wondered if there was a convenient way around the issue as it is quite frustrating at my current stage of testing... Dave
  21. daves

    Old i-variables

    That's great. Thank you very much
  22. While upgrading our UMAC project to PPMAC I have managed to translate most of the setup i-variables to the new structures. Some of them can be found by searching the help (e.g. i8 is found in the help under Sys.RtIntPeriod). Some of them can be worked out by seeing where they point in the terminal (e.g. i168-> tells me I168->Motor[1].Servo.Kfff so I can tell what it is called now). Some I think can be ignored (e.g. I48 deals with DPRAM which does not exist). However I feel like there are some I am guessing. Is there a definitive translation guide (especially the non-motor variables i1-99 which are now part of motor 0 so give no help in the terminal)? As a quick start could you tell me if these Turbo i-variables are needed and can be set up (I know what they are but don't know how to start looking if they have Power PMAC equivalents. I think i11 looks like the only important one): i1 i2 i6 i11 i52 i53 i68 Also during the translation I found we were using i14=1 with a comment about matching coordinate system on start. This is what i14 meant in PMAC, not Turbo so I think it slipped through that translation stage. Could there be any effect from this in UMAC or PPMAC? Cheers Dave
  23. Thanks Dro. If it useful I think I have only seen the IDE touch open and unmodified .pmh files unnecessarily. It doesn't seem to touch .c .h .plc .pmc files which are unmodified, and it doesn't touch .pmh files which are not open in the editor. Dave
  24. Thank you Curt. This works perfectly now, and I'm hopeful it could be a possible error reporting/logging mechanism in my project. I guess the 'necessary return variable' is a PLC language feature? My background is more C-type languages where it is acceptable to have lines such as strcpy(str, "123"); where the 'real' work happens in the parameters and you are uninterested in the result. Even cos(30); is a valid (if pointless) line. Thanks again for putting me on the right track, your help is appreciated. Dave
  25. I have seen some interesting new things in the September release. rtpmacapi.h enum progstatus {PROG_RUNNING, PROG_STOP_ON_PAUSE_STEP, PROG_STOP_ON_LIMIT, PROG_STOP_ON_BKPT, PROG_STOP_CODE_ERR, PROG_STOP_STACK_ERR, PROG_STOP_LVAR_STACK_ERR, PROG_STOP_CALL_ERR, PROG_STOP_AXIS_ASSIGN_ERR, PROG_STOP_KINEMATICS_ERR, PROG_NOT_IN_USE = 16}; //------------------------------------------------------------- /// Returns enum of Plc Status /// /// \param[in] num - number /// \return enum progstatus enum progstatus PlcStatus(int num); //------------------------------------------------------------- /// Returns enum of Coord Program Status /// /// \param[in] num - number /// \return enum progstatus enum progstatus CoordStatus(int num); Could this be related to my question in http://forums.deltatau.com/showthread.php?tid=592&pid=2068&mode=threaded Is there some updated API documentation, the version change document does not seem to be complete and I would also like to know about new status parameters like Sys.BgSleepTime, etc. Maybe we are not supposed to know about these yet and my snooping around the symbol files is premature :) Cheers Dave
×
×
  • Create New...