Michael Lloyd

MrPLC Member
  • Content count

    963
  • Joined

  • Last visited

Everything posted by Michael Lloyd

  1. I converted some of my structured text routines to CLX Add-ons. If anyone is interested I would be happy to share. They are tried and true routines that I've used for years. Both are used for calculating flow through an orifice plate. Gas Routine: It follows AGA7 but does not include a calculation for a live NX19 z factor (if you don't know what that is then you probably don't need the add-on). I've compared it to TotalFlow's and Fisher ROC's and while I wouldn't use it for custody transfer it's very good for plant or system balancing. If you understand gas measurement then you'll understand the required inputs. Personally I map the input values to the tag with structured text and then lock the routine with a password so someone doesn't screw something up. Inputs: Atmospheric Pressure, Pressure Base, Temperature Base, Pipe ID, Plate Bore, Inches of Water, Flowing Pressure (PSIG), Flowing Temperature (°F), Specific Gravity, Z factor, Cp/Cv, Nitrogen Mol %, CO2 Mol%. You can set the last two to zero if you aren't correcting for btu Outputs: SCFH, MSCFD, MMSCFD, and #/Hr as well as Beta Ratio and the factors used to calculate flow through an orifice (Fr, Fgr, Fpb, etc) Liquid Routine: This is a much simpler routine. The result is extremely accurate if you feed it good data. The routine requires you to know, or at least guess accurately , what the flowing specific gravity of the fluid is as well as the specific gravity at 60°F. For processes that have widely varying temperature (for instance a hot oil heater. On cold startup the oil is 60 - 100° but when running it can be as much as 350 - 600°. The specific gravity of the oil varies significantly between the two conditions) I use a function generator (10 x and y data points) set up with specific gravity for the range of operating conditions. Neither routine requires the user to input factors. Inputs: Pipe ID, Plate Bore, Flowing Temperature, Specific gravity@ 60°F, Specific gravity@ flowing temperature °F, inches of water differential. Outputs: GPM, BPH, and #/HR (plus all of the intermediate calcs like Beta ratio, etc)
  2. Is there a prebuilt Rate of Change routine in CLX? If there is I can't find it, so: I've been trying to figure out the timing routine for a rate of change AOI and I'm stumped. I would like for everything to be contained in the AOI. I would use structured text language. I originally thought that I would just use a timer and call the routine every X seconds. Interval would be Preset / 10.0 but that would mean using an external timer. It's not a horrible solution but way back in my S7300/400 days I wrote a routine that calculated elapsed time between calls based on the system clock for use in a PID loop reset and derivative calculation. I was trying to write my own PID loop. Why? Because... :) This isn't that exacting of a calculation requirement so I was hoping for something simple. The calc is for tank rate of change and direction. Since tanks vary in capacity and inflow / outflow the time interval needs to be adjustable. No longer than a minute. No less than 5s or so. It looks like I can use a TONR in a structured text routine but I didn't have much luck when I tried to code one. Maybe I should have put the timer in the local group? Ideally the AOI would be drag and drop into a function block routine and I could map the IO via STX.
  3. I'm trying to make sense of a reply from a PLC by decoding each Hex value (hint, it's not working lol). It works great with serial MODBUS but TCP/IP is a completely different structure.  Here's what we are seeing. I can't decide if we are getting two RX for every TX or if the event log is just splitting the response into two different lines to make it easier to view. Actually I can decide and that's what I think is going on. 7/20/2022   12:22:56.194 PM   TX        60 70 00 24 00 04 00 1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 A1 00 04 00 89 4C 92 FF B1 00 10 00 EA 0B 03 03 20 6B 25 00 BD C6 02 00 03 00 06 00 7/20/2022   12:22:56.237 PM   RX        24 70 00 2C 00 04 00 1C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7/20/2022   12:22:56.237 PM   RX        44 00 00 00 00 00 00 02 00 A1 00 04 00 01 00 FE 80 B1 00 18 00 EA 0B 83 00 00 00 02 00 03 00 00 00 84 1D 08 00 06 00 00 00 8A 44 01 0C The next thing to try was to make a spreadsheet, use HEX2DEC to convert each Hex value to decimal. Like magic I expected (not really) to see the IP address of the PLC in the data. The problem is, if I understand TCP/IP packet structure right (Vegas odds on that one) the structure isn't as neat and orderly as that. Rather than continue telling you what I don't know lets go with - Can anyone here decode this?
  4. Decoding TCP/IP packet from Kepware

    Kind of answering my question, kind of not. I opened the file in Notepad ++ and it gives me a better look at data. The first Hex value is the length. After that, I'm back to trying to decode with brute force. Which doesn't work btw. I attached the text file. Opening it in Notepad++ makes it easier to read.  The problem we are having is the station suddenly started dropping out for no reason. Just the PLC's though. The "last good poll" for the PLC's starts lagging behind the OMNI's and can fall behind as much as 10 minutes or more. When things are good the last good poll time is the same down to the second. At the worst the PLC's both drop out and after 10 minutes of no comm the station shuts down. I'm pretty sure it's not the comm device (probably a cell modem but I've never been to this site) because the OMNI's don't drop out. There are two PLC's and two OMNI Flow computers. All are using ethernet. The OMNI Flow Computers are rock solid. The text file is from one of the two PLC's. Watching it poll in Kepware TX/RX happens at one sec (or less) intervals which is entirely too fast for the kind of connection we have. It's not local to the server. It's probably 300 miles away from the server. TCPIP Log.txt
  5. Inflation - Cost Increases

    I'm seeing the same thing with components. I needed some Nichicon 100uF 35V electrolytic capacitors a few days ago and Mouser had less than 200. That would normally be an item that they stocked 10,000 of. Some things, like connectors, are 6 months out at best
  6. Satellite communication

    Obvious first - you'll need a VSAT receiver with a serial or ethernet port. When we used them we installed a port server or a serial card in an AB PLC rack. We used MODBUS to move data. It's pretty simple once you've done one. If you'll look at the satellite as one end of a very long wire it will make sense. 
  7. Binary outputs RSlogix 5000

    I'm at work so I have access to the AB software. I can't open the L5X files. It says The specified L5X file does not contain a controller export. Likely because I don't fully understand what you are trying to do, I don't see a problem with your logic. You are trying to " call the same output on different rungs" Flip that around to call the same output with different logic Kudo's for getting this far without PLC experience. I've attached a completely unrelated type of program with various kinds of branches, one shots (ONS) (positive edge trigger that passes the on state once and won't pass it again until the input turns off then on again), etc Take a look at any of the MOV routines (motor operated valve). Some of the triggers come from Pxxx routines (pumps). There are numerous branched rungs I like to map IO to tags to user defined data types (under Data Types folder) so I can easily reassign the IO... None of this is THE way to do it. It's how I do it.        Asherton_05_26_16.ACD
  8. Binary outputs RSlogix 5000

    You can also use bits of an integer to trigger the output and then Move an Int into the register based on the DI.
  9. Binary outputs RSlogix 5000

    Unfortunately I can't look at your logic from this computer. Why can't you use OR logic to turn on the output --! ! --------------( )           ! --! !-----            ! --! !-----
  10. Very good. I think you'll find an enormously talented group of people here (not so much me :o) ) and they are always willing and able to help.
  11. First - I have nothing against FB programming. When I need it I use it. For clarity - in my line of work an alarm is used to tell the operator that something that he can affect is impending, and I don't latch those. A shutdown is latched and and must be reset. All of that is done in ladder logic. Use a one shot (positive edge trigger) between your reset button and unlatch otherwise the button can "fault" or, more commonly seen, the operator can hold the button in and bypass the alarm or shutdown. Or a jumper clip can be installed. Or someone could sharpen a stick and jam it into the button. I've seen all three happen.    
  12. Learning RSLOgic5000

    Just a heads up, when you say process be aware that could be anything from batch processes, to power plant control and shutdown, gas processing control and shutdown, conveyer systems, machinery control, and whatever else I am not even aware of.  "Any process" is a big topic
  13. Compact Logix run without I/O Cards

    I've never done it but have you tried disabling the IO cards in the IO tree? Right Click the card, select the Connection tab, Check the Inhibit Module box
  14. I hate when something is right in front of me and I don't see it :) It looks like it performs the function on the array variables (FAL_Top or does that point to an array?), one at a time every time Top_New_Data cycles, and updates the single Real value?
  15. To the OP - It's not unusual to use 0,1, or 2 (or higher) with a compare to make things happen in an HMI or program. As everyone else has said- you can't use a BOOL tag for an integer function.
  16. Copied this from the help file Description The FAL instruction performs the same operations on arrays as the CPT instruction performs on elements. Added rambling thoughts- Length 520 double integers. It's set to INC so it's going to step through every time the HSC see new data.  So where's the math (computation) that's being performed?  This is why I prefer a clear and concise description to blah_blah_blahty_blah tag structure :/
  17. Masked moved instruction

    I was just looking at the help info for that instruction. It didn't make sense. A mask value of 0 is supposed to block the source bit and 1 passes the source bit yet  Input a = 0101 0101 ... etc Mask = 1111 0000 ... etc Output = 1111 1111 ... etc Description The MVM instruction uses a Mask to either pass or block Source data bits. A "1" in the mask means the data bit is passed; a "0" in the mask means the data bit is blocked. If you mix integer data types, the instruction fills the upper bits of the smaller integer data types with 0s so that they are the same size as the largest data type.   So basically I'm just camping out on your post to get an explanation that's useful.
  18. Nothing against the OP but if this was possible I would expect Rockwell to close that hole asap
  19. Allen Bradley Newbie

    RS Logix 500. You may be able to use the HMI end of the cable to connect to your laptop serial port. <--- yes... you need a serial port or at least a good USB to serial adapter. 
  20. MikeC

    I need to see the logic to know. DN is probably happening so fast that you don't see it energize. Use Timer[].DN to a OTL and see if it latches (it will)
  21. I installed something like 15 or 20 L32e's in our SCADA system almost 10 years ago. I used an ethernet card rather than the DH485 port. We have no plans to change them. We have PLC 5's that have been obsolete for a very long time. We are just now thinking about replacing them. Cost vs benefit. If what you have ia working, maybe put a spare L32e processor on the shelf (you should already have one) and leave the L32e's in place. 
  22. Control Logix CPT Statement Oddity

    Over 10 years ago I was working on a burner management system for the company, that I now work for, at the same time someone else was working on a surge controller for two Solar Saturn turbines. Their PLC's kept showing up on the network. What does any "good" integrator do when they encounter someone else's program? Why they download it and check it out of course  I was already using UDT's and making my own AOI's so I wasn't overly interested in the program, but you never know what kind of jewels (or feces) you might find in someone else's program (including mine). The did the surge calc for the antisurge controller in ladder. It almost 100% duplicated my AOI (it's a common method and I'm not implying they copied mine. In fact, if they had there wouldn't have been one of "those conversations" with them years later. One thing that made me scratch my head was the last rung. It was a divide and the result was placed into an integer. I didn't think too much about it. Fast forward a few years later, now an employee, and I was called to come investigate why our turbine driven centrifugal compressor surge valve opened. They had already figured out that the high temperature shutdown on the suction didn't kill it. The RTD element was 3" long. The thermowell was 18" long. The element tip wasn't in the process flow. I was tasked with figuring out why the surge valve came open and stayed open. That's more complicated than what I'll get into but hot gas has less differential across an orifice plate thna cold gas. The rest is elementary. The surge valve basically connects discharge to suction to keep flow through the compressor from dropping so low that it surges and bad things happen. Discharge in this case came off before the cooler (ie it was hot).  I remembered the weird calc (not the specifics) so I started there. The surge calc is easy Relative Flow / Relative Speed (Relative = % so actual over design)). Calculating flow accurately takes a little effort. So if I'm at 96% flow and 96% speed, 0,96/0.96 = 1.000. Life is good even if it is an integer. If the turbine is it 50% Flow and 96% speed, 0.50/0.96 = 0.52, still a 1.0 if it's an integer but approaching surge. Sort of. I'd normally start with the setpoint for the surge controller at 70%. Normally a Saturn is going to run between 100% and 110% gas producer speed (max) so my example is a little off but basically te result drops below .50 and that makes it 0 in integer form. The surge valve opened, nobody caught it, hot gas returned to suction makes the discharge temperature higher which increases suction temp, etc, etc... melted compressor internals. and much dinero spent on the repair.  Decimal points matter.
  23. I need to. I wrote an orifice plate sizing calc that I used VBA in the background. It's been a long time since I looked at it though. I wonder where the OP went?
  24. PS - I hated the Rx3i system because it failed one weekend. The primary controller AND the redundant controller lost their program. Like gone. Nobody home. Sorry, I can't hear you... The IO was programmed to hold last position. The operator looked around and said he only had one PID controller on that system and he wasn't using it so there was no need to shut down. That's correct... the plant was still running with a brainless PLC. I called our engineer, explained what I was told, and we left it alone. The plant ran all weekend like that. Well guess what, when we finally loaded a program in the PLC we found out that a good 65% of the PID loops were on a remote rack that everyone had forgotten about AND the GE (pos) doesn't store the PID loop parameters in the saved file. When the guy we called out to dump the program in (I refused to touch that thing) and switched to run, all hell broke loose. :) Nothing that the ESD button wouldn't fix... It took all day to pull the PID config out of the HMI historian and reconfigure all of the PID loops. We sent the controller to GE to analyze why the primary and secondary lost their minds... They charged for the service. The answer? Couldn't find anything. :/ 
  25. The last plant I managed had a redundant GE RX3i system (about 3 years ago). It's was newer than the 90-30 by quite a bit but not up to Rx7i standards. I hated that system. After working with S7 and CLX I've turned into a PLC snob lol  When I contracted to the company I work for now I did a couple of burner management PLC's in that plant. The first BMS was done with a CLX, then next one was GE because the plant manager at the time "didn't like Allen Bradley". He didn't even know how to spell Allen Bradley but that's what the subcontractor he used liked. So, I used an Rx3i on that BMS. Same basic program just in a different platform. I'm a big fan of UDT's. I live by the tag lol The contract guy that did all of their GE work hated my BMS program lol. Today... that same guy loves the CLX stuff and doesn't ever spec GE. We hired him to replace me when I transferred to NM. I have standardized routines with standardized tag structure. Pump control, valve control, etc each have a starting ladder structure that can be modified. If I need to add a pump, I just create a new pump tag, copy the existing routine to a new routine, search and replace the tagname (before the .), fix the shutdown string and add or delete whatever I need. At the peak of building the pipeline system we built in the Eagle Ford I could write a 3 pump, 4 tank station program in one day and build out the HMI (ClearSCADA) the next day. I didn't reuse old programs. I started clean every time. Make the IO sheet complete with tag names, transmitter list, alarm and shutdown list, and cause and effect. Do some cut / paste import / export tag stuff, pull in all of the UDT's needed, create all of the tags, start programming. It seems like oil and gas is a different animal than machine or factory floor automation. We use a lot of analog inputs. The largest station that we built had 241 analog inputs (quite a few of those were calculated variables), 255 analog input "tag slots". It took about 30s to document them via an Excel sheet (with a VB backend) and csv import. I start with a base program that has text in the description to make it a simple cut / paste operation. 53 station programs spec'd, panel and transmitters ordered, FAT done (btw the FAT's were linked back to the HMI server with a cell modem so validating the panel wiring also validated the HMI), and pre-startup checkout done in a hair over a 3 year time period. At one point I had 6 programs in progress at the same time. I didn't get to the point of being able to write the programs in a day until about 1/2 way through the system build out. While that was going on I was also the guy they called when something wasn't working right. Baptism by fire but I'd do it all over again.  The analog UDT looks like this: String1    STRING        Tag    Read/Write    1    0 String2    STRING        Description    Read/Write    2    0 PV    REAL    Float    Scaled Process Variable    Read/Write    3    0 AHHA    REAL    Float    High High Alarm Setpoint    Read/Write    4    0 AHA    REAL    Float    High Alarm Setpoint    Read/Write    5    0 ALA    REAL    Float    Low Alarm Setpoint    Read/Write    6    0 ALLA    REAL    Float    Low Low Alarm Setpoint    Read/Write    7    0 Deadband    REAL    Float    Alarm Deadband    Read/Write    8    0 HH_Limit    BOOL    Decimal    High High Alarm Bit    Read/Write    10    0 H_Limit    BOOL    Decimal    High Alarm Bit    Read/Write    11    0 L_Limit    BOOL    Decimal    Low Alarm Bit    Read/Write    12    0 LL_Limit    BOOL    Decimal    Low Low Alarm Bit    Read/Write    13    0 MinEU    REAL    Float    Transmitter LRV for HMI    Read/Write    14    0 MaxEU    REAL    Float    Transmitter URV for HMI    Read/Write    15    0 EnableAlarmHH    BOOL    Decimal    Enable HH Alarm    Read/Write    17    0 EnableAlarmH    BOOL    Decimal    Enable H Alarm    Read/Write    18    0 EnableAlarmL    BOOL    Decimal    Enable L Alarm    Read/Write    19    0 EnableAlarmLL    BOOL    Decimal    Enable LL Alarm    Read/Write    20    0 Status    DINT    Hex    Alarm Block Status    Read/Write    21    0 The Motor UDT (anything with and electric motor uses this one) String1    STRING            Read/Write    1    0 String2    STRING            Read/Write    2    0 SW    INT    Decimal        Read/Write    3    0 A    BOOL    Decimal        Read/Write    5    0 A_Stop    BOOL    Decimal        Read/Write    6    0 A_Start    BOOL    Decimal        Read/Write    7    0 Stop_I    BOOL    Decimal        Read/Write    8    0 Start_I    BOOL    Decimal        Read/Write    9    0 HMIStop    BOOL    Decimal        Read/Write    10    0 HMIStart    BOOL    Decimal        Read/Write    11    0 RunStat    BOOL    Decimal        Read/Write    12    0 Stop    BOOL    Decimal        Read/Write    14    0 Run    BOOL    Decimal        Read/Write    15    0 AStop_OS    BOOL    Decimal        Read/Write    16    0 AStart_OS    BOOL    Decimal        Read/Write    17    0 FStart_OS    BOOL    Decimal        Read/Write    18    0 HStart_OS    BOOL    Decimal        Read/Write    19    0 SOS    BOOL    Decimal        Read/Write    20    0 RH    DINT    Decimal        Read/Write    21    0 S    DINT    Decimal        Read/Write    22    0 FailTMR    TIMER            Read/Write    23    0 T1    TIMER            Read/Write    24    0 T2    TIMER            Read/Write    25    0 T3    TIMER            Read/Write    26    0 T4    TIMER            Read/Write    27    0 T5    TIMER            Read/Write    28    0 T6    TIMER            Read/Write    29    0 T7    TIMER            Read/Write    30    0 T8    TIMER            Read/Write    31    0 T9    TIMER            Read/Write    32    0 T10    TIMER            Read/Write    33    0 RMT    TIMER            Read/Write    34    0 RMC    COUNTER            Read/Write    35    0   Basically anything that we needed for an analog tag is in the Analog udt and anything that could come up for a pump or other motor driven device is in the motor tag. The larger REDA pumps used every timer. Things like low suction shutdown delay, vibration shutdown delay (1s), start sequencing... all kinds of stuff. If I needed to see what was going on with P-9001 I just expand the tag called P9001. The two strings are used by the HMI in the faceplate that pops when you click on the value box. The guy that wrote the ClearSCADA back end made templates that matched the UDT's that I used. To "make" a point on the screen you create the tag in the HMI, run a script that replaces Analog[10] with the correct Analog[x] value, drag the mimic to the screen. Poof... What was really handy was copying a whole station to a new group and running a global script that replaced the station number. Like this - Lets say I have Station 9000 built. They decide to build Station 7000. Btw... I picked the numbering system so that made it easy. The pumps in station 9000 were P901, P902, and P903 for the boosters and P9001, P9002, and P9003 for the mainline pumps. Station 7000 only had 2 of each. Copy past the station folder to a new folder named 7000, search and replace the 9 with a 7, delete the two extra pumps, done. The same applied for MOV's (motor operated valves), tanks, tank mixers, etc. The main caveat is that the numbering and naming had to be tightly controlled and there was a little bit of crystal ball stuff going on. Station 9000 was easy, It was at the end of the mainline. Picking what all of the stations upstream would be numbered was a SWAG because there was no way to know how many booster stations were going to be on the pipeline. Back then oil was over $100.00 a barrel and the Eagle Ford was going to last for at least 10 years. We were moving 150,000 BPD at the peak. You can increase capacity on a pipeline three ways, increase the diameter, loop the line with a second pipeline, or add a booster station and breakout tanks. 1 and 2 were not an option, so 5000 was around the middle, 1000 was at the beginning, and I just hoped the numbering I picked for everything in between worked otherwise I was going to have to do a lot of work renumbering. We could have got out of order, Nobody but me would have cared and it would have driven me nuts lol. It worked out. No renumbering required. Gas plants are little more tedious due to tags needing to match P&ID and other PSM docs. But with the right pre-planning and tag structure it's not that hard.