Linguagem de Comandos Elétricos (Electric Commands Language) - LCE 2.1  
 
 
 
Web Site: www.andrebarbosa.eti.br


Previous  Top  Next



Because I believe and hope that adequate versions of the programmables logic controllers will come be, as they already are at the industrial sector, widely utilized in the commercial and domestic sectors, in malleable automation of buildings, residences, offices, doctor's offices, professionals equipments, toys, vehicles, electrical appliances, and other, by the marvels of comfort, reliability, economy, reasonableness and quality that can aggregate to the pattern of ours lifes, when substitute the manual and repetitive controls that we are obliged to make (when we get and when we don't forget them - imagine the programming of a video!) by programmable flexible actions, I've created the SimuPLC and the LCE. (Obs.: as happens with every technology, everything will be vain if the focus isn't the human felicity.)

The Linguagem de comandos Elétricos - LCE
(Electric Commands Language), is a high-level language (to opposition to the Instruction List - IL) developed for finality to agilize, facilitate and make the PLCs programming any more natural and comprehensible for the non-specialists, and more productive for the specialists, making the control programs better estructured, semantically more meaningful and naturally documented, beyond of potentially independent of equipment. Example of a control program very simple written into LCE:

plc On_Off_LightBulb // Simpler control than I imagined: turn on and turn off a light bulb

var
   I0.0   Electric_Switch,
      
Q0.0
   LightBulb;

network
1 // Verifies if Electric_Switch is turned on to operate the light bulb

if
(Electric_Switch) {
operate
LightBulb;
}

end

Though this control have been the simplest that I imagined, with it already is possible to verify some interesting points and expose several aspects of the
LCE language:

·At begin, the program should present, after of obligatory plc clause, a name or denomination, that will may describe, on synthetic, but significant mode, of that treats the control. The end of the source program is signalized with the end clause.  
 
·With the var clause it make possible (however not obligatory) the association of meaningful names to variables of the program, those can be referenced subsequently, in the body of the logic of program, making more clear its understanding.  
 
·The network clause segments the program into parts, whereabouts each part initiates the utilization of the stack, making its management more rational, because guarantees that it don't will grow without limit in the course of functioning of the program. In addition, when enlarged comments enlighten the use of each segment, the control program gets more well documented, facilitating its understanding and maintenance.  
 
·The syntax of the LCE is similar to one of general use programming languages, like C, C++, Pascal, Basic, but is infinitely smaller and more simple that these ones, it approaching of imperatives commands into natural language (in Portuguese, English, or bilingual, regardless) and of the Structured Text - ST, what minimizes too much the learning curve of the LCE, even for the laymen in programming, because it hides of the user the inherent complexity to the control languages Instruction List based.  
 
·The alternative ways of PLCs programming, the straight drawing of the ladder diagram or of the function blocks diagram, are appropriate, in programs of minor presence, for electricians or electronic engineers and technicians, respectively, that detain the specialized required knowledges.  
·Note that, in programs of larger presence, this technique, even for the specialists on the area, suffers at the aspect of the documentation about the implemented control, that constitute a long supplementary work to be made, that ensue of the absence of significance and textual semantics of the obtained program, features naturally inherent to the high-level languages, where the text itself of the written program composes its better documentation.  
 
·For visualization purposes of the simulation, from Instruction List, is automatically generated the correspondent ladder diagram, that will function as if traversed by real scan cycles, repeatedly reading the points of virtual entry and updating the respective internal variables (simulation of the memory-image of I/O process), processing the instructions from beginning to the end of the control program, or in accordance with the utilized logic of deviations, attending, if enabled, the occurrences of virtual events of interrupts, and, at the end, setting the results on the points of virtual output. Obs.: the way of updating of the inputs and actuating of the outputs can be altered by the menu item I/O.  
 
·This cycle is repeated indefinitely, until that the Simulator be put on the Stop Mode.  

As result of compilation of the program
On_Off_Lightbulb above, the SimuPLC 4.1.0 generated, exactly, the following code, into language Instruction List - IL:

// CLP    On_Off_LightBulb
// Simpler control than I imagined: lit and puts out a light bulb

//
=VAR   I0.0   Electric_Switch
//
=VAR   Q0.0   LightBulb

NETWORK    1 // Verifies if electric_switch is turned on to operate the light bulb

LD   I0.0
=   Q0.0

More complex examples:    

The structure of simplified free context grammar of the language LCE 2.1
, in the Backus-Naur Form (BNF), is the following:

Grammar of the Linguagem de commands Elétricos - LCE 2.1


program -> plc id variables circuit end

variables
->   var list_var | e
list_var
   ->    id idVar more_var ;
more_var
   -> , id idVar more_var | e

circuit
   -> network id commands more_circ
more_circ
   -> network id commands more_circ | e

commands   -> if (cond) { list_action } else more_commands |

          
while
(cond) { commands } more_commands |

          
repeat
{ commands } while (cond); more_commands |

when
(cond) temporize idVar id tempo; more_commands |

when_not
(cond) temporize idVar id tempo; more_commands |

when
(cond) temporize_accumulate idVar id tempo; more_commands |

when_not
(cond) temporize_accumulate idVar id tempo; more_commands |

count
(cond) reset_when (cond) in idVar reference id;
more_commands
|

count_dec
(cond) when (cond) let idVar receber id;
more_commands
|

count_cresc
(cond) count_dec (cond)
reset_when
(cond) in idVar reference id; more_commands |

label
id: more_commands |

sequence
idVar circuit end_cto_seq network id if (cond) { more_action
transfer_sequence
id; } else_seq more_transfer network id end_seq; |

IL
command_il carriage_return new_line more_commands |

         
subroutine
id (param1 param2) commands more_circ end_sub more_sub more_interrupt
|


         
interrupt_handle
id( ) commands more_circ end_interrupt_handle more_interrupt

param1
   -> idVar1 | e
param2
   -> , idVar2 | e

else
      -> else { list_action } | e

else_seq
   -> else { action_else_seq } | e

action_else_seq
-> if (cond) { more_action transfer_sequence id; } |
          
transfer_sequence
id;

more_commands->
commands | e

more_transfere
-> if (cond) { more_action transfer_sequence id; } else_seq more_transfere | e

time
      -> ms | s | min | h

more_sub
   -> network id subroutine id param1 param2 circuit end_sub more_sub | e

more_interrupt
-> network id interrupt_handle id commands more_circ end_interrupt_handle more_interrupt | e

cond
      -> PPm
Pm
      -> or PPm | e
P
         -> FFm
Fm
      -> and FFm | e
F
         -> type_action idVar | id_cmp type_op Rel id | not type_action idVar | (cond) | no_error | overflow | pulse_off (cond) | pulse_on (cond) | negates (cond)

Rel
      -> = | <> | > | < | >= | <=
type_op
      -> B | W | D | R | e

list_action
   -> turn_on type_action idVar; more_action |
turn_off
type_action idVar; more_action |
operate
type_action idVar; more_action |
if
(cond) { list_action } more_action |
          
transfer_sequence
id; more_action |
goto
id; |
for
idVar from id to id commands end_for |
idVar
type_opop:= expressão; more_action |
swap_bytes
from idVar; more_action |
increment
type_op idVar; more_action |
decrement
type_op idVar; more_action |
shift
to direction type_op idVar id positions; more_action |
rotate
to direction type_op idVar id positions; more_action |
encode
id in idVar; more_action |
decode
idVar from id; more_action |
7_segment_display
id in idVar; more_action |
pid
id, SP = id, Kc = id, Ti = id, Td = id,
MX
= id, PV = id, Mn = id; |
id_sbr
(id1, id2); more_action |
convert
type_op id for type_op idVar; more_action |
BCD_to_integer
in idVar; more_action |
integer_to_BCD
in idVar; more_action |
extract_square_root
from id in idVar; more_action |
extract_sine
from id in idVar; more_action |
extract_cosine
from id in idVar; more_action |
extract_tangent
from id in idVar; more_action |
extract_natural_logarithm
from id in idVar; more_action |
randomize
id in idVar; more_action |
round
id in idVar; more_action |
trunc
id in idVar; more_action |
invert
type_op idVar; more_action |
return
; |
stop
; |
finish_scan
; |
enable_interrupt
; more_action |
disable_interrupt
; more_action |
attach
id to_the interrupt evento; more_action |
detach
evento; more_action |
receive_byte
in id come_in port; more_action |
transmit_byte
id in port; more_action

expression
   -> parcel more_parcel
parcel
   -> factor more_factor
more_parcel->
type_op+ parcel more_parcel | type_op- parcel more_parcel | type_op| parcel                     more_parcel | type_op^ parcel more_parcel | e
more_factor
   -> type_op* factor more_factor | type_op/ factor more_factor | type_op& factor more_factor | e
factor
      -> id | idVar | (expression)

port
      -> Port0 | Port1

evento
   -> rising_edge_I0.0 | falling_edge_I0.0 | rising_edge_I0.1 |
          
falling_edge_I0.1
| rising_edge_I0.2 | falling_edge_I0.2 |
          
rising_edge_I0.3
| falling_edge_I0.3 | reception_Port0 |
          
reception_port1
| transmission_port0 | transmission_port1 |
          temporization_T32 | temporization_T96

more_action
         -> list_action | or (cond_OrIf) { list_action } more_action_OrIf | e

more_action_OrIf
   -> or (cond_OrIf) { list_action } more_action_OrIf | e

cond_OrIf
      -> type_action idVar | id_cmp type_op Rel id | not type_action idVar

op
         -> + | - | * | / | & | | | ^ | e

type_action
   -> immediate | e

direction
   -> left | right


where idVar (identifier variable variant) is a name that must begin with a letter, and can have until 255 characters; id (identifier) can be, beyond of a name like the former, also a constant, formed by numerical digits, where the decimal symbol is the dot, and cmd_stl is any valid command line into IL.

Obs. 1
: the variables and instructions in the SimuPLC are case sensitive, that is, it's considered different the lower and upper case of the same letter. Generally, the instructions into IL are written in upper, and, into LCE, in lower case.

Obs. 2
: in the grammar above, the symbols in blue are non-terminals and the ones in black are terminals.

Obs. 3
: the arithmetical operators must be separated by spaces of the respective operands in the construction of the expressions, except the unary operators - e +. Example:

Signal_Correction
:= (-3*Current+100)/(Speed+Pressure); // Wrong. Always keep space between operator and operand and never between operation type and operator.

Signal_Correction
:= (-3 * Current + 100) / (Speed + Pressure); // Correct.