Electric Automation Forum
Forum » General Discussion » How would you code this in logic controller?
Topics: How would you code this in logic controller? on General Discussion
#1
Start by
David Stonier-Gibson
01-03-2014 10:37 PM

How would you code this in logic controller?

In logic controller design *sequence* is very important. So is *context*. A logic controller is essentially something that responds to inputs by altering outputs in the right sequence, where the sequence may vary with context. (Use the terms "history" or "past events" instead of "context", if that is more comfortable.

My job includes studying and designing programming methods that can express sequence and context.

So here is my question: How would you code the following in the language(s) you use ...

A controller has one push button switch wired to an input, and one lamp wired to an output. The first time the button is pressed the lamp must come on. The next time the button is pressed, the lamp must turn off. On the next press the lamp comes on, etc. etc. Don't forget to allow for the button to be released before it is pressed again.

This is not a trick question or "test". I am simply interested in how a simple example involving sequence and context is handled by different professionals in various languages. I would also be interested in opinions as to how easily a given solution would be to explain to a colleague who is not familiar with the specific language (or operating system)
01-04-2014 12:51 AM
Top #2
Stewart Farr
01-04-2014 12:51 AM
Simple solution would be to set the manufacturers "toggle" - pretty much most of them have one in some form.
Complicated solution would be setting up a debounced, fully interlocked setup using an embedded system.
I would be against using ladder logic in such a simple system, as the poor registers would get overwritten before certain commands (external to the ladder, but internal to the bios) would happen. You need at least 5 rungs for ladder to not jam or miss stuff. Would be ideal for an FPGA where you could process the task as a multithread with another task.
Easiest solution of course would be to have a toggle switch hardwired to the lamp with no controller of course.
01-04-2014 03:22 AM
Top #3
Shawn Burke
01-04-2014 03:22 AM
Here is an example (SCL - Structured Control Language (Siemens))
As a note, I could do it in less instructions, however this is clean and gives the "next" user comments to follow:

-------------------
FUNCTION_BLOCK toggle_lamp;

TITLE = 'Momentary Pushbutton Control to Toggle a Lamp'
VERSION : '1.0'
AUTHOR : 'SGB'
NAME : 'toggle_lamp'
FAMILY : 'LINKEDIN.COM'

VAR_INPUT
PB : BOOL; //MOMENTARY PUSHBUTTON INPUT
END_VAR;

VAR_OUTPUT
LAMP : BOOL; //LAMP OUTPUT CONTROL
END_VAR;

VAR
pb_old : BOOL; //VALUE OF PUSHBUTTON AT THE END OF THE SCAN
lamp_old : BOOL; //VALUE OF THE LAMP AT THE END OF THE SCAN
END_VAR;

BEGIN

// CHECK FOR A CHANGE IN THE PUSHBUTTON STATE
IF (PB AND NOT pb_old) THEN
LAMP := NOT(lamp_old);
END_IF;

// SET THE VALUE OF pb_old TO COMPARE WITH PB ON NEXT SCAN
pb_old := PB;

// SET THE VALUE OF lamp_old IN PREPARATION FOR A CHANGE IN PB
lamp_old := LAMP;

END_FUNCTION_BLOCK
01-04-2014 05:28 AM
Top #4
Mark Englund
01-04-2014 05:28 AM
Here is a way to do this in Ladder using a one shot on the pushbutton and a simple latching circuit. Pbout is an internal memory bit or tag. I have applied this to GE and AB PLC's on many occasions.


pb1 pbout
----I I-----------[ons]-------------------( )---

pbout Lamp1 Lamp1
----I I----------I/I-------------------------( )-----
I I
I Lamp1 PBout I
I---I I----------I/I-------I
01-04-2014 08:07 AM
Top #5
David Stonier-Gibson
01-04-2014 08:07 AM
I am going to use the link at the very bottom of this page to ask the LI people to provide at least basic formatting control!! Who will join me?
01-04-2014 10:08 AM
Top #6
Michael Feldman
01-04-2014 10:08 AM
This type of problems (events, state and context) is screaming for State Machines. No programming language can compare to the graphical state machine diagram with "your programming language" implementing guards and actions. (Can't post pictures here, but you are welcome to check it at www.as1tech.com) Add some complexities to your example and prepare to write pages of code or start using State Machines
01-04-2014 12:38 PM
Top #7
Paul Tucker
01-04-2014 12:38 PM
David - Curious that you use such a simple example to enquire about sequence control. I am a plc man, so i would think of something on Mark's lines for this. however, in much more complex systems, it is possible to design a plc program such that it acts like a true multi-tasking sequencing system, that can be reprogrammed to perform entirely different sequences merely by altering a datatable list. The beauty of it is that the tasks within the sequence are fully tested, and provided the sequences are valid, no validation is needed for the new sequences. (Systems on this principle have been running in UK factories for 25 years now).
As to your question, I'd use latched outputs
XIC pb, XIO lamp, XIO os, OTL lamp OTL os
XIC pb XIC lamp XIO os OTU lamp OTL os
XIO pb OTU os
-| |- is XIC, -|\|- is XIO, -(L)- is OTL, -(U)- is OTU
01-04-2014 03:27 PM
Top #8
David Stonier-Gibson
01-04-2014 03:27 PM
Paul, the reason for the trivial example is exactly that it is the simplest case of sequence and context I know of. The statement of the problem fits in 4 lines of text in (I hope) a completely unambiguous form. It could even be shortened to "code a push on/push off light switch" and most people would cotton on.

In our interactive online programming tutorial I use this example, then build it up with increasing levels of complexity, so the student can follow the developing concepts.

Tutorial: http://www.splatco.com/training/tute1/start.swf
01-04-2014 05:42 PM
Top #9
Paul Tucker
01-04-2014 05:42 PM
Thanks David - I like what I have seen so far - well thought out.
Novel marketing ploy - but justified!
Paul
01-04-2014 08:06 PM
Top #10
Geoff White
01-04-2014 08:06 PM
In TwinCAT PLC using Structured Text:

(* Create a rising edge trigger to handle button *)
fbR_TRIG( (* rising edge trigger function block (one-shot) *)
CLK:= diPushbutton); (* input or 'clock' to function block is linked to PB *)

(* If the button is pressed then invert the state of the output *)
IF fbR_TRIG.Q = TRUE THEN doLamp:= NOT(doLamp);

I think this would be difficult to explain to someone who is unfamiliar with TwinCAT. There's some overhead to take care of first. A POU (Program Organizon Unit ( a program) ) or Action (a subroutine) has to be created that is continually scanned to check for a change in the push button state. Your tutorial represented the solution in a simple and effective form. The logic is simple. Translating it to another language is the challenge. Syntax and program structure vary from one language/platform to the next. There are so many variables to consider.

I'm not sure if that's kind of feedback you're looking for. I enjoyed the tutorial.

-Geoff
01-04-2014 10:50 PM
Top #11
David Stonier-Gibson
01-04-2014 10:50 PM
Thank you everyone who has responded to my question. I posted this on a range of LI groups, covering the whole gamut from industrial automation (PLC type guys) to realtime embedded (C/C++ and RTOS type guys). The range of responses was equally broad. The issue of contact debounce was an unintended distraction. Sorry, I should have precluded it in my original post.

[A whole bunch of philosophizing about state machines omitted because LI won't allow long posts. In summary: C/C++ discourage FSM programming because there is no one-to-one mapping between a place in a state diagram and a place in the code. A human reads and analyzes a state diagram in state-event order. The code gets written in event-state order. A tabular representation, rather than a diagram, can relieve this problem.]

(Sponsor’s message alert). Our controllers use a text-based language that is "positional", so where "it" is in the code is a very direct reflection of the current state of the program. This makes it much easier for a lay person or student to relate a state diagram to the code. The push-push example coded for a SPLat Controller is:

iButton. . . .iEQU. . . . 0. . . .;Define the switch PB input
oLamp. . . .oEQU. . . .5. . . .;Define the lamp output

PushPush:
. . . . . . . . WaitOn. . . iButton
. . . . . . . . On. . . . . . . oLamp
. . . . . . . . WaitOff. . . iButton
. . . . . . . . WaitOn. . . iButton
. . . . . . . . Off. . . . . . . oLamp
. . . . . . . . WaitOff. . . iButton
. . . . . . . . GoTo. . . . .PushPush

The first 2 lines are simple declarations. The WaitOn instruction simply sits waiting, and blocking, until the nominated input is ON. WaitOff is the converse. On, Off and GoTo are fairly self-evident.

The Wait instructions block. By preceding the above with two more lines of code, I convert it into a task within our integral multitasking system:

. . . . . . . . .LaunchTask. . . . . .PushPush . . . .;Initiate a task
. . . . . . . . .RunTasksForever . . . . . . . . . . . . . ;Start the multitasking going

Now, as long as a Wait is blocking this task, other tasks will get the processor. I can have 32 tasks with little more effort.

Debounce is done courtesy of the underlying runtime. It costs the application programmer nothing. That is the kind of service that should be taken as a given in a controller.

The program can actually be simplified further. The WaitOnK instruction waits for an off-to-on transition, eliminating the need to "WaitOff".

PushPush:
. . . . . . . . WaitOnK. . . iButton
. . . . . . . . On. . . . . . . . oLamp
. . . . . . . . WaitOnK. . . iButton
. . . . . . . . Off. . . . . . . . oLamp
. . . . . . . . GoTo. . . . . . PushPush

The above code is so clear that I have reports that an 8-year old can understand it. In fact, she programs SPLat.

LinkedIn won’t allow me to include a state diagram. However, the first code version above will have 4 states, one per Wait instruction. There is a very direct mapping between code and state diagram. The second version will have 2 states, because in effect part of the function has been separated out into a secondary FSM (input edge detection), which just happens to live in the operation system.

This simplicity of code is attributable to two features of the SPLat product:

. 1. The multitasking is cooperative.
. 2. The multitasking is tightly integrated with the language.

David Stonier-Gibson http://splatco.com
Reply to Thread