A Simple 2 state machine: How would you have done it?

You may consider a buffer step, so you don't blast through each step. Having a buffer gives you a one scan delay between steps, so you can service the rest of the program if you need to. Put a MOV at the top, buffer moves into step. The left side is step, the right side is buffer. Sometimes it's not necessary to do this, but I always get into the habit of doing it.

Edit, which is basically what Lare stated. I didn't read his post.


Yeah, it is same. But you explained it better.
 
I usually have to integers STATE_NOW and STATE_NEXT


On EQU is comparison with STATE_NOW and move is to STATE_NEXT


On last rung there is move from STATE_NEXT to STATE_NOW.


That way 2 or more consecutive STATEs aren't skipped on same program scan if all next STATE conditions are met.


Whit timer before copying next to state now you can add minimun time / STATE. Helps debugging.

I've done the same, with slightly different terminology. I use AT state and TO state and I do this on the very first rung.

I make the first rung if AT state is not equal to TO state, then make AT state TO state. This ensures that your logic works one scan through at minimum without flipping states.

The disadvantage to using INTS is you have to put a finite number of steps between each. If you have to go back and add states, it is inevitable that you will need more steps than you left space for.

With bits, you can theoretically put an infinite number of steps between each state, but it is a lot less organized/cluttered.
(Of course, you could always create a new sub-state to insert steps between your states)
 
The disadvantage to using INTS is you have to put a finite number of steps between each. If you have to go back and add states, it is inevitable that you will need more steps than you left space for.

With bits, you can theoretically put an infinite number of steps between each state, but it is a lot less organized/cluttered.
(Of course, you could always create a new sub-state to insert steps between your states)


You could also use floats, but then you are limited to around 2*(23-log2(N)) interstitial states, where N is the largest state number rounded up to the next power of 2.


;-)
 
I personally don't like any OTEs or (L) or (U) in my actual states but rather a few rungs at the bottom with an EQU or LIM looking at the SEQ_DINT value and trigger from there.

The cleaner the EQU MOV rungs are the better OMI, however I acknowledge there is more than 1 way to skin a cat. As long as it works to your liking.
 
Are you likely to have 32,767 sequences ? if so you will need plenty of memory and use a DINT, what's the problem.

Use bits instead how many PLC's have 32,000 plus internal bits. not withstanding all the others you need for control.
 
You can always use next_state = next_state+1 if executing the next state.
you can also assign names to states like
error_state = 13
If you use names then you can keep all the state names in one place instead of chasing then all over your program. Now I can write
next_state = error_state
instead of
next_state = 13
 
I also generally use sequences indices to keep track of the state and have "Requested" and "Current" step indices. Usually I will also use XPY on the current index to transform it into bits I can use for actions, because you can cross-reference bits and not step numbers so it makes it easier to see which steps activate what. You can also comment bits in DINTs and not different values of a DINT so you can have comments describing the step over the step bit. This makes it easier to change things on the fly.

I wish Rockwell would let us bit address LINTs though, and I also wish Rockwell had enums.

One disadvantage of the numerical index method is that you can't have true Grafcet AND divergences/convergences. You need a subsequence for that. With the "seal-in bit" method as shown by DrBitBoy you can. Also inserting steps is a PITA (XPY precludes leaving much space inbetween numbers, unfortunately, and I'm so anal about this I just end up shifting everything by 5s or 10s anyway).
 
I also generally use sequences indices to keep track of the state and have "Requested" and "Current" step indices.
There is nothing to keep you from having two state machines a and b.Then you have new_state_a and new_state_b.



I wish Rockwell would let us bit address LINTs though, and I also wish Rockwell had enums.
Accessing bits is good but you can always assign values to variables. It just uses memory.



One disadvantage of the numerical index method is that you can't have true Grafcet AND divergences/convergences.
Yes you can as stated above. State machine b would just be a branch or stated by state machine a. State machine a would need to wait for state machine b to finish to converge.
 
I also generally use sequences indices to keep track of the state and have "Requested" and "Current" step indices. Usually I will also use XPY on the current index to transform it into bits I can use for actions, because you can cross-reference bits and not step numbers so it makes it easier to see which steps activate what. You can also comment bits in DINTs and not different values of a DINT so you can have comments describing the step over the step bit. This makes it easier to change things on the fly.

I wish Rockwell would let us bit address LINTs though, and I also wish Rockwell had enums.

One disadvantage of the numerical index method is that you can't have true Grafcet AND divergences/convergences. You need a subsequence for that. With the "seal-in bit" method as shown by DrBitBoy you can. Also inserting steps is a PITA (XPY precludes leaving much space in between numbers, unfortunately, and I'm so anal about this I just end up shifting everything by 5s or 10s anyway).

Yes I think we need to make clear, that there are different types of State Machines. (And some hybrids in between).

Also lets point out that a SMs can have "Sub SM" inside of individual states. Which is a SM inside of another SMs state.

Some State Machine also have Sub States, which is a bit different then just have a Sub SM in side a State of another SM. That gets complicated though. I have used those in C# before. Side note if you want a decent light weight C# SM Library you can check out Stateless
  • A basic linear sequencer
    • numerical indexing/incrementing
    • uses a incrementing Integer
  • A Diverging and ANDing Linear State Machine
    • Kind of like SFC (Have never used SFC so maybe I am wrong)
    • There is a clear singular loop here, with branches that diverge and then merge again, but it still has to keep moving in the same direction
    • This could use sealing bits, latching or could use an integer
  • A full finite state machine
    • Has no "Right" direction
    • Can loop back on itself
    • To be practical it needs to use an Integer, BUT simple ones could probably use Sealing Bits but it would be messy


I wish Rockwell would let us bit address LINTs though, and I also wish Rockwell had enums.
Absolutely would make things so much cleaner.

But it's never going to happen There are too many Rockwell Simps that think Rockwell is GREAT!!!! and will **** on you if you suggest improvements. "Don't need that" and "It's too Complicated" (Can you hear the frustration when you read that?) Why would rockwell want to actually create new features if they are people that are actively against them?
 
Last edited:
The disadvantage to using INTS is you have to put a finite number of steps between each. If you have to go back and add states, it is inevitable that you will need more steps than you left space for.

With bits, you can theoretically put an infinite number of steps between each state, but it is a lot less organized/cluttered.
(Of course, you could always create a new sub-state to insert steps between your states)


There is 65536 different values on integer. You can add step by 10 or 100 and have 9 or 99 spares between each.

Still 6553 or 655 different steps on sequence with those spares.


Where you need so much steps? :unsure:
 
There is 65536 different values on integer. You can add step by 10 or 100 and have 9 or 99 spares between each.

Still 6553 or 655 different steps on sequence with those spares.


Where you need so much steps? :unsure:

All I'm really trying to say is that you will increment your state/steps by a number to try and future-proof your code.

For example, maybe you go by 10, which is very common.

10 = State 1
20 = State 2
30 = State 3

Then, a year or two later, something will be added to the machine. Even though you left 10 states/steps in between, you will have to add 12 states/steps between state 2 & 3 and you won't be able to use the same integer.

You can, of course, use a new sub-integer to get around this.

By using individual bits - you could theoretically put an infinite amount of new bits in between the two states/steps.
 
Accessing bits is good but you can always assign values to variables. It just uses memory.

Yes, tag constants would achieve the cross-referencing functionality and the name of the tag would also carry some information about the step. What I often see is that people just use an EQU with a hardcoded value which makes it impossible to cross-reference.

Yes you can as stated above. State machine b would just be a branch or stated by state machine a. State machine a would need to wait for state machine b to finish to converge.

Sticking with Grafcet terms, and as I noted myself in that same post, I agree there's no functional difference between a subprogram called once at a certain step of a program, with a transition later down the road requiring that the subprogram be at its exit step, and an AND divergence. Since I prefer using integers to keep track of states that is how I do it myself.

That being said, strictly speaking, in an AND divergence in a Grafcet there are two or more steps in the same program that become active at the same time. If you structure your PLC Grafcets in a way that one program's state is rendered via bits in a DINT or a UDT then you can accurately convey that which is written on paper. You need multiple variables to do the same if you're using values, at which point you're better off just making it a subprogram for clarity.

It's legalistic and semantic (in French we call that "enculer des mouches") but that was what I wanted to convey. I myself don't use AND divergences where I write out Grafcet on paper. I prefer synchronizing Grafcets that call subprograms.
 

Similar Topics

Hello, I´m having a problem trying to program in Ladder. An output should be trigged by two possible contacts. Take a look on the printscreen...
Replies
5
Views
160
Hello again..trying something on an existing poorly written program and just wanted to double check something system is an A-B MicroLogix 1200 In...
Replies
5
Views
180
Hi all, Writng a FB in ST on Beckhoff TC for a pulser which turns on and off on a cycle, is paused by turning bControlInput to FALSE, but resumes...
Replies
6
Views
271
I'm trying to build my Classic Step 7 programming skills this weekend. I get stuck on little things that are not covered in YouTube tutorials. I'm...
Replies
7
Views
326
I have a program that does a 7 second "scan" sensor calibration routine whenever a setting (setting is called assistance level or "AL" and ranges...
Replies
3
Views
220
Back
Top Bottom