MrPLC Member
  • Content count

  • Joined

  • Last visited

Everything posted by Hoobs

  1. NJ501-1300 Has anybody started using the (relatively new) instruction on the NJ/NX series, AC_StepProgram? There is a structure variable used to provide the details of all steps of all programs (profiles) that you would want AC_StepProgram to manage.  It will calculate ramps, holds, soaks, etc., and move the setpoint around as necessary to implement each program/profile.  If ya need to do these things, it looks like a *big* headstart...  I'm glad I found it before I wrote a pile of code to do the same things! My question: The structure variable used to provide the details of all the steps is an InOut variable.  For the life of me I can't figure out why, or if there is any scenario where the instruction would actually change anything in that structure.  There are other variables that I believe are all it needs to maintain state between task cycles.  Does anybody know why this is an InOut variable instead of just an In variable? If you're wondering: This is important to me because I'm building a system to control several dozen closed loop furnace systems.  If need be I will replicate all 5 of my processing profiles to each one of the loops, but I was hoping to avoid that if AC_StepProgram doesn't actually change anything in the structure. Thanks! Hoobs
  2. Am I the only person on the OMRON forum these days who is using the AC_StepProgram instruction?  If anybody else is using it, and is getting success, please let me know here or PM me. I'm using it heavily, and I currently believe there is a bug (or multiple bugs) that are preventing this instruction from correctly recovering after an unexpected power cycle.  I have also failed to ever see the StartAtPV option to the instruction ever do what it is advertised to do.  I'd like to hear what other folks are doing with this instruction, and if anybody has tried to put together a power hit recovery strategy for a system that includes this instruction.. Thanks! Hoobs
  3. @innoaloe, Thanks for that pointer.  I had discovered this as well, and it does what it is supposed to but, as you state, it's not really what I'm looking for. @Crossbow, It's been a little while but I remember 6-7 years ago working on an A-B unit that had the type of WDT I was expecting to see on the OMRON units.  This approach to WDT comes from embedded industrial microprocessor control technology of the last couple decades, where an on-board WDT has options for what to do if it gets triggered: full system reset (like a power cycle), reset only some system components (i.e., reset a network port/stack, reset a potentially stuck I/O module, etc.), and/or simply jump to a specific machine instruction address and execute from there.  It's not that software can reset the WDT (which is pretty pointless in most real-world situations because the software is likely not even executing in a predictable manner any more).   Rather,  the WDT has on-board ability to take specified action that can recover the system functionality and allow normal processing to continue from that point forward.  Of course, this requires that the up-front engineering work correctly designs how to identify that the system is in a state that requires the WDT to take action. I could do the external hardware design you're talking about, it's not difficult, but I was expecting this kind of functionality to be on-board, otherwise the WDT is essentially useless for recovery of a locked-up system.  If I have to do something external I'll instead stick in an IP-controlled switched outlet, and have my production proxy server (which expects a ping from the PLC every 500ms) to use that IP-controlled switched outlet to force a power-cycle.  It's kinda brute force, but it should get the job done. ASSUMING the implementation bug(s) in the AC_StepProgram instruction don't get in my way (subject of a different thread).  My regional OMRON field engineer is supposed to be here next week so I can show him how the AC_StepProgram instruction is not coming up in a stable state after a power cycle of the PLC, making full recovery/restart of the affected control processes impossible.  If we can get that issue figured out, then I should be able to correctly bring the system back up after a power hit.  If I can get to that point, I can then use that capability to also be the WDT/locked-up recovery approach. Thanks guys! Hoobs
  4. I would like to explicitly utilize the cpu watchdog timer to not only determine when the CPU is hung/stuck, but then execute a cpu reset.  Other PLCs I have used expose a config setting where you can choose a timelimit for the watchdog timer and, if that time limit is exceeded, there is independent hardware that sees this and causes a cpu reset to occur. In my NJ501, I see in the docs that there is a watchdog time (WDT), but I can't find any information about configuring it, or utilizing it as part of a state identification and recovery strategy. Anybody else doing something like this with the WDT?  How? Thanks! Hoobs
  5. Thanks guys!  Makes sense now...  I was so buried down in ST-land I forgot to look up at the IDE and see that I had to define them first in the multi-view.  DOH! Hoobs
  6. Sorry for such a noob question, but I'm still figuring out the OMRON-specific  implementation details for ST...    I can't find anywhere what the language syntax is to define a function or function block of my own in ST.  I can see how to do it in ladder, but I'd rather do it in ST because I will be calling it from ST as opposed to ladder. The "standard" way is with a FUNCTION_BLOCK keyword, etc., but the OMRON NJ series doesn't seem to know anything about this syntax, either in-line or in a function or function block that's been added to the project. How do I define my own function or function block in ST? Thanks! --Hoobs
  7. Wow...  that's surprising.  I must be missing something then...  what is it good for as currently implemented?  Without the ability to take asynchronous recovery action, that is not dependent on proper code execution occurring, the WDT doesn't strike me as useful.  What do I not see? Thanks, Hoobs
  8. It always depends on the situation.  On my current project, it would be far more dangerous to let the operator continue processing with the PLC hung than with it being reset.  In this particular case the hardware was specifically designed to be handled this way, and if a keepalive pulse generated out of the main loop doesn't arrive on schedule the hardware could also initiate a reset externally.  In either case the hardware correctly locks out the operator console until well after the system is fully backup and a positive status position is established.
  9. Thanks Inoaloe!  It turns out in my situation I'll not have things set up that way, so I'm going to try to just have a single one of these structures, set to be a constant, and see what happens.  If it doesn't work, I'll report back here.
  10. Figured this out, just want to be sure it's documented here. It turns out there are two input variables to PIDAT that are structures, one holds initial setup parameters and the other holds on-going operational parameters.  Things like max/min ranges, some operational preferences, etc.  Well, it further turns out that the default values for the items in these structures are such that the PIDAT instruction is guaranteed not to function correctly.  If you define those two variables, and set up their initial values correctly for your situation, PIDAT should spring to life even if there are no autotune cycles that have been performed. Hoobs.
  11. NJ501-1300 Question specific to PIDAT...   in the W502 manual (instructions reference) I find the following statements buried down in the descriptions of all the variables, specifically the variable ATDone, which is the outgoing signal leaving to enable the next instruction to the right on this rung: My question is: How do I get the PIDAT instruction into the state of "PID control is in progress without autotuning"?  If the value of the StartAT input is false, then ATDone will never go true.  However, if StartAT is true, then the instruction is going to start an autotune cycle, which I don't want.  There is no description I can find for how to get it to do "PID control without an autotune cycle having been completed".  The timing diagrams aren't making this apparent either, unless I'm not seeing it. Thoughts? Thanks! Hoobs
  12. Perfect, that's what I believed looking at the docs, thanks!  It's not a problem, as I can keep all my fb_PIDATxx instances in an array indexed by loop number, so they are easy to get to. Al  
  13. NJ501-1300, with a pile of TS3101 analog input modules and OD5256 digital output modules. First, a general question: Are NJ function blocks reentrant as a rule?  No?  Sometimes? Second, a specific question:  I am setting up this NJ-based system to perform multiple (42, for now) temperature control loops.  Each control loop must obviously be able to run independently.  As I am intending to use the PIDAT function block to handle PID duties, it raises a question: Is the PIDAT function block reentrant?  If so, how would it keep track of different sets of PID coefficients, and everything else it would need to keep multiple invocations straight?  I don't see how it can do this, but maybe I'm missing something. My current belief is that it doesn't do this, and that I will need one instance of PIDAT for each control loop, i.e., 42 instances, with distinct sets of variables for each one.  Is this correct? Thanks! --Hoobs
  14. No, I had not discovered that here in my early days with Sysmac Studio, that will be extremely helpful -- thanks!!! Regards, --Al
  15. NJ501-1300. Attached is a simple program that just opens a socket, reads one message off of it and echos that message back to the socket, then closes the socket.  I have a socket client that I'm using to send small strings to the socket, and I can choose whether or not the client closes the socket from it's end.  The first time I execute this it after a reset it works great.  However, after that, I can never connect to this socket again.  The only way to recover is to pull the ethernet cable and plug it back in or, sometimes, I have to actually power cycle the NJ.  Then, I can connect from my client, send/receive the message into the socket again successfully, and then again find myself back in the state where I can't can't connect.  This is consistent regardless of whether the client is closing the socket from its end or not. I've tried to strip this down to the shortest example I can.  Anybody have an idea what's happening?  It seems to me that as soon as the socket is closed the next time around the SktTCPAccept instruction should hang on the closed socket, awaiting a request to come in from the network.  But it appears there is something happening deeper down in the networking stack that prevents this, and the only way to fix it is to pull the cable or power cycle the NJ, neither of which is acceptable for production, obviously.  If I can get this working then I intend to also explore persistent connections for throughput reasons, but I need to get this  more simple example fully working first. Thanks! --Al Sysmac ladder.pdf
  16. OK, I have found a workaround for this problem, I describe it below.  Unless I'm confused (always possible, LOL!) this is possibly a bug, maybe in SktTCPAccept, maybe further down the stack, there's no way to tell from this vantage point. When using ladder logic, my expectation is that each time execution of a rung is started every function and function block on that rung have their constructors/initializers called (under the hood).  I made a guess that possibly SktTCPAccept wasn't leaving itself in a clean state after its first invocation, and was then confused at subsequent invocations.  So, at the end of the rung with the Accept, after I had set a flag variable to release other rungs, I have an Inline ST block with one line in it: SktTCPAccept_instance(Execute:=FALSE); This causes SktTCPAccept to be explicitly initialized before each subsequent invocation. If I was doing persistent socket connections, this wouldn't work.  However, it appears that the NJ is also closing sockets after each network transaction, even if I'm not doing an explicit close.  That's OK, I can deal with opening/closing a connection for each transaction in this situation.  However, if the NJ is closing sockets "automatically", behind the back of the program, that should be considered a bug as well. Hope this helps the next newbie...    enjoy! Best, --Al
  17. Innoaloe, thanks very much for digging back into this with me, I appreciate it.  Two thoughts: Even though it doesn't affect me, the 60-second hold-off with SktTCPConnect still doesn't make sense to me.  Why would the controller enforce such a hold-off? Your point I quoted above: This is unusual to me, I'm really lucky I had a chance to learn this early in my NJ experience.  I expected these blocks to be reentrant, but that is obviously not the case if the Execute in-parm has to be forced to cycle through False to reset a block before it can be executed again.  I can work with it, this is just different from some other situations I've been in where blocks could be re-executed on subsequent passes without this requirement being in place. Thanks!--Al
  18. Thanks, Solheim95...  I had not noticed that.  It's not the problem I was having but it could cause me a problem, I'm glad you pointed it out! Now, the question is:  Why is this the case?  I can see no scenario where this behavior would be desired... --Al
  19. Hi Innoaloe, thanks for taking a look at this.  Please look at the pdf I uploaded with the original post on this topic.  This ladder diagram executes exactly as described above, and I can see the power trace run through the SktClose instruction and terminate with no error.  However, after the SktClose is executed, the SktTCPAccept still behaves as if the socket is open and active.  I understand that the reason I can't connect the second time is because SktTCPAccept is confused about the socket being closed (after I've already closed it), but the questions are: Why is it confused? How can I either avoid getting it confused, or how can I get it unconfused without resetting the entire network stack (which is what removing the physical media accomplishes, in a crude manner...)?  There will be other network/socket transactions going on simultaneously, so resetting the entire network stack between connections is not viable. I'm stuck at the moment, having tried many different sequences of events in an attempt to find something that doesn't leave SktTCPAccept in this state of affairs.  Any thoughts, suggestions or other observations welcomed! Best, Al
  20. One more follow-up:  I have found that, after the first transaction that works, if I unplug the ethernet cable from the NJ, wait a few seconds, and plug it back in then I can do one successful transaction again before it locks up.  Whatever condition is preventing the SktTCPAccept instruction from running is not visible in Sysmac Studio, but it can be cleared by disconnecting the physical layer and connecting it back up.  I need to know what that condition is. Any thoughts?  Hep me, hep me, please!  :) --Al
  21. OK, I have learned a bit more...  the problem appears to specifically affect the SktTCPAccept instruction.  After a full reset, the attached program works as expected, the SktTCPAccept opens a socket, listens on it for incoming data, etc.  However, once that has all occurred, if I restart the NJ (without resetting it, or the EIP subsystem), then the attached program stops at the SktTCPAccept instruction and does not continue.  No prior instruction has thrown an error, and neither is the SktTCPAccept.  I have looked at every parameter, and nothing is out of the ordinary.  But something is happening under the hood that is causing this instruction to stop in its tracks.  The attached screenshot show the power trace when SktTCPAccept gets into this situation.  The parameter values can be seen.  Why is the instruction stopping? Thanks! --Al  
  22. Thanks for the FB hints...  I had started down that path to see what would happen, it's good to know that is one possible "accepted" path to handle this. Re: single connection to be accepted as a "server"...   In my case I've built a simple proxy server that will sit between an httpd and the PLC.  I intend to have the PLC always listening on somewhere between 8 and 16 ports all the time with SktTCPAccept, and the proxy will handle making round-robin requests across these ports.  Until a request on a port completes (correctly or with an error) the proxy will not attempt another connection on that port.  So, yes, you are correct, we don't technically need to close the socket.  However, the httpd is sessionless in nature, so I need to think through the architectural considerations of where to switch from a sessionless processing model to one that involves a persistant session.  I'm not sure yet where I'll come down on that.
  23. In doing a bunch of socket programming on the NJ501-1300, I have found what appears to possibly be an error/omission in all the manuals related to this controller.  There is an instruction mentioned in numerous places, the "SktSetOption" instruction, but nowhere am I able to find details on it.  What options can be manipulated?  How is that done?  Is there status information returned?  While it is mentioned in several places, it is *not* in the NJ Instruction Reference manual, unless there has been a recent update to this manual that I have been unable to track down. Does anybody know where the usage details for this instruction may be found? Thanks! --Al
  24. OK, thanks.  Interesting that's the only option.  I assume the TCP_NODELAY enumerator maps to the RFP-defined option setting down in the tcp/ip stack with the same name, if so then I know what it does. Thanks for making sure I know about sockets in general.  Yes, I've done network programming for about 30 years, and I'm familiar with sockets...   :)      There's an interesting problem I'm having currently, in which it appears that SktClose() is not closing a socket that I successfully created with SktTCPAccept.  I've confirmed with a port scanner that the port is indeed still open on the NJ, even though in Sysmac Studio I'm looking at the power trace running right through the SktClose() instruction and it is kicking off no errors.  Thus, the socket logic all works great the first time through, but then the socket isn't closed and SktTCPAccept can't open another on the same port when a second request comes through.  Any thoughts on that are greatly appreciated as well! Thanks! --Al
  25. Siemens and EZRack PLC, IIRC...  both have current products on the market with on-board debugging features such as single-step.  I have it from a trusted source that Allen Bradley is close to releasing updates with this type of functionality as well, but I have no way to confirm/deny this information. --Al