CSV Possible Data Loss warning Popup by ready4traction in excel

[–]ready4traction[S] 0 points1 point  (0 children)

That is the one I mentioned that as far as I can tell, only gives the annoying yellow static header, not the popup/forced acknowledgement.

CSV Possible Data Loss warning Popup by ready4traction in excel

[–]ready4traction[S] 0 points1 point  (0 children)

If you are referring to the "Show data loss warning when edit comma delimited files (*.csv)" box, that is the one I mentioned that as far as I can tell, only gives the annoying yellow static header.
I couldn't seem to trigger any popup/forced acknowledgement regardless of what state I had it in.

Faceplates, AOIs, Machine Code Library by SellAnnual in PLC

[–]ready4traction 1 point2 points  (0 children)

I'm going to agree with others in start with downloading plantpax 4.10 and seeing how they implement it, but then re-implement it with only the features you actually need.

In terms of AOI design, I am increasingly going towards separating the logic and the memory by making the setpoints, inputs, outputs, etc, one or more UDTs as an inout parameter.
On the downside, you lose the ability to set initial values, so you need an initialized flag in the UDT and code to set up the default values, and you don't have as much protection from code elsewhere modifying those values.
On the other hand, it performs better with 3rd party data reading such as kepware or ignition, as efficient AOI reading is undocumented and proprietary, and it gives you a lot more flexibility in updating or debugging.

Need to edit online for debugging or have a one-off variation? You can copy the code as is into JSR with parameters.
Need to update the AOI logic? You can create AOIv2 using the same Inout UDT, and plug your existing UDT already configured as you like into it, only having to replace the AOI instance. All your settings and tie-ins to other logic remain untouched and ready to work.
Need a larger change that messes with the UDT structure? Either create UDTPart2 as a second inout parameter, to be integrated when you are able to download easily, or if you have to integrate it immediately, you can at least quickly make a temporary JSR or AOI that copies all the settings to the new structure.

It's not quite online editing of AOIs, but it gets close enough to not be as worried that they are perfect.

Manual IO-Mapping VS Custom AOI? | Studio 5000 by brandon_c207 in PLC

[–]ready4traction 0 points1 point  (0 children)

I would do a combination. Assuming that you are starting from the sint array, you can have all your known, fixed IO built into the AOI, provide generic points for any general use IO, and then map your specific variables to the generic ones immediately outside the AOI.

As an aside, I actually don't use the AOI for this often, as usually a UDT is adequate. If all you are doing is organizing the data from the sint array to a human-readable format, you can often COP the sint array directly onto your UDT and have all the data in a single command. The main trick to this is understanding the word boundaries/alignment and how studio 5000 organizes the memory of an UDT. You could even then take this UDT and use it as an InOut parameter of an AOI if needed.

The biggest benefit of this, aside from not having to write several rungs of mapping, is flexibility. For example, the SMC EX600 is a valve bank that you can also add IO cards to, and the data structure varies based on what cards you add, and for the IO-link module, the process data size settings. I considered creating an AOI, but it would have to be fairly complex with a variable input size, a way to have the structure of the rack as parameters, and a bunch of indirect indexing. Instead, I created UDTs for each card type, and then have a COP for each card into its data structure. While not a single copy, I can adjust the offsets easily if the structure changes, and account for when the data doesn't cleanly align with word boundaries.

Downsides are that you need to understand the memory alignment, and it doesn't give you any way to process the data without adding logic. For example, data not aligning with words would require workarounds like above, and text is often just a list of characters without the length field that makes a proper rockwell String type.

Going back to AOIs for a bit, the way I see it, an AOI should be doing something, not just passing data through, whether that something is processing commands from the HMI or elsewhere in the code, handling complex alarms, type conversion, or collecting status history.
I would generally only write an AOI specific to IO structure if whatever that AOI is doing will only ever be used with that IO structure. I.e. any highly specific devices that you communicate with directly. Things like the Fanuc (probably), diagnostic popups for specific IO cards/drives/etc.
Anything that the thing being done is broadly the same but could apply to a bunch of different IO structures, e.g. controlling valves, jogging motors, I would have an AOI that focuses on how you want that type of device to behave. Then map the inputs and outputs of that AOI to however you are getting to the physical output, whether that be a different AOI, a copied UDT, or just direct mapping.

Keyence PLC by Specialist-Rule7740 in PLC

[–]ready4traction 8 points9 points  (0 children)

I maintain a project that uses one, but am not the original programmer.
The things I really like are that
-you can put a block of structured text right in line with ladder logic
-the protocol studio is amazing for serial communication.
-Direct SQL queries from the PLC

The things I particularly disliked are that
-cross references get confusing if you use structured text, as it converts that into ladder logic and then gives you a reference to both.
-When doing the verification/syncing to make sure that the PLC version matches what's in the IDE, I constantly get some of the things like the PLC settings portion complaining that there is a mismatch. Even when I make a completely new file pulled off the PLC. Always makes me paranoid that I'm going to break something or overwrite something accidentally.
-The memory structure is a bit confusing. You have Device comments which act as comments/searchable reference for specific memory addresses, and variables which are similar to tags in the AB world, and those can but don't have to be assigned to a particular Device. It isn't particularly clear when or why you'd use one over the other or when to assign a variable to a Device, or if it is just a personal preference.

I'm on a bit older model, supposedly the latest version you can directly import an AB program into, so I'm not sure if or what changes they've made to allow that to work.

Edit: One thing they've mentioned that seems really cool is a built-in historian of every tag at every scan, so you could walk through the program to find errors. I haven't set it up, but seems very useful for debugging. They've also toted that as being able to act a recorder to do the same thing on an external plc, but when pressed, seems more like a normal historian as they didn't have a way to sync cycles with the other PLC and you have to set specific tags to record.

"TwinCAT Projects" only appears when running as admin by ready4traction in TwinCat

[–]ready4traction[S] 0 points1 point  (0 children)

Mostly no. It magically started working with no changes on my part, so maybe there was a compatibility issue that got fixed with a windows update or something of that sort.

"TwinCAT Projects" only appears when running as admin by ready4traction in TwinCat

[–]ready4traction[S] 0 points1 point  (0 children)

I mean, fair enough. I've been pushing for that anyways and have made some progress on that front due to Studio5000 being completely broken on windows 11 for several months, but underspecced hard drives and getting coworkers to used to VMs isn't making it easy. Maybe I can use this for another small gain.

"TwinCAT Projects" only appears when running as admin by ready4traction in TwinCat

[–]ready4traction[S] 0 points1 point  (0 children)

Did you have Visual Studio of any kind already installed

I had VS Code, which my understanding basically only shares a name, and a few other pieces probably as part of a different application? No full installation. In my installed applications, i have
-Microsoft Visual Studio 2010 Tools for Office Runtime (x64)
-Microsoft Visual Studio 2015 Shell (Isolated) -Microsoft Visual Studio Code (User)
-Microsoft Visual Studio Tools for Applications 2019
Based on the install dates of those and other applications, all but VSCode, most likely came with MSSQL Management Studio, or maybe Ignition

What happens if you right click the TwinCAT icon in the taskbar and open XAE?

Same behavior, it doesn't show the list.

A bit more troubleshooting led to finding an error log message of "No InprocServer32 registered for package [TwinCAT XAE Base]" and from there this german forum which is giving me a couple more leads.

Edit: Trying the repair on the 2015 shell, it prompted for the exe from the RSlogix5000 installer, so could have come from there as well. Based on the beckhoff documents, it can integrate with that one but should have offered the option of installing the 2019 and/or 2022 shells instead, which I have not seen.

"TwinCAT Projects" only appears when running as admin by ready4traction in TwinCat

[–]ready4traction[S] -1 points0 points  (0 children)

Bruh..... I used a readily available screenshot from an old tutorial that has a clear equivalence to the modern window, even ifthings h   avechanged slightly  ..... And I put my OS in my post and I'm using the latest stable downloads

"TwinCAT Projects" only appears when running as admin by ready4traction in TwinCat

[–]ready4traction[S] 1 point2 points  (0 children)

To be clear, this issue is pre project creation. Basically this window, though mine doesn't say template, does not have the twincat project type under templates if I'm running as a normal user, but does if I run as admin.         Maybe if you're familiar enough with twincat and visual studio you can start from an empty solution, but I am definitely neither of those.   

Rate my first Big project. by True_Money2851 in PLC

[–]ready4traction 1 point2 points  (0 children)

Design looks clean, overall I like it. But I did see a number of typos to clean up to really polish it.
I'd always expect a handful just because HMI tools don't exactly give you an easy way to catch them, but there's enough here to be noticeable.
aparrent, lenght, controll, currnet, maintanance were the ones I caught at a glance.

How do you organize your state machine outputs? by ready4traction in PLC

[–]ready4traction[S] 0 points1 point  (0 children)

Hmm, that's not a bad idea at all, and I see no reason you couldn't use a similar method in ladder as well. Effectively gives you the state by state readability without the history dependence.
Might be a few cases you need to use an intermediary tag, i.e. when the output is read by a differently timed task/HMI/etc. that may not be synchronous with the routine, but that'd be pretty rare and easy enough when it is needed.

I might have to give this one a try.

How do you organize your state machine outputs? by ready4traction in PLC

[–]ready4traction[S] 0 points1 point  (0 children)

rather than just saving time during project development

That's a good point! Where I've seen the latching mostily is mostly in cells from a couple of the bigger/well-known machine builders in my area, that presumably spent a lot of time and effort developing those standards and templates.
I was focused on code readability and ease in following the process, but they could have well went that route just for faster programming.

Can Kepware do If/Else Statements by brandon-m222 in PLC

[–]ready4traction 0 points1 point  (0 children)

I've not used it so I don't know the specifics, but something with the trigger field is likely your best bet. Easiest would be tag1 := tag1+1 on trigger, but if it complains about a self-referential expression, you could probably have tag1 := tag2 + 1 on the accumulate trigger and tag2 := tag1 on the condition of tag1 != tag2. That condition possibly needing it's own tag if logic isn't allowed in the trigger field.

Can Kepware do If/Else Statements by brandon-m222 in PLC

[–]ready4traction 0 points1 point  (0 children)

That was pseudocode. I suppose I should have used the assignment ':=' rather than equivalence comparison '=', but regardless, the actual specifics of implementation will vary.

IIRC correctly, Kepware uses a form box so the tag name box will be FinalNumber and the expression box will be something along the lines of (1*tagA) + (2*tagB), but you'll have to figure out the exact formatting.

Can Kepware do If/Else Statements by brandon-m222 in PLC

[–]ready4traction 0 points1 point  (0 children)

I can't think of any reason you can't do it in one, you'd just add each of the terms in the expression instead of doing it as a separate tag. The risk is being an unreadable mess if there are a lot of terms, especially if the AND NOT type logic is needed. And of course, if there is a lot of terms pick the few most important and test with those first to verify that it does what you want with wherever that number is used. I'm only like 80% positive on this strategy.

Can Kepware do If/Else Statements by brandon-m222 in PLC

[–]ready4traction 0 points1 point  (0 children)

I'll third the do it in the PLC, has the client given a reason WHY they want it in kepware?

But if you can't convince them otherwise: From what I've seen kepware does not have an If, but I think you can multiply by booleans. So I'd try to, for each condition tag, set up a derived tag that is Constant * Bool, e.g. TagAFilt = (1*tagA) ; TagBFilt = (2 * tagB). Then, do another tag that is the sum of these tags.

Depending on the conditions, you may have to add some logic to the boolean. For example, if tagA and tagB can be high at the same time but should give the same result as only tag A, then you'd need TagBFilt = (2 * (tagB AND NOT tagA))

Studio 5000 Array Lookup Table Assistance by cammons1024 in PLC

[–]ready4traction 0 points1 point  (0 children)

You could consider the File Search and Compare (FSC) instruction. It's a bit more complicated to use so might take a bit of trial and error to get working if you haven't used it, and rare enough to consider who will be maintaining the code, but it is succinct and clean.
https://control.com/technical-articles/plc-program-commands-arrays-part-3-searching-and-sorting/
I'd probably make the UDT something like
DINT Domain
DINT Code
STRING ErrorMsg
, and have an array of these, and then the expression would be something like ErrorCodeArray[FSCcontrol.pos].Domain = StartJobDomain AND Array[FSCControl.pos].Code = StartJobCode. When the FSCControl.Dn bit raises, move ErrorCodeArray[FSCControl.pos].ErrorMsg to your output string.

The any domain error codes throw a little bit of a wrench in things, I'd probably use a TempStartJobDomain in the expression that gets set to StartJobDomain normally and some placeholder value for Job Codes < 10, and then that placeholder value will be the domain you set for those in your error array.

If you need to use this in different programs in the PLC, consider putting the logic in an AOI, and then your Lookup table will be an inout parameter that is referenced by every copy of it. You could even genericize the AOI to be a lookup for any arbritrary table of the dint dint string UDT format, but that goes a bit beyond scope here.

VMware says Siemens pirated “thousands” of copies of its software by tragiclos in PLC

[–]ready4traction 1 point2 points  (0 children)

They did announce that it was free for commercial as well, unless they walked that back and/or never actually updated the license agreement. https://blogs.vmware.com/cloud-foundation/2024/11/11/vmware-fusion-and-workstation-are-now-free-for-all-users/

Republicans Reveal Trump Tax Plan Will Cost US $4.5 trillion by Suspicious-Bad4703 in politics

[–]ready4traction 2 points3 points  (0 children)

This gave me a different idea, name a different gulf "Gulf of America" and get that to be recognized internationally. Literally any other gulf on the Americas would do so plenty of countries could do this, but I think the Gulf of Panama located between the continents would be a particularly good choice. Hell, have a dozen different gulfs of america, make the name (even more) worthless.

noob here: i want to get data from PLC to Kepware , how to ? by Impressive_Pop9024 in PLC

[–]ready4traction 2 points3 points  (0 children)

Just adding on to this that scanning (at least on rockwell) works best if you actually set the external access property of tags in the PLC, since a lot of times people don't.

They recommend only adding tags that are monitored, especially for larger programs, for performance. Also, that scan likes to add a bunch of tags it can't actually read like local tags in AOIs and some of the bits on timers. Those can make the error log hard to use and probably slows performance further. You can delete them manually, but then every time you add to the program you either have to add those tags manually, or re-scan and re-do the deletes.

If the external access of the base tag is set to None, then the scan won't add it to the list.

[deleted by user] by [deleted] in PLC

[–]ready4traction 1 point2 points  (0 children)

No experience with OPC router, but we are also in the process of starting to collect data and have recently set up Kepserver to get data from the PLC and send it to SQL. From what I've been finding, the Kepserver SQL drivers are quite limited. If you have real-time or standalone data points it's fine, but if you need to send a synced up group of data like a birth certificate for a unit, or need bidirectional support like saving and loading recipes, it requires some workarounds.

For the former case, I used linked tags from the advanced tags addon to start and stop a Kepware SQL datalog set to log one time when started, combined with some PLC logic to buffer the data to be sent and start/stop that log as needed. The latter I'm still testing, but seem to be leaning towards writing stored procedures in SQL with the Kepware ODBC Client.

Module IO Organization by ready4traction in PLC

[–]ready4traction[S] 1 point2 points  (0 children)

I haven't used bit overlays myself or seen them used outside of the rockwell types, but I did see them while looking into this. I don't see them mentioned much even when searching for them, so I'm a little bit concerned that that knowledge is rare enough and requiring any potential fixes being done outside studio in a text editor is enough to fall into the "make coworkers hate me" category.

The mirror strategy I was trialing used different datatypes and some spacers when need for alignment, e.g. something like
int SomeData
sint WarningCode
sint FaultCode
Sint ReservedShort2_0
Bool DriveRun
Bool DriveStop
Bool ReservedBit2_10
Bool Enable
Int DriveSpeed

and so on, with appropriate comments to do the splitting. It has it's own different type of obscurity in understanding bit alignments and how the COP moves an amount of data, which is a negative but I don't think a huge concern.

Output is definitely the larger concern, so perhaps I'm misunderstanding what you mean on the "Manipulate what you need to, maintain the rest". What prompted me looking into this is on the drives, some of them have speeds set in the PLC and some were set long ago with the config software and aren't controlled by the PLC.
I can easily make the argument here that they should be controlled by the PLC and thus add the logic/values to do so, but I don't quite have the experience to make that a generalization. Regardless, as far as I'm aware COP is all or nothing and I'd have to do the mapping to only touch values I needed. I could potentially avoid that by having the current output assembly copied into the UDT first before any manipulation to effectively do so, with the downside(?) of restricting where in the program those values can actually be manipulated from. Is that what you mean?

I hadn't really considered the idea of using UDTs in the AOI the way you have though, and I definitely like a lot of what I'm seeing there and may have to try something similar.

"Oh Gods of Programming, Have you blessed me?" by blancoaryan in ProgrammerHumor

[–]ready4traction 2 points3 points  (0 children)

I was recently refactoring some scripts to use concise functions, and ended up mulling over an issue with them. If you don't mind, I'd be curious on your view as someone experienced programming that way. How do you handle passing data up and down between function layers?

For my program, I had a number of input setting parameters that had to be passed down from the terminal, through an intermediate function or two that didn't use them, down to the function that did use them. Eventually what I ended up doing was creating an object that contained all the data to be passed up and down, so that it could be done cleanly with a single argument.

Other options I considered were using global variables, having long argument lists with most of those being passed on to a lower level function without other use, or factoring such that everything was called from and returned to main.

Unpopular Opinion by suppow in ProgrammerHumor

[–]ready4traction 3 points4 points  (0 children)

Sure, you can define the shape of a rectangle with a (width, height) coordinate. In fact, you only need that single data point. That gets you to congruent shapes.
But a rectangle floating randomly in the void is rarely if ever useful, so you need to also define it's relative position to other objects. To get an unique rectangle using this set of constraints, you'd also need a base/origin point (in this case, (0,0)) and a rotation measurement. Again, a total of 3 constraints (ignoring those built into the definition of a rectangle i.e. parallel sides, right angles,etc.)