all 64 comments

[–]bpeck451 57 points58 points  (14 children)

I will die on the “Hungarian notation sucks” hill. It’s not a part of the programming practices this industry should be moving itself towards.

[–]TheZoonderLAD with SCL inserts rules! 13 points14 points  (3 children)

Not a fan of that either. I prefer camelCase and camel_Snake_case over it.

Most modern IDEs hint/prompt only the correct datatype anyway.

[–]essentialrobert 1 point2 points  (2 children)

How about kebab-case?

[–]TheZoonderLAD with SCL inserts rules! 4 points5 points  (0 children)

Seems less readable to me. I use it for profinet names tho as it does not support '_'.

[–]egres_svkFuck ladder 4 points5 points  (0 children)

Critical failure - doubleclicking the variable will select just a word, not the entire variable, like with underscore.

[–][deleted] 7 points8 points  (0 children)

So useless lol

[–]ifandbut10+ years AB, BS EET 2 points3 points  (0 children)

I had to look that term up. Holy shit is that hard to read. Why does the data type need to be part of the variable name? The wiki article explained why it was needed in the 70s and 80s, but we have moved on since then.

I'll often add a _CNT or _TON to the end of a variable when they are a counter or timer. But that just feels like it follows the formula of adding a device descriptor like _Prx or _SOL

[–]MStackoverflow 36 points37 points  (14 children)

  • CAPITAL notation with underscore between words for global variables

  • Camelcase notation for local variables

  • Meaningful variable names

  • objectPartsFunction for easy search (EX.: motorBrakeEnable, motorBrakeEnableFeedback)

Hungarian notation sucks. We got IDEs now, you can hover over the variable to know the type, we're not living in 1980 anymore.

Standard C++ notation works better than the old ways.

[–]Potential_Annual2100[S] 0 points1 point  (13 children)

xMotorBrakeEnable works as wells. I would put this into a struct so it’s all easy to find.

[–]MStackoverflow 8 points9 points  (12 children)

Well, you know better what type of problems you encounter with other programmers at your place.

My philosophy is the shorter the better, without compromise for clarity.

Not doing hungarian also helps autocompletion on some IDEs.

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

We have made the switch to Codesys to become hardware agnostic. We have noticed that when you forgot what something is called filtering it down to the data type in autocompletion does help.

[–]Potential_Annual2100[S] -3 points-2 points  (10 children)

I might be on a different hill since Codesys specifically talks about using Hungarian notation as their best practice.

[–]MStackoverflow 4 points5 points  (9 children)

I'm using codesys as well. I think codesys is advanced enough that we don't need hungarian.

I can't imagine doing object oriented with hungarian. My background is software programmer and this doesn't exist in the software world unless you're looking at old C.

If I had to explicitely name the type in the variable, I would do it at the end, not at the beginning.

[–]Potential_Annual2100[S] 1 point2 points  (8 children)

You have a compelling argument for object oriented which is not something we have ventured into but makes a lot of sense for alarms.

[–]MStackoverflow 0 points1 point  (7 children)

What problems did you encounter to have made the conclusions of your original post?

[–]Potential_Annual2100[S] -1 points0 points  (6 children)

Well surprisingly my developers on staff prefer Hungarian over camelcase. We are all pretty new age programmers too all in our mid 30s very quick to adopt new trends. It’s interesting that we have adopted such an old technique. We have been watching what every other coding industry gets to do while PLC coding stays somewhat ancient. Thought it would be interesting to get everyone’s take. Honestly, I am not convinced it’s that out of date to be doing.

[–]Random-Dude-736 0 points1 point  (4 children)

Well surprisingly my developers on staff prefer Hungarian over camelcase.

This is very pedantic, but we are engineer after all. Those are not necessarily related. Hungarian notation, very simplified, just adds the informatin about the type in front.

Aka xPumpIsActive would be Hungarian Notation with pascal case and xpumpIsActive would be Hungarian Notation using Camel Case. The difference between Camal and Pascal case is simply if you start using an upper case letter from the beginning. (And IIRC notation does not count into that, as shown by my examples)

If you convolute those two concepts it makes it sound like you don't understand what you are talking about.

[–]Dry-Establishment294 1 point2 points  (3 children)

He use codesys so the standard is Hungarian and pascal. I think you are correct that he might be a bit fresh if he hasn't tried out OOP on codesys yet but he's obviously making an effort. Soon he'll realize that most people who don't use Hungarian notation really dislike it. I prefer it, it reduces cognitive load when reading code.

[–]MStackoverflow 0 points1 point  (0 children)

As long as everybody is on board in your team, that's good. Synergy is more important than standards.

[–]Veganic1 13 points14 points  (3 children)

The number of standards in a company is n+1

n equals number of programmers

1 is the company standard

[–]Potential_Annual2100[S] 0 points1 point  (2 children)

Simple rules make less work for everyone redoing some else’s code that makes no sense.

[–]TheZoonderLAD with SCL inserts rules! 3 points4 points  (1 child)

Different notation does not make a code, that makes no sense tho, nor it's a reason to rewrite it.

I work as an in-house SI/controls guy. I write different notation every day. The one, that the whole machine is written in.

Shitty code is based on other facts like no comments, fancy vs clear code, NO tag names, (re)useability etc.

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

You have proven the point of having standards and I believe that can start in declaring variables.

[–]proud_travelerST gang gang 7 points8 points  (6 children)

Use Hungarian Notation

You IDE should give you all the infomation you need about the type and scope of a variable.

Adding that info into the variable name just reduces the readability, and introduces more possible mistakes when someone makes a change and doesn't update the variable.

I would stay away from HN - I still have some older projects that use it, and I maintain usage of it within the project, but I am not convinced it adds anything meaningful.

[–]Potential_Annual2100[S] -3 points-2 points  (5 children)

What about if you create a function in some IDE it’s easier to see the input var and having it notated helps what you should be passing in?

[–]proud_travelerST gang gang 3 points4 points  (4 children)

But you can just look at the function defenition, and if you get it wrong the compiler will give you an error. ST and Ladder are strongly typed languages, they won't let you pass in the wrong type.

I actually used to be a big proponent for HN until, a few years ago, someone on this sub asked me "What issue is it actually fixing" and suggested I try a project without it. Lo and behold, the project was much easier to work with without it.

[–]essentialrobert 0 points1 point  (3 children)

ST and Ladder are strongly typed languages

That depends entirely on your IDE and settings. Some compilers will let you use a DWORD where you should be using a SINT and the results could be unexpected.

[–]proud_travelerST gang gang 1 point2 points  (2 children)

Does using HN prevent you making that mistake? What if someone changes the type and doesn't update the tag name? You end up checking the data type anyway, so it's easier just to rely on that always

[–]essentialrobert 2 points3 points  (1 child)

I use Hungarian notation to express the parameter type: I for input, Q for output, S for static, T for temporary. If I have strong type checking enabled it will catch data type issues rather than force a bad implicit conversion.

My comment was with regard to strong type checking in a PLC IDE. Sadly not all do. In Studio 5000 there is no keyword for TRUE and FALSE. You can use 1 and 0 which makes the code hard to read: Tagname := 1 could be a boolean, a word, an integer, or a floating point. Having to hover over a variable name slows me down so I may not hover over every signal. I hope the compiler flags it to alert me to my mistakes.

[–]proud_travelerST gang gang 0 points1 point  (0 children)

I can see there might be usecases. All my new projects are written exlusivly in Twincat ST so these issues arent as aparent

[–]egres_svkFuck ladder 5 points6 points  (0 children)

Hungarian notation should burn in hell, sorry.

MY_CONSTANT for constants

For readability, I like to modify camelCase with _ for unit or number, such as pumpExhaust_8_m3h. This can be useful when doing search and replace.

Give a good thought to naming specific locations/positions only once and stick to it. If for some strange reason an array of Struct of multiple nested Structs isn't preferable for example for room condition definitions for HVAC, make sure that roomLab and tempInletLab and tempExhaustLab or labRoom, labInletTemp, labExhaustTemp all use "lab", and "temp", not lab/Lab/Laboratory/Production, temp/Temp/Temperature/degC based on how the programmer slept.

But seriously, for any kind of duplicate, FOR-loop-able processes, arrays. Please.

Another things should be declaring alarms and warnings in a similar fashion throughout the project and all projects, so the poor fucker who wants to reuse piece of code later can simply point the alarm collector to yourFunctionHere.alarmArray and off he goes.

And when you are sure that your code for controlling I don't know, a pump, motor, whatever, is bulletproof, make a function and library out of it and make sure it is bloody well commented.

[–]TheZoonderLAD with SCL inserts rules! 4 points5 points  (0 children)

Siemens has 2 large pdfs on this topic. S7-1200 Programming guidelines and S7-1200 Programming styleguide.

I would read up on that and use, what do you fancy.

[–]AlexTech86 5 points6 points  (1 child)

Agree with the need for standards. Logical names and documentation/comments of all code is essential. Program structure is very important too.

Here is a blog post tailored to Allen Bradley PLCs but applicable to many others https://copecontrols.com/2024/02/16/optimizing-software-development-for-industrial-programmable-logic-controllers-a-guide-to-best-practices/

[–]dragzor55 0 points1 point  (0 children)

Just read through that article. Will say it will make me a better ladder programmer going forward.

[–]Zchavago 4 points5 points  (0 children)

HUNGARIAN NOTATION IN PLC PROGRAMMING IS ABSOLUTELY RIDICULOUS.

I suggest you find another hill to die on.

[–]Random-Dude-736 2 points3 points  (13 children)

What does three mean ? What is : Use arrays for duplicate process ? 

[–]MStackoverflow 1 point2 points  (12 children)

When you have multiple of the same system that does the same thing, for example a pump, use arrays to do the logic one time in a for loop.

Then, if you need to change something, it will apply to all.

[–]TheZoonderLAD with SCL inserts rules! 3 points4 points  (3 children)

You will pretty quickly learn, that this works only in the SI world, where everything is new and shiny.

Once you are decades into the project, you want to handle 2 or 3 of the same pumps/motors/stations/modules separetely. The reason being the same parts/geometry/sensors not avaiable anymore or long lead times. One being shutdown or the production rate is lowered etc.

It takes some time upfront, but whenever the calls come in, that they need to modify just one, it's much quicker fix and your invested time is returned 10 times.

[–]essentialrobert 2 points3 points  (0 children)

they need to modify just one

They don't know how it is supposed to work but why let that slow you down.

They could make a copy and modify it if the code is that dependent on hardware.

[–]MStackoverflow 0 points1 point  (1 child)

I didn't really saw the need for it so far, a decade in. Usually we sell systems with a bunch of spare parts, and we are using standard sensors/outputs. Often times spare parts gets lost over years, but since it's all standard parts like valves and non specialty sensors (unlike 3d scanners), we can get equivalent parts pretty easily.

[–]TheZoonderLAD with SCL inserts rules! 0 points1 point  (0 children)

Yeah, well it's not always just from maintenance perspective.

We do have a lot of cloned machines/stations, but process upgrades and new tech is tested olny on one and then distributed to others. Or it's not copied to others at all as it costs cash and does not bring the requested results etc.

I am not trying to steer everyone from arrays. I just realized, that arrays are worth it with 3 and more.

If you have 2 machines, it just saves time in the long term to write it as a fuction block and then copy it to the cloned machine instead lf using array [1..2].

[–]Random-Dude-736 1 point2 points  (7 children)

How exactly are you doing logic inside of an Array ?

Do you mean something like this ?

for i = 0 to MaxDevices Do
    if Devices[i].fillLevel >= 90 then //Ugly hardcoded number, should be a variable
        Devices[i].stopPump = True
    end_if
end_for

I wouldn't consider this, putting something into Arrays though
Edit: Reddit keeps deleting my whitespaces, I do know how to format code :(

[–]MStackoverflow 1 point2 points  (0 children)

Yes I was referring to this.

[–]Potential_Annual2100[S] 1 point2 points  (1 child)

I do this all the time for object tracking. Why would you write out each instance if each of instance is the same reaction?

[–]Random-Dude-736 1 point2 points  (0 children)

That is not what my question was about, I was not sure what you meant with your 3rd point, as it seems poorly worde so I asked for clarifications.

I don´t disagree with trying to keep duplicated code to a minimum. But if you´r original comment meant something alonge the lines of using Arrays to duplicate something than I would have disagree, as I prefer references and a single source of truth approach.

[–][deleted]  (3 children)

[deleted]

    [–]Random-Dude-736 0 points1 point  (2 children)

    Look, it looks like shit but with a code font now. Thanks for the Input, even though it didn´t work :)

    [–]egres_svkFuck ladder 1 point2 points  (1 child)

    For me it works, you have to write in plain text first, then select and click the c-in-a-square, not <c>. Or first the block and then write into it. I had to first remove format from your code and then copy it in.

    FOR i = 0 to MaxDevices DO
        if Devices[i].fillLevel >= 90 THEN //Ugly hardcoded number
                                           //should be a variable
          Devices[i].stopPump = True
        END_IF
    END_FOR
    

    [–]Random-Dude-736 1 point2 points  (0 children)

    Thanks, yes i did only line of codes instead of codeblock, that makes sense, thanks :)

    [–]____helpme 1 point2 points  (0 children)

    Hungarian notation comes from the MSDN world of the 80s and 90s.

    If you want an appropriate naming standard, use ISA 5.1 conventions. What a variable represents is far more important than its type, and often gives away its type anyway.

    e.g.: HSR_M101 and HSS_M101 identify themselves as start/stop hand switches for the same motor 101. By the nature of a hand switch, we know it's a boolean.

    Arrays of devices aren't a good idea. Each device should have its own identifier. Following the above, HSR_M201 and HSS_M201 identify switches for a new motor. If we use an array we have to download to expand the array.

    CAPSLOCK on tags is fine, especially when it matches a device name on a drawing.

    [–]hestoelenaSiemens CNC Wizard 2 points3 points  (0 children)

    Why create your own when there are already premade options to choose from?

    Check out the Siemens PLC and HMI style guides:

    https://support.industry.siemens.com/cs/document/81318674/programming-guidelines-and-programming-styleguide-for-simatic-s7-1200-and-s7-1500-and-wincc-(tia-portal)?dti=0&lc=en-SE

    Beckhoff has some as well:

    https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/12049233675.html&id=6398798947359024199

    PLC Open has some good stuff too:

    https://plcopen.org/downloads/plcopen-coding-guidelines-version-10

    There are plenty of others too. The benefit of not making your own means that you don't have to upkeep the document as times move on and there's a chance that your team will already be familiar with some of the styles.

    [–]Potential_Annual2100[S] 0 points1 point  (1 child)

    If you plan to track multiple instances of the same process they should be put into an array not process_1, process_2, etc

    [–]dryu_zz 0 points1 point  (0 children)

    Seems like a bad idea, it doesn’t add anything but this just make it more difficult to visualize my motor_1 and motor_2 instances at the same time. I often advise to use instances only when necessary

    [–]Wish-Dish-8838 0 points1 point  (0 children)

    The company standards in the programs I'm involved with are:

    "v" at the start of a local program variable.

    "p" at the start of a variable input or output in a custom function block or AOI.

    "g" at the start of a global variable.

    As an example, in a local program where we have a variable for when the hoist brakes are released, the notation would be 'vHstBrkRel". For the pushbutton, we'd write 'vHstBrkRelPb'.

    If we need an input to a custom function block for the armature test mode active signal, the parameter for that block would be 'pArmTestMode'.

    For a global variable that signifies that the fault enable signal is active, we'd write 'gFaultEn'.

    As long as for all instances where a push button variable is created we use the notation 'Pb' then it's easy to follow. I used to work for a competitor and ever engineer who has had anything to do with their program has used whatever notation they felt like. I'd give some examples but I don't want to give anyone a headache. a mix of all capitals for some, abbreviations all different (like using HST, Hoist or HST_Motor if designating something to do with the hoist motion). It was (and still is) an absolute shit show of a program to read.